From 7c21a96e9afa3408ca0b459a392275aa0ae77608 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sun, 27 Nov 2005 23:41:55 +0000 Subject: Initial check-in of (stripped-down) UCL data compression library v 1.01 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8087 a1c6a512-1295-4272-9138-f99709370657 --- tools/ucl/include/ucl/ucl.h | 235 ++++++++++++++ tools/ucl/include/ucl/uclconf.h | 407 ++++++++++++++++++++++++ tools/ucl/include/ucl/uclutil.h | 71 +++++ tools/ucl/src/alloc.c | 151 +++++++++ tools/ucl/src/fake16.h | 81 +++++ tools/ucl/src/getbit.h | 64 ++++ tools/ucl/src/internal.h | 48 +++ tools/ucl/src/io.c | 105 +++++++ tools/ucl/src/n2_99.ch | 643 ++++++++++++++++++++++++++++++++++++++ tools/ucl/src/n2b_99.c | 38 +++ tools/ucl/src/n2b_d.c | 178 +++++++++++ tools/ucl/src/n2b_ds.c | 40 +++ tools/ucl/src/n2b_to.c | 79 +++++ tools/ucl/src/n2d_99.c | 38 +++ tools/ucl/src/n2d_d.c | 183 +++++++++++ tools/ucl/src/n2d_ds.c | 40 +++ tools/ucl/src/n2d_to.c | 79 +++++ tools/ucl/src/n2e_99.c | 38 +++ tools/ucl/src/n2e_d.c | 186 +++++++++++ tools/ucl/src/n2e_ds.c | 40 +++ tools/ucl/src/n2e_to.c | 79 +++++ tools/ucl/src/ucl_conf.h | 359 ++++++++++++++++++++++ tools/ucl/src/ucl_crc.c | 135 ++++++++ tools/ucl/src/ucl_dll.c | 61 ++++ tools/ucl/src/ucl_init.c | 500 ++++++++++++++++++++++++++++++ tools/ucl/src/ucl_mchw.ch | 313 +++++++++++++++++++ tools/ucl/src/ucl_ptr.c | 81 +++++ tools/ucl/src/ucl_ptr.h | 211 +++++++++++++ tools/ucl/src/ucl_str.c | 133 ++++++++ tools/ucl/src/ucl_swd.ch | 665 ++++++++++++++++++++++++++++++++++++++++ tools/ucl/src/ucl_util.c | 204 ++++++++++++ tools/ucl/src/ucl_util.h | 180 +++++++++++ tools/ucl/uclpack.c | 660 +++++++++++++++++++++++++++++++++++++++ 33 files changed, 6325 insertions(+) create mode 100644 tools/ucl/include/ucl/ucl.h create mode 100644 tools/ucl/include/ucl/uclconf.h create mode 100644 tools/ucl/include/ucl/uclutil.h create mode 100644 tools/ucl/src/alloc.c create mode 100644 tools/ucl/src/fake16.h create mode 100644 tools/ucl/src/getbit.h create mode 100644 tools/ucl/src/internal.h create mode 100644 tools/ucl/src/io.c create mode 100755 tools/ucl/src/n2_99.ch create mode 100644 tools/ucl/src/n2b_99.c create mode 100644 tools/ucl/src/n2b_d.c create mode 100644 tools/ucl/src/n2b_ds.c create mode 100644 tools/ucl/src/n2b_to.c create mode 100644 tools/ucl/src/n2d_99.c create mode 100644 tools/ucl/src/n2d_d.c create mode 100644 tools/ucl/src/n2d_ds.c create mode 100644 tools/ucl/src/n2d_to.c create mode 100644 tools/ucl/src/n2e_99.c create mode 100644 tools/ucl/src/n2e_d.c create mode 100644 tools/ucl/src/n2e_ds.c create mode 100644 tools/ucl/src/n2e_to.c create mode 100644 tools/ucl/src/ucl_conf.h create mode 100644 tools/ucl/src/ucl_crc.c create mode 100644 tools/ucl/src/ucl_dll.c create mode 100644 tools/ucl/src/ucl_init.c create mode 100755 tools/ucl/src/ucl_mchw.ch create mode 100644 tools/ucl/src/ucl_ptr.c create mode 100644 tools/ucl/src/ucl_ptr.h create mode 100644 tools/ucl/src/ucl_str.c create mode 100755 tools/ucl/src/ucl_swd.ch create mode 100644 tools/ucl/src/ucl_util.c create mode 100644 tools/ucl/src/ucl_util.h create mode 100644 tools/ucl/uclpack.c (limited to 'tools') diff --git a/tools/ucl/include/ucl/ucl.h b/tools/ucl/include/ucl/ucl.h new file mode 100644 index 0000000000..3eb37925c8 --- /dev/null +++ b/tools/ucl/include/ucl/ucl.h @@ -0,0 +1,235 @@ +/* ucl.h -- prototypes for the UCL real-time data compression library + + This file is part of the UCL data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#ifndef __UCL_H +#define __UCL_H + +#ifndef __UCLCONF_H +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* note: to use default values pass -1, i.e. initialize + * this struct by a memset(x,0xff,sizeof(x)) */ +struct ucl_compress_config_t +{ + int bb_endian; + int bb_size; + ucl_uint max_offset; + ucl_uint max_match; + int s_level; + int h_level; + int p_level; + int c_flags; + ucl_uint m_size; +}; + +#define ucl_compress_config_p ucl_compress_config_t __UCL_MMODEL * + + +/*********************************************************************** +// compressors +************************************************************************/ + +UCL_EXTERN(int) +ucl_nrv2b_99_compress ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_progress_callback_p cb, + int level, + const struct ucl_compress_config_p conf, + ucl_uintp result ); + +UCL_EXTERN(int) +ucl_nrv2d_99_compress ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_progress_callback_p cb, + int level, + const struct ucl_compress_config_p conf, + ucl_uintp result ); + +UCL_EXTERN(int) +ucl_nrv2e_99_compress ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_progress_callback_p cb, + int level, + const struct ucl_compress_config_p conf, + ucl_uintp result ); + + +/*********************************************************************** +// decompressors +************************************************************************/ + +UCL_EXTERN(int) +ucl_nrv2b_decompress_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +UCL_EXTERN(int) +ucl_nrv2d_decompress_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +UCL_EXTERN(int) +ucl_nrv2e_decompress_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_decompress_safe_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_decompress_safe_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_decompress_safe_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + + +/*********************************************************************** +// assembler decompressors [TO BE ADDED] +************************************************************************/ + + +/*********************************************************************** +// test an overlapping in-place decompression within a buffer: +// - try a virtual decompression from &buf[src_off] -> &buf[0] +// - no data is actually written +// - only the bytes at buf[src_off .. src_off+src_len] will get accessed +************************************************************************/ + +UCL_EXTERN(int) +ucl_nrv2b_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2b_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +UCL_EXTERN(int) +ucl_nrv2d_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2d_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +UCL_EXTERN(int) +ucl_nrv2e_test_overlap_8 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_test_overlap_le16 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); +UCL_EXTERN(int) +ucl_nrv2e_test_overlap_le32 ( const ucl_bytep buf, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/tools/ucl/include/ucl/uclconf.h b/tools/ucl/include/ucl/uclconf.h new file mode 100644 index 0000000000..75f163fa8d --- /dev/null +++ b/tools/ucl/include/ucl/uclconf.h @@ -0,0 +1,407 @@ +/* uclconf.h -- configuration for the UCL real-time data compression library + + This file is part of the UCL data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#ifndef __UCLCONF_H +#define __UCLCONF_H + +#define UCL_VERSION 0x010100L +#define UCL_VERSION_STRING "1.01" +#define UCL_VERSION_DATE "Jan 02 2002" + +/* internal Autoconf configuration file - only used when building UCL */ +#if defined(UCL_HAVE_CONFIG_H) +# include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// UCL requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* workaround a compiler bug under hpux 10.20 */ +#define UCL_0xffffffffL 4294967295ul + +#if !defined(UCL_UINT32_C) +# if (UINT_MAX < UCL_0xffffffffL) +# define UCL_UINT32_C(c) c ## UL +# else +# define UCL_UINT32_C(c) c ## U +# endif +#endif + + +/*********************************************************************** +// architecture defines +************************************************************************/ + +#if !defined(__UCL_WIN) && !defined(__UCL_DOS) && !defined(__UCL_OS2) +# if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# define __UCL_WIN +# elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) +# define __UCL_WIN +# elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__) +# define __UCL_WIN +# elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS) +# define __UCL_DOS +# elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2) +# define __UCL_OS2 +# elif defined(__palmos__) +# define __UCL_PALMOS +# elif defined(__TOS__) || defined(__atarist__) +# define __UCL_TOS +# endif +#endif + +#if (UINT_MAX < UCL_0xffffffffL) +# if defined(__UCL_WIN) +# define __UCL_WIN16 +# elif defined(__UCL_DOS) +# define __UCL_DOS16 +# elif defined(__UCL_PALMOS) +# define __UCL_PALMOS16 +# elif defined(__UCL_TOS) +# define __UCL_TOS16 +# elif defined(__C166__) +# else +# error "16-bit target not supported - contact me for porting hints" +# endif +#endif + +#if !defined(__UCL_i386) +# if defined(__UCL_DOS) || defined(__UCL_WIN16) +# define __UCL_i386 +# elif defined(__i386__) || defined(__386__) || defined(_M_IX86) +# define __UCL_i386 +# endif +#endif + +#if defined(__UCL_STRICT_16BIT) +# if (UINT_MAX < UCL_0xffffffffL) +# include +# endif +#endif + +/* memory checkers */ +#if !defined(__UCL_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __UCL_CHECKER +# elif defined(__CHECKER__) +# define __UCL_CHECKER +# elif defined(__INSURE__) +# define __UCL_CHECKER +# elif defined(__PURIFY__) +# define __UCL_CHECKER +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* Integral types with 32 bits or more */ +#if !defined(UCL_UINT32_MAX) +# if (UINT_MAX >= UCL_0xffffffffL) + typedef unsigned int ucl_uint32; + typedef int ucl_int32; +# define UCL_UINT32_MAX UINT_MAX +# define UCL_INT32_MAX INT_MAX +# define UCL_INT32_MIN INT_MIN +# elif (ULONG_MAX >= UCL_0xffffffffL) + typedef unsigned long ucl_uint32; + typedef long ucl_int32; +# define UCL_UINT32_MAX ULONG_MAX +# define UCL_INT32_MAX LONG_MAX +# define UCL_INT32_MIN LONG_MIN +# else +# error "ucl_uint32" +# endif +#endif + +/* ucl_uint is used like size_t */ +#if !defined(UCL_UINT_MAX) +# if (UINT_MAX >= UCL_0xffffffffL) + typedef unsigned int ucl_uint; + typedef int ucl_int; +# define UCL_UINT_MAX UINT_MAX +# define UCL_INT_MAX INT_MAX +# define UCL_INT_MIN INT_MIN +# elif (ULONG_MAX >= UCL_0xffffffffL) + typedef unsigned long ucl_uint; + typedef long ucl_int; +# define UCL_UINT_MAX ULONG_MAX +# define UCL_INT_MAX LONG_MAX +# define UCL_INT_MIN LONG_MIN +# else +# error "ucl_uint" +# endif +#endif + +/* Memory model that allows to access memory at offsets of ucl_uint. */ +#if !defined(__UCL_MMODEL) +# if (UCL_UINT_MAX <= UINT_MAX) +# define __UCL_MMODEL +# elif defined(__UCL_DOS16) || defined(__UCL_WIN16) +# define __UCL_MMODEL __huge +# define UCL_999_UNSUPPORTED +# elif defined(__UCL_PALMOS16) || defined(__UCL_TOS16) +# define __UCL_MMODEL +# else +# error "__UCL_MMODEL" +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define ucl_byte unsigned char __UCL_MMODEL +#define ucl_bytep unsigned char __UCL_MMODEL * +#define ucl_charp char __UCL_MMODEL * +#define ucl_voidp void __UCL_MMODEL * +#define ucl_shortp short __UCL_MMODEL * +#define ucl_ushortp unsigned short __UCL_MMODEL * +#define ucl_uint32p ucl_uint32 __UCL_MMODEL * +#define ucl_int32p ucl_int32 __UCL_MMODEL * +#define ucl_uintp ucl_uint __UCL_MMODEL * +#define ucl_intp ucl_int __UCL_MMODEL * +#define ucl_voidpp ucl_voidp __UCL_MMODEL * +#define ucl_bytepp ucl_bytep __UCL_MMODEL * + +typedef int ucl_bool; + + +/*********************************************************************** +// function types +************************************************************************/ + +/* linkage */ +#if !defined(__UCL_EXTERN_C) +# ifdef __cplusplus +# define __UCL_EXTERN_C extern "C" +# else +# define __UCL_EXTERN_C extern +# endif +#endif + +/* calling conventions */ +#if !defined(__UCL_CDECL) +# if defined(__UCL_DOS16) || defined(__UCL_WIN16) +# define __UCL_CDECL __far __cdecl +# elif defined(__UCL_i386) && defined(_MSC_VER) +# define __UCL_CDECL __cdecl +# elif defined(__UCL_i386) && defined(__WATCOMC__) +# define __UCL_CDECL __near __cdecl +# else +# define __UCL_CDECL +# endif +#endif +#if !defined(__UCL_ENTRY) +# define __UCL_ENTRY __UCL_CDECL +#endif + +/* DLL export information */ +#if !defined(__UCL_EXPORT1) +# define __UCL_EXPORT1 +#endif +#if !defined(__UCL_EXPORT2) +# define __UCL_EXPORT2 +#endif + +/* calling convention for C functions */ +#if !defined(UCL_PUBLIC) +# define UCL_PUBLIC(_rettype) __UCL_EXPORT1 _rettype __UCL_EXPORT2 __UCL_ENTRY +#endif +#if !defined(UCL_EXTERN) +# define UCL_EXTERN(_rettype) __UCL_EXTERN_C UCL_PUBLIC(_rettype) +#endif +#if !defined(UCL_PRIVATE) +# define UCL_PRIVATE(_rettype) static _rettype __UCL_ENTRY +#endif + +/* cdecl calling convention for assembler functions */ +#if !defined(UCL_PUBLIC_CDECL) +# define UCL_PUBLIC_CDECL(_rettype) \ + __UCL_EXPORT1 _rettype __UCL_EXPORT2 __UCL_CDECL +#endif +#if !defined(UCL_EXTERN_CDECL) +# define UCL_EXTERN_CDECL(_rettype) __UCL_EXTERN_C UCL_PUBLIC_CDECL(_rettype) +#endif + +/* C++ exception specification for extern "C" function types */ +#if !defined(__cplusplus) +# undef UCL_NOTHROW +# define UCL_NOTHROW +#elif !defined(UCL_NOTHROW) +# define UCL_NOTHROW +#endif + + +typedef int +(__UCL_ENTRY *ucl_compress_t) ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +typedef int +(__UCL_ENTRY *ucl_decompress_t) ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +typedef int +(__UCL_ENTRY *ucl_optimize_t) ( ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ); + +typedef int +(__UCL_ENTRY *ucl_compress_dict_t)(const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem, + const ucl_bytep dict, ucl_uint dict_len ); + +typedef int +(__UCL_ENTRY *ucl_decompress_dict_t)(const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem, + const ucl_bytep dict, ucl_uint dict_len ); + + +/* a progress indicator callback function */ +typedef struct +{ + void (__UCL_ENTRY *callback) (ucl_uint, ucl_uint, int, ucl_voidp user); + ucl_voidp user; +} +ucl_progress_callback_t; +#define ucl_progress_callback_p ucl_progress_callback_t __UCL_MMODEL * + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define UCL_E_OK 0 +#define UCL_E_ERROR (-1) +#define UCL_E_INVALID_ARGUMENT (-2) +#define UCL_E_OUT_OF_MEMORY (-3) +/* compression errors */ +#define UCL_E_NOT_COMPRESSIBLE (-101) +/* decompression errors */ +#define UCL_E_INPUT_OVERRUN (-201) +#define UCL_E_OUTPUT_OVERRUN (-202) +#define UCL_E_LOOKBEHIND_OVERRUN (-203) +#define UCL_E_EOF_NOT_FOUND (-204) +#define UCL_E_INPUT_NOT_CONSUMED (-205) +#define UCL_E_OVERLAP_OVERRUN (-206) + + +/* ucl_init() should be the first function you call. + * Check the return code ! + * + * ucl_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define ucl_init() __ucl_init2(UCL_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(ucl_uint32),(int)sizeof(ucl_uint),\ + (int)-1,(int)sizeof(char *),(int)sizeof(ucl_voidp),\ + (int)sizeof(ucl_compress_t)) +UCL_EXTERN(int) __ucl_init2(ucl_uint32,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +UCL_EXTERN(ucl_uint32) ucl_version(void); +UCL_EXTERN(const char *) ucl_version_string(void); +UCL_EXTERN(const char *) ucl_version_date(void); +UCL_EXTERN(const ucl_charp) _ucl_version_string(void); +UCL_EXTERN(const ucl_charp) _ucl_version_date(void); + +/* string functions */ +UCL_EXTERN(int) +ucl_memcmp(const ucl_voidp _s1, const ucl_voidp _s2, ucl_uint _len); +UCL_EXTERN(ucl_voidp) +ucl_memcpy(ucl_voidp _dest, const ucl_voidp _src, ucl_uint _len); +UCL_EXTERN(ucl_voidp) +ucl_memmove(ucl_voidp _dest, const ucl_voidp _src, ucl_uint _len); +UCL_EXTERN(ucl_voidp) +ucl_memset(ucl_voidp _s, int _c, ucl_uint _len); + +/* checksum functions */ +UCL_EXTERN(ucl_uint32) +ucl_adler32(ucl_uint32 _adler, const ucl_bytep _buf, ucl_uint _len); +UCL_EXTERN(ucl_uint32) +ucl_crc32(ucl_uint32 _c, const ucl_bytep _buf, ucl_uint _len); + +/* memory allocation functions */ +UCL_EXTERN(ucl_voidp) ucl_alloc(ucl_uint _nelems, ucl_uint _size); +UCL_EXTERN(ucl_voidp) ucl_malloc(ucl_uint _size); +UCL_EXTERN(void) ucl_free(ucl_voidp _ptr); + +typedef ucl_voidp (__UCL_ENTRY *ucl_alloc_hook_t) (ucl_uint, ucl_uint); +typedef void (__UCL_ENTRY *ucl_free_hook_t) (ucl_voidp); + +extern ucl_alloc_hook_t ucl_alloc_hook; +extern ucl_free_hook_t ucl_free_hook; + +/* misc. */ +UCL_EXTERN(ucl_bool) ucl_assert(int _expr); +UCL_EXTERN(int) _ucl_config_check(void); +typedef union { ucl_bytep p; ucl_uint u; } __ucl_pu_u; +typedef union { ucl_bytep p; ucl_uint32 u32; } __ucl_pu32_u; + +/* align a char pointer on a boundary that is a multiple of `size' */ +UCL_EXTERN(unsigned) __ucl_align_gap(const ucl_voidp _ptr, ucl_uint _size); +#define UCL_PTR_ALIGN_UP(_ptr,_size) \ + ((_ptr) + (ucl_uint) __ucl_align_gap((const ucl_voidp)(_ptr),(ucl_uint)(_size))) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/tools/ucl/include/ucl/uclutil.h b/tools/ucl/include/ucl/uclutil.h new file mode 100644 index 0000000000..48d7e39ee9 --- /dev/null +++ b/tools/ucl/include/ucl/uclutil.h @@ -0,0 +1,71 @@ +/* uclutil.h -- utilities for the UCL real-time data compression library + + This file is part of the UCL data compression library. + + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#ifndef __UCLUTIL_H +#define __UCLUTIL_H + +#ifndef __UCLCONF_H +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +UCL_EXTERN(ucl_uint) +ucl_fread(FILE *f, ucl_voidp buf, ucl_uint size); +UCL_EXTERN(ucl_uint) +ucl_fwrite(FILE *f, const ucl_voidp buf, ucl_uint size); + + +#if (UCL_UINT_MAX <= UINT_MAX) + /* avoid problems with Win32 DLLs */ +# define ucl_fread(f,b,s) (fread(b,1,s,f)) +# define ucl_fwrite(f,b,s) (fwrite(b,1,s,f)) +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/tools/ucl/src/alloc.c b/tools/ucl/src/alloc.c new file mode 100644 index 0000000000..d32ea5113a --- /dev/null +++ b/tools/ucl/src/alloc.c @@ -0,0 +1,151 @@ +/* alloc.c -- memory allocation + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" + +#if defined(HAVE_MALLOC_H) +# include +#endif +#if defined(__palmos__) +# include +#endif + + +#undef ucl_alloc_hook +#undef ucl_free_hook +#undef ucl_alloc +#undef ucl_malloc +#undef ucl_free + + +/*********************************************************************** +// implementation +************************************************************************/ + +UCL_PRIVATE(ucl_voidp) +ucl_alloc_internal(ucl_uint nelems, ucl_uint size) +{ + ucl_voidp p = NULL; + unsigned long s = (unsigned long) nelems * size; + + if (nelems <= 0 || size <= 0 || s < nelems || s < size) + return NULL; + +#if defined(__palmos__) + p = (ucl_voidp) MemPtrNew(s); +#elif (UCL_UINT_MAX <= SIZE_T_MAX) + if (s < SIZE_T_MAX) + p = (ucl_voidp) malloc((size_t)s); +#elif defined(HAVE_HALLOC) && defined(__DMC__) + if (size < SIZE_T_MAX) + p = (ucl_voidp) _halloc(nelems,(size_t)size); +#elif defined(HAVE_HALLOC) + if (size < SIZE_T_MAX) + p = (ucl_voidp) halloc(nelems,(size_t)size); +#else + if (s < SIZE_T_MAX) + p = (ucl_voidp) malloc((size_t)s); +#endif + + return p; +} + + +UCL_PRIVATE(void) +ucl_free_internal(ucl_voidp p) +{ + if (!p) + return; + +#if defined(__palmos__) + MemPtrFree(p); +#elif (UCL_UINT_MAX <= SIZE_T_MAX) + free(p); +#elif defined(HAVE_HALLOC) && defined(__DMC__) + _hfree(p); +#elif defined(HAVE_HALLOC) + hfree(p); +#else + free(p); +#endif +} + + +/*********************************************************************** +// public interface using the global hooks +************************************************************************/ + +/* global allocator hooks */ +ucl_alloc_hook_t ucl_alloc_hook = ucl_alloc_internal; +ucl_free_hook_t ucl_free_hook = ucl_free_internal; + + +UCL_PUBLIC(ucl_voidp) +ucl_alloc(ucl_uint nelems, ucl_uint size) +{ + if (!ucl_alloc_hook) + return NULL; + + return ucl_alloc_hook(nelems,size); +} + + +UCL_PUBLIC(ucl_voidp) +ucl_malloc(ucl_uint size) +{ + if (!ucl_alloc_hook) + return NULL; + +#if defined(__palmos__) + return ucl_alloc_hook(size,1); +#elif (UCL_UINT_MAX <= SIZE_T_MAX) + return ucl_alloc_hook(size,1); +#elif defined(HAVE_HALLOC) + /* use segment granularity by default */ + if (size + 15 > size) /* avoid overflow */ + return ucl_alloc_hook((size+15)/16,16); + return ucl_alloc_hook(size,1); +#else + return ucl_alloc_hook(size,1); +#endif +} + + +UCL_PUBLIC(void) +ucl_free(ucl_voidp p) +{ + if (!ucl_free_hook) + return; + + ucl_free_hook(p); +} + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/fake16.h b/tools/ucl/src/fake16.h new file mode 100644 index 0000000000..db773d5284 --- /dev/null +++ b/tools/ucl/src/fake16.h @@ -0,0 +1,81 @@ +/* fake16.h -- fake the strict 16-bit memory model for test purposes + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* + * NOTE: + * this file is *only* for testing the strict 16-bit memory model + * on a 32-bit machine. Because things like integral promotion, + * size_t and ptrdiff_t cannot be faked this is no real substitute + * for testing under a real 16-bit system. + * + * See also + * + * Usage: #include "src/fake16.h" at the top of + */ + + +#ifndef __UCLFAKE16BIT_H +#define __UCLFAKE16BIT_H + +#ifdef __UCLCONF_H +# error "include this file before uclconf.h" +#endif + +#include + +#if (USHRT_MAX == 0xffff) + +#ifdef __cplusplus +extern "C" { +#endif + +#define __UCL16BIT_H /* do not use */ + +#define __UCL_STRICT_16BIT +#define __UCL_FAKE_STRICT_16BIT + +#define UCL_99_UNSUPPORTED +#define UCL_999_UNSUPPORTED + +typedef unsigned short ucl_uint; +typedef short ucl_int; +#define UCL_UINT_MAX USHRT_MAX +#define UCL_INT_MAX SHRT_MAX + +#if 1 +#define __UCL_NO_UNALIGNED +#define __UCL_NO_ALIGNED +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + +#endif /* already included */ + diff --git a/tools/ucl/src/getbit.h b/tools/ucl/src/getbit.h new file mode 100644 index 0000000000..be27254cd4 --- /dev/null +++ b/tools/ucl/src/getbit.h @@ -0,0 +1,64 @@ +/* getbit.h -- bit-buffer access + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +/*********************************************************************** +// +************************************************************************/ + +#if 1 +#define getbit_8(bb, src, ilen) \ + (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1) +#elif 1 +#define getbit_8(bb, src, ilen) \ + (bb*=2,bb&0xff ? (bb>>8)&1 : ((bb=src[ilen++]*2+1)>>8)&1) +#else +#define getbit_8(bb, src, ilen) \ + (((bb*=2, (bb&0xff ? bb : (bb=src[ilen++]*2+1,bb))) >> 8) & 1) +#endif + + +#define getbit_le16(bb, src, ilen) \ + (bb*=2,bb&0xffff ? (bb>>16)&1 : (ilen+=2,((bb=(src[ilen-2]+src[ilen-1]*256u)*2+1)>>16)&1)) + + +#if 1 && defined(UCL_UNALIGNED_OK_4) && (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) +#define getbit_le32(bb, bc, src, ilen) \ + (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\ + bb=*(const ucl_uint32p)((src)+ilen),ilen+=4,(bb>>31)&1)) +#else +#define getbit_le32(bb, bc, src, ilen) \ + (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\ + bb=src[ilen]+src[ilen+1]*0x100+src[ilen+2]*UCL_UINT32_C(0x10000)+src[ilen+3]*UCL_UINT32_C(0x1000000),\ + ilen+=4,(bb>>31)&1)) +#endif + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/internal.h b/tools/ucl/src/internal.h new file mode 100644 index 0000000000..101ed45cbb --- /dev/null +++ b/tools/ucl/src/internal.h @@ -0,0 +1,48 @@ +/* internal.h -- + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __UCL_INTERNAL_H +#define __UCL_INTERNAL_H + + +/*********************************************************************** +// +************************************************************************/ + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/io.c b/tools/ucl/src/io.c new file mode 100644 index 0000000000..58bd436ac0 --- /dev/null +++ b/tools/ucl/src/io.c @@ -0,0 +1,105 @@ +/* io.c -- io functions + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" + +#if !defined(NO_STDIO_H) + +#include +#include + +#undef ucl_fread +#undef ucl_fwrite + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(ucl_uint) +ucl_fread(FILE *f, ucl_voidp s, ucl_uint len) +{ +#if 1 && (UCL_UINT_MAX <= SIZE_T_MAX) + return fread(s,1,len,f); +#else + ucl_byte *p = (ucl_byte *) s; + ucl_uint l = 0; + size_t k; + unsigned char *b; + unsigned char buf[512]; + + while (l < len) + { + k = len - l > sizeof(buf) ? sizeof(buf) : (size_t) (len - l); + k = fread(buf,1,k,f); + if (k <= 0) + break; + l += k; + b = buf; do *p++ = *b++; while (--k > 0); + } + return l; +#endif +} + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(ucl_uint) +ucl_fwrite(FILE *f, const ucl_voidp s, ucl_uint len) +{ +#if 1 && (UCL_UINT_MAX <= SIZE_T_MAX) + return fwrite(s,1,len,f); +#else + const ucl_byte *p = (const ucl_byte *) s; + ucl_uint l = 0; + size_t k, n; + unsigned char *b; + unsigned char buf[512]; + + while (l < len) + { + k = len - l > sizeof(buf) ? sizeof(buf) : (size_t) (len - l); + b = buf; n = k; do *b++ = *p++; while (--n > 0); + k = fwrite(buf,1,k,f); + if (k <= 0) + break; + l += k; + } + return l; +#endif +} + + +#endif /* !defined(NO_STDIO_H) */ + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/n2_99.ch b/tools/ucl/src/n2_99.ch new file mode 100755 index 0000000000..5df69baaf4 --- /dev/null +++ b/tools/ucl/src/n2_99.ch @@ -0,0 +1,643 @@ +/* n2_99.ch -- implementation of the NRV2[BDE]-99 compression algorithms + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +#include +#include +#include "ucl_conf.h" + +#if 0 +#undef UCL_DEBUG +#define UCL_DEBUG +#endif + +#include + +#if 0 && !defined(UCL_DEBUG) +#undef NDEBUG +#include +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#if 0 +#define N (128*1024ul) /* size of ring buffer */ +#else +#define N (1024*1024ul) /* size of ring buffer */ +#define SWD_USE_MALLOC +#define SWD_HSIZE 65536ul +#endif +#define THRESHOLD 1 /* lower limit for match length */ +#define F 2048 /* upper limit for match length */ + +#if defined(NRV2B) +# define UCL_COMPRESS_T ucl_nrv2b_t +# define ucl_swd_t ucl_nrv2b_swd_t +# define ucl_nrv_99_compress ucl_nrv2b_99_compress +# define M2_MAX_OFFSET 0xd00 +#elif defined(NRV2D) +# define UCL_COMPRESS_T ucl_nrv2d_t +# define ucl_swd_t ucl_nrv2d_swd_t +# define ucl_nrv_99_compress ucl_nrv2d_99_compress +# define M2_MAX_OFFSET 0x500 +#elif defined(NRV2E) +# define UCL_COMPRESS_T ucl_nrv2e_t +# define ucl_swd_t ucl_nrv2e_swd_t +# define ucl_nrv_99_compress ucl_nrv2e_99_compress +# define M2_MAX_OFFSET 0x500 +#else +# error +#endif +#define ucl_swd_p ucl_swd_t * __UCL_MMODEL + +#if 0 +# define HEAD3(b,p) \ + ((((((ucl_uint32)b[p]<<3)^b[p+1])<<3)^b[p+2]) & (SWD_HSIZE-1)) +#endif +#if 0 && defined(UCL_UNALIGNED_OK_4) && (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) +# define HEAD3(b,p) \ + (((* (ucl_uint32p) &b[p]) ^ ((* (ucl_uint32p) &b[p])>>10)) & (SWD_HSIZE-1)) +#endif + +#include "ucl_mchw.ch" + + +/*********************************************************************** +// +************************************************************************/ + +static void code_prefix_ss11(UCL_COMPRESS_T *c, ucl_uint32 i) +{ + if (i >= 2) + { + ucl_uint32 t = 4; + i += 2; + do { + t <<= 1; + } while (i >= t); + t >>= 1; + do { + t >>= 1; + bbPutBit(c, (i & t) ? 1 : 0); + bbPutBit(c, 0); + } while (t > 2); + } + bbPutBit(c, (unsigned)i & 1); + bbPutBit(c, 1); +} + + +#if defined(NRV2D) || defined(NRV2E) +static void code_prefix_ss12(UCL_COMPRESS_T *c, ucl_uint32 i) +{ + if (i >= 2) + { + ucl_uint32 t = 2; + do { + i -= t; + t <<= 2; + } while (i >= t); + do { + t >>= 1; + bbPutBit(c, (i & t) ? 1 : 0); + bbPutBit(c, 0); + t >>= 1; + bbPutBit(c, (i & t) ? 1 : 0); + } while (t > 2); + } + bbPutBit(c, (unsigned)i & 1); + bbPutBit(c, 1); +} +#endif + + +static void +code_match(UCL_COMPRESS_T *c, ucl_uint m_len, const ucl_uint m_off) +{ + unsigned m_low = 0; + + while (m_len > c->conf.max_match) + { + code_match(c, c->conf.max_match - 3, m_off); + m_len -= c->conf.max_match - 3; + } + + c->match_bytes += m_len; + if (m_len > c->result[3]) + c->result[3] = m_len; + if (m_off > c->result[1]) + c->result[1] = m_off; + + bbPutBit(c, 0); + +#if defined(NRV2B) + if (m_off == c->last_m_off) + { + bbPutBit(c, 0); + bbPutBit(c, 1); + } + else + { + code_prefix_ss11(c, 1 + ((m_off - 1) >> 8)); + bbPutByte(c, (unsigned)m_off - 1); + } + m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); + if (m_len >= 4) + { + bbPutBit(c,0); + bbPutBit(c,0); + code_prefix_ss11(c, m_len - 4); + } + else + { + bbPutBit(c, m_len > 1); + bbPutBit(c, (unsigned)m_len & 1); + } +#elif defined(NRV2D) + m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); + assert(m_len > 0); + m_low = (m_len >= 4) ? 0u : (unsigned) m_len; + if (m_off == c->last_m_off) + { + bbPutBit(c, 0); + bbPutBit(c, 1); + bbPutBit(c, m_low > 1); + bbPutBit(c, m_low & 1); + } + else + { + code_prefix_ss12(c, 1 + ((m_off - 1) >> 7)); + bbPutByte(c, ((((unsigned)m_off - 1) & 0x7f) << 1) | ((m_low > 1) ? 0 : 1)); + bbPutBit(c, m_low & 1); + } + if (m_len >= 4) + code_prefix_ss11(c, m_len - 4); +#elif defined(NRV2E) + m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); + assert(m_len > 0); + m_low = (m_len <= 2); + if (m_off == c->last_m_off) + { + bbPutBit(c, 0); + bbPutBit(c, 1); + bbPutBit(c, m_low); + } + else + { + code_prefix_ss12(c, 1 + ((m_off - 1) >> 7)); + bbPutByte(c, ((((unsigned)m_off - 1) & 0x7f) << 1) | (m_low ^ 1)); + } + if (m_low) + bbPutBit(c, (unsigned)m_len - 1); + else if (m_len <= 4) + { + bbPutBit(c, 1); + bbPutBit(c, (unsigned)m_len - 3); + } + else + { + bbPutBit(c, 0); + code_prefix_ss11(c, m_len - 5); + } +#else +# error +#endif + + c->last_m_off = m_off; + UCL_UNUSED(m_low); +} + + +static void +code_run(UCL_COMPRESS_T *c, const ucl_byte *ii, ucl_uint lit) +{ + if (lit == 0) + return; + c->lit_bytes += lit; + if (lit > c->result[5]) + c->result[5] = lit; + do { + bbPutBit(c, 1); + bbPutByte(c, *ii++); + } while (--lit > 0); +} + + +/*********************************************************************** +// +************************************************************************/ + +static int +len_of_coded_match(UCL_COMPRESS_T *c, ucl_uint m_len, ucl_uint m_off) +{ + int b; + if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET)) + || m_off > c->conf.max_offset) + return -1; + assert(m_off > 0); + + m_len = m_len - 2 - (m_off > M2_MAX_OFFSET); + + if (m_off == c->last_m_off) + b = 1 + 2; + else + { +#if defined(NRV2B) + b = 1 + 10; + m_off = (m_off - 1) >> 8; + while (m_off > 0) + { + b += 2; + m_off >>= 1; + } +#elif defined(NRV2D) || defined(NRV2E) + b = 1 + 9; + m_off = (m_off - 1) >> 7; + while (m_off > 0) + { + b += 3; + m_off >>= 2; + } +#else +# error +#endif + } + +#if defined(NRV2B) || defined(NRV2D) + b += 2; + if (m_len < 3) + return b; + m_len -= 3; +#elif defined(NRV2E) + b += 2; + if (m_len < 2) + return b; + if (m_len < 4) + return b + 1; + m_len -= 4; +#else +# error +#endif + do { + b += 2; + m_len >>= 1; + } while (m_len > 0); + + return b; +} + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(NDEBUG) +static +void assert_match( const ucl_swd_p swd, ucl_uint m_len, ucl_uint m_off ) +{ + const UCL_COMPRESS_T *c = swd->c; + ucl_uint d_off; + + assert(m_len >= 2); + if (m_off <= (ucl_uint) (c->bp - c->in)) + { + assert(c->bp - m_off + m_len < c->ip); + assert(ucl_memcmp(c->bp, c->bp - m_off, m_len) == 0); + } + else + { + assert(swd->dict != NULL); + d_off = m_off - (ucl_uint) (c->bp - c->in); + assert(d_off <= swd->dict_len); + if (m_len > d_off) + { + assert(ucl_memcmp(c->bp, swd->dict_end - d_off, d_off) == 0); + assert(c->in + m_len - d_off < c->ip); + assert(ucl_memcmp(c->bp + d_off, c->in, m_len - d_off) == 0); + } + else + { + assert(ucl_memcmp(c->bp, swd->dict_end - d_off, m_len) == 0); + } + } +} +#else +# define assert_match(a,b,c) ((void)0) +#endif + + +#if defined(SWD_BEST_OFF) + +static void +better_match ( const ucl_swd_p swd, ucl_uint *m_len, ucl_uint *m_off ) +{ +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(int) +ucl_nrv_99_compress ( const ucl_bytep in, ucl_uint in_len, + ucl_bytep out, ucl_uintp out_len, + ucl_progress_callback_p cb, + int level, + const struct ucl_compress_config_p conf, + ucl_uintp result) +{ + const ucl_byte *ii; + ucl_uint lit; + ucl_uint m_len, m_off; + UCL_COMPRESS_T c_buffer; + UCL_COMPRESS_T * const c = &c_buffer; +#undef swd +#if 1 && defined(SWD_USE_MALLOC) + ucl_swd_t the_swd; +# define swd (&the_swd) +#else + ucl_swd_p swd; +#endif + ucl_uint result_buffer[16]; + int r; + + struct swd_config_t + { + unsigned try_lazy; + ucl_uint good_length; + ucl_uint max_lazy; + ucl_uint nice_length; + ucl_uint max_chain; + ucl_uint32 flags; + ucl_uint32 max_offset; + }; + const struct swd_config_t *sc; + static const struct swd_config_t swd_config[10] = { + /* faster compression */ + { 0, 0, 0, 8, 4, 0, 48*1024L }, + { 0, 0, 0, 16, 8, 0, 48*1024L }, + { 0, 0, 0, 32, 16, 0, 48*1024L }, + { 1, 4, 4, 16, 16, 0, 48*1024L }, + { 1, 8, 16, 32, 32, 0, 48*1024L }, + { 1, 8, 16, 128, 128, 0, 48*1024L }, + { 2, 8, 32, 128, 256, 0, 128*1024L }, + { 2, 32, 128, F, 2048, 1, 128*1024L }, + { 2, 32, 128, F, 2048, 1, 256*1024L }, + { 2, F, F, F, 4096, 1, N } + /* max. compression */ + }; + + if (level < 1 || level > 10) + return UCL_E_INVALID_ARGUMENT; + sc = &swd_config[level - 1]; + + memset(c, 0, sizeof(*c)); + c->ip = c->in = in; + c->in_end = in + in_len; + c->out = out; + if (cb && cb->callback) + c->cb = cb; + cb = NULL; + c->result = result ? result : (ucl_uintp) result_buffer; + memset(c->result, 0, 16*sizeof(*c->result)); + c->result[0] = c->result[2] = c->result[4] = UCL_UINT_MAX; + result = NULL; + memset(&c->conf, 0xff, sizeof(c->conf)); + if (conf) + memcpy(&c->conf, conf, sizeof(c->conf)); + conf = NULL; + r = bbConfig(c, 0, 8); + if (r == 0) + r = bbConfig(c, c->conf.bb_endian, c->conf.bb_size); + if (r != 0) + return UCL_E_INVALID_ARGUMENT; + c->bb_op = out; + + ii = c->ip; /* point to start of literal run */ + lit = 0; + +#if !defined(swd) + swd = (ucl_swd_p) ucl_alloc(1, ucl_sizeof(*swd)); + if (!swd) + return UCL_E_OUT_OF_MEMORY; +#endif + swd->f = UCL_MIN(F, c->conf.max_match); + swd->n = UCL_MIN(N, sc->max_offset); + if (c->conf.max_offset != UCL_UINT_MAX) + swd->n = UCL_MIN(N, c->conf.max_offset); + if (in_len >= 256 && in_len < swd->n) + swd->n = in_len; + if (swd->f < 8 || swd->n < 256) + return UCL_E_INVALID_ARGUMENT; + r = init_match(c,swd,NULL,0,sc->flags); + if (r != UCL_E_OK) + { +#if !defined(swd) + ucl_free(swd); +#endif + return r; + } + if (sc->max_chain > 0) + swd->max_chain = sc->max_chain; + if (sc->nice_length > 0) + swd->nice_length = sc->nice_length; + if (c->conf.max_match < swd->nice_length) + swd->nice_length = c->conf.max_match; + + if (c->cb) + (*c->cb->callback)(0,0,-1,c->cb->user); + + c->last_m_off = 1; + r = find_match(c,swd,0,0); + if (r != UCL_E_OK) + return r; + while (c->look > 0) + { + ucl_uint ahead; + ucl_uint max_ahead; + int l1, l2; + + c->codesize = c->bb_op - out; + + m_len = c->m_len; + m_off = c->m_off; + + assert(c->bp == c->ip - c->look); + assert(c->bp >= in); + if (lit == 0) + ii = c->bp; + assert(ii + lit == c->bp); + assert(swd->b_char == *(c->bp)); + + if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET)) + || m_off > c->conf.max_offset) + { + /* a literal */ + lit++; + swd->max_chain = sc->max_chain; + r = find_match(c,swd,1,0); + assert(r == 0); + continue; + } + + /* a match */ +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&m_len,&m_off); +#endif + assert_match(swd,m_len,m_off); + + /* shall we try a lazy match ? */ + ahead = 0; + if (sc->try_lazy <= 0 || m_len >= sc->max_lazy || m_off == c->last_m_off) + { + /* no */ + l1 = 0; + max_ahead = 0; + } + else + { + /* yes, try a lazy match */ + l1 = len_of_coded_match(c,m_len,m_off); + assert(l1 > 0); + max_ahead = UCL_MIN(sc->try_lazy, m_len - 1); + } + + while (ahead < max_ahead && c->look > m_len) + { + if (m_len >= sc->good_length) + swd->max_chain = sc->max_chain >> 2; + else + swd->max_chain = sc->max_chain; + r = find_match(c,swd,1,0); + ahead++; + + assert(r == 0); + assert(c->look > 0); + assert(ii + lit + ahead == c->bp); + + if (c->m_len < 2) + continue; +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&c->m_len,&c->m_off); +#endif + l2 = len_of_coded_match(c,c->m_len,c->m_off); + if (l2 < 0) + continue; +#if 1 + if (l1 + (int)(ahead + c->m_len - m_len) * 5 > l2 + (int)(ahead) * 9) +#else + if (l1 > l2) +#endif + { + c->lazy++; + assert_match(swd,c->m_len,c->m_off); + +#if 0 + if (l3 > 0) + { + /* code previous run */ + code_run(c,ii,lit); + lit = 0; + /* code shortened match */ + code_match(c,ahead,m_off); + } + else +#endif + { + lit += ahead; + assert(ii + lit == c->bp); + } + goto lazy_match_done; + } + } + + assert(ii + lit + ahead == c->bp); + + /* 1 - code run */ + code_run(c,ii,lit); + lit = 0; + + /* 2 - code match */ + code_match(c,m_len,m_off); + swd->max_chain = sc->max_chain; + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + +lazy_match_done: ; + } + + /* store final run */ + code_run(c,ii,lit); + + /* EOF */ + bbPutBit(c, 0); +#if defined(NRV2B) + code_prefix_ss11(c, UCL_UINT32_C(0x1000000)); + bbPutByte(c, 0xff); +#elif defined(NRV2D) || defined(NRV2E) + code_prefix_ss12(c, UCL_UINT32_C(0x1000000)); + bbPutByte(c, 0xff); +#else +# error +#endif + bbFlushBits(c, 0); + + assert(c->textsize == in_len); + c->codesize = c->bb_op - out; + *out_len = c->bb_op - out; + if (c->cb) + (*c->cb->callback)(c->textsize,c->codesize,4,c->cb->user); + +#if 0 + printf("%7ld %7ld -> %7ld %7ld %7ld %ld (max: %d %d %d)\n", + (long) c->textsize, (long) in_len, (long) c->codesize, + c->match_bytes, c->lit_bytes, c->lazy, + c->result[1], c->result[3], c->result[5]); +#endif + assert(c->lit_bytes + c->match_bytes == in_len); + + swd_exit(swd); +#if !defined(swd) + ucl_free(swd); +#endif + return UCL_E_OK; +#undef swd +} + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2b_99.c b/tools/ucl/src/n2b_99.c new file mode 100644 index 0000000000..d2e6d6edf5 --- /dev/null +++ b/tools/ucl/src/n2b_99.c @@ -0,0 +1,38 @@ +/* n2b_99.c -- implementation of the NRV2B-99 compression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +#define NRV2B +#include "n2_99.ch" +#undef NRV2B + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2b_d.c b/tools/ucl/src/n2b_d.c new file mode 100644 index 0000000000..e8f96d6d37 --- /dev/null +++ b/tools/ucl/src/n2b_d.c @@ -0,0 +1,178 @@ +/* n2b_d.c -- implementation of the NRV2B decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +/*********************************************************************** +// actual implementation used by a recursive #include +************************************************************************/ + +#ifdef getbit + +#ifdef SAFE +#define fail(x,r) if (x) { *dst_len = olen; return r; } +#else +#define fail(x,r) +#endif + +{ + ucl_uint32 bb = 0; +#ifdef TEST_OVERLAP + ucl_uint ilen = src_off, olen = 0, last_m_off = 1; +#else + ucl_uint ilen = 0, olen = 0, last_m_off = 1; +#endif +#ifdef SAFE + const ucl_uint oend = *dst_len; +#endif + UCL_UNUSED(wrkmem); + +#ifdef TEST_OVERLAP + src_len += src_off; + fail(oend >= src_len, UCL_E_OVERLAP_OVERRUN); +#endif + + for (;;) + { + ucl_uint m_off, m_len; + + while (getbit(bb)) + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(olen >= oend, UCL_E_OUTPUT_OVERRUN); +#ifdef TEST_OVERLAP + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); + olen++; ilen++; +#else + dst[olen++] = src[ilen++]; +#endif + } + m_off = 1; + do { + m_off = m_off*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_off > UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN); + } while (!getbit(bb)); + if (m_off == 2) + { + m_off = last_m_off; + } + else + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + m_off = (m_off-3)*256 + src[ilen++]; + if (m_off == UCL_UINT32_C(0xffffffff)) + break; + last_m_off = ++m_off; + } + m_len = getbit(bb); + m_len = m_len*2 + getbit(bb); + if (m_len == 0) + { + m_len++; + do { + m_len = m_len*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_len >= oend, UCL_E_OUTPUT_OVERRUN); + } while (!getbit(bb)); + m_len += 2; + } + m_len += (m_off > 0xd00); + fail(olen + m_len > oend, UCL_E_OUTPUT_OVERRUN); + fail(m_off > olen, UCL_E_LOOKBEHIND_OVERRUN); +#ifdef TEST_OVERLAP + olen += m_len + 1; + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); +#else + { + const ucl_byte *m_pos; + m_pos = dst + olen - m_off; + dst[olen++] = *m_pos++; + do dst[olen++] = *m_pos++; while (--m_len > 0); + } +#endif + } + *dst_len = olen; + return ilen == src_len ? UCL_E_OK : (ilen < src_len ? UCL_E_INPUT_NOT_CONSUMED : UCL_E_INPUT_OVERRUN); +} + +#undef fail + +#endif /* getbit */ + + +/*********************************************************************** +// decompressor entries for the different bit-buffer sizes +************************************************************************/ + +#ifndef getbit + +#include +#include "ucl_conf.h" +#include "getbit.h" + + +UCL_PUBLIC(int) +ucl_nrv2b_decompress_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2b_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2b_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +#endif /* !getbit */ + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2b_ds.c b/tools/ucl/src/n2b_ds.c new file mode 100644 index 0000000000..1a52b46218 --- /dev/null +++ b/tools/ucl/src/n2b_ds.c @@ -0,0 +1,40 @@ +/* n2b_ds.c -- implementation of the NRV2B decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#define SAFE +#define ucl_nrv2b_decompress_8 ucl_nrv2b_decompress_safe_8 +#define ucl_nrv2b_decompress_le16 ucl_nrv2b_decompress_safe_le16 +#define ucl_nrv2b_decompress_le32 ucl_nrv2b_decompress_safe_le32 +#include "n2b_d.c" +#undef SAFE + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2b_to.c b/tools/ucl/src/n2b_to.c new file mode 100644 index 0000000000..29a6d65820 --- /dev/null +++ b/tools/ucl/src/n2b_to.c @@ -0,0 +1,79 @@ +/* n2b_to.c -- implementation of the NRV2B test overlap algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +/*********************************************************************** +// entries for the different bit-buffer sizes +************************************************************************/ + +#include +#include "ucl_conf.h" +#include "getbit.h" + +#define SAFE +#define TEST_OVERLAP + + +UCL_PUBLIC(int) +ucl_nrv2b_test_overlap_8 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2b_test_overlap_le16 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2b_test_overlap_le32 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2b_d.c" +#undef getbit +} + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2d_99.c b/tools/ucl/src/n2d_99.c new file mode 100644 index 0000000000..c4d501a26b --- /dev/null +++ b/tools/ucl/src/n2d_99.c @@ -0,0 +1,38 @@ +/* n2d_99.c -- implementation of the NRV2D-99 compression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +#define NRV2D +#include "n2_99.ch" +#undef NRV2D + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2d_d.c b/tools/ucl/src/n2d_d.c new file mode 100644 index 0000000000..42409506c3 --- /dev/null +++ b/tools/ucl/src/n2d_d.c @@ -0,0 +1,183 @@ +/* n2d_d.c -- implementation of the NRV2D decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +/*********************************************************************** +// actual implementation used by a recursive #include +************************************************************************/ + +#ifdef getbit + +#ifdef SAFE +#define fail(x,r) if (x) { *dst_len = olen; return r; } +#else +#define fail(x,r) +#endif + +{ + ucl_uint32 bb = 0; +#ifdef TEST_OVERLAP + ucl_uint ilen = src_off, olen = 0, last_m_off = 1; +#else + ucl_uint ilen = 0, olen = 0, last_m_off = 1; +#endif +#ifdef SAFE + const ucl_uint oend = *dst_len; +#endif + UCL_UNUSED(wrkmem); + +#ifdef TEST_OVERLAP + src_len += src_off; + fail(oend >= src_len, UCL_E_OVERLAP_OVERRUN); +#endif + + for (;;) + { + ucl_uint m_off, m_len; + + while (getbit(bb)) + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(olen >= oend, UCL_E_OUTPUT_OVERRUN); +#ifdef TEST_OVERLAP + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); + olen++; ilen++; +#else + dst[olen++] = src[ilen++]; +#endif + } + m_off = 1; + for (;;) + { + m_off = m_off*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_off > UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN); + if (getbit(bb)) break; + m_off = (m_off-1)*2 + getbit(bb); + } + if (m_off == 2) + { + m_off = last_m_off; + m_len = getbit(bb); + } + else + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + m_off = (m_off-3)*256 + src[ilen++]; + if (m_off == UCL_UINT32_C(0xffffffff)) + break; + m_len = (m_off ^ UCL_UINT32_C(0xffffffff)) & 1; + m_off >>= 1; + last_m_off = ++m_off; + } + m_len = m_len*2 + getbit(bb); + if (m_len == 0) + { + m_len++; + do { + m_len = m_len*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_len >= oend, UCL_E_OUTPUT_OVERRUN); + } while (!getbit(bb)); + m_len += 2; + } + m_len += (m_off > 0x500); + fail(olen + m_len > oend, UCL_E_OUTPUT_OVERRUN); + fail(m_off > olen, UCL_E_LOOKBEHIND_OVERRUN); +#ifdef TEST_OVERLAP + olen += m_len + 1; + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); +#else + { + const ucl_byte *m_pos; + m_pos = dst + olen - m_off; + dst[olen++] = *m_pos++; + do dst[olen++] = *m_pos++; while (--m_len > 0); + } +#endif + } + *dst_len = olen; + return ilen == src_len ? UCL_E_OK : (ilen < src_len ? UCL_E_INPUT_NOT_CONSUMED : UCL_E_INPUT_OVERRUN); +} + +#undef fail + +#endif /* getbit */ + + +/*********************************************************************** +// decompressor entries for the different bit-buffer sizes +************************************************************************/ + +#ifndef getbit + +#include +#include "ucl_conf.h" +#include "getbit.h" + + +UCL_PUBLIC(int) +ucl_nrv2d_decompress_8 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2d_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2d_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +#endif /* !getbit */ + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2d_ds.c b/tools/ucl/src/n2d_ds.c new file mode 100644 index 0000000000..81b15c02a0 --- /dev/null +++ b/tools/ucl/src/n2d_ds.c @@ -0,0 +1,40 @@ +/* n2d_ds.c -- implementation of the NRV2D decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#define SAFE +#define ucl_nrv2d_decompress_8 ucl_nrv2d_decompress_safe_8 +#define ucl_nrv2d_decompress_le16 ucl_nrv2d_decompress_safe_le16 +#define ucl_nrv2d_decompress_le32 ucl_nrv2d_decompress_safe_le32 +#include "n2d_d.c" +#undef SAFE + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2d_to.c b/tools/ucl/src/n2d_to.c new file mode 100644 index 0000000000..58b43fa57a --- /dev/null +++ b/tools/ucl/src/n2d_to.c @@ -0,0 +1,79 @@ +/* n2d_to.c -- implementation of the NRV2D test overlap algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +/*********************************************************************** +// entries for the different bit-buffer sizes +************************************************************************/ + +#include +#include "ucl_conf.h" +#include "getbit.h" + +#define SAFE +#define TEST_OVERLAP + + +UCL_PUBLIC(int) +ucl_nrv2d_test_overlap_8 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2d_test_overlap_le16 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2d_test_overlap_le32 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2d_d.c" +#undef getbit +} + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2e_99.c b/tools/ucl/src/n2e_99.c new file mode 100644 index 0000000000..122c4dc036 --- /dev/null +++ b/tools/ucl/src/n2e_99.c @@ -0,0 +1,38 @@ +/* n2e_99.c -- implementation of the NRV2E-99 compression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +#define NRV2E +#include "n2_99.ch" +#undef NRV2E + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2e_d.c b/tools/ucl/src/n2e_d.c new file mode 100644 index 0000000000..6c4586d75c --- /dev/null +++ b/tools/ucl/src/n2e_d.c @@ -0,0 +1,186 @@ +/* n2e_d.c -- implementation of the NRV2E decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +/*********************************************************************** +// actual implementation used by a recursive #include +************************************************************************/ + +#ifdef getbit + +#ifdef SAFE +#define fail(x,r) if (x) { *dst_len = olen; return r; } +#else +#define fail(x,r) +#endif + +{ + ucl_uint32 bb = 0; +#ifdef TEST_OVERLAP + ucl_uint ilen = src_off, olen = 0, last_m_off = 1; +#else + ucl_uint ilen = 0, olen = 0, last_m_off = 1; +#endif +#ifdef SAFE + const ucl_uint oend = *dst_len; +#endif + UCL_UNUSED(wrkmem); + +#ifdef TEST_OVERLAP + src_len += src_off; + fail(oend >= src_len, UCL_E_OVERLAP_OVERRUN); +#endif + + for (;;) + { + ucl_uint m_off, m_len; + + while (getbit(bb)) + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(olen >= oend, UCL_E_OUTPUT_OVERRUN); +#ifdef TEST_OVERLAP + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); + olen++; ilen++; +#else + dst[olen++] = src[ilen++]; +#endif + } + m_off = 1; + for (;;) + { + m_off = m_off*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_off > UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN); + if (getbit(bb)) break; + m_off = (m_off-1)*2 + getbit(bb); + } + if (m_off == 2) + { + m_off = last_m_off; + m_len = getbit(bb); + } + else + { + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + m_off = (m_off-3)*256 + src[ilen++]; + if (m_off == UCL_UINT32_C(0xffffffff)) + break; + m_len = (m_off ^ UCL_UINT32_C(0xffffffff)) & 1; + m_off >>= 1; + last_m_off = ++m_off; + } + if (m_len) + m_len = 1 + getbit(bb); + else if (getbit(bb)) + m_len = 3 + getbit(bb); + else + { + m_len++; + do { + m_len = m_len*2 + getbit(bb); + fail(ilen >= src_len, UCL_E_INPUT_OVERRUN); + fail(m_len >= oend, UCL_E_OUTPUT_OVERRUN); + } while (!getbit(bb)); + m_len += 3; + } + m_len += (m_off > 0x500); + fail(olen + m_len > oend, UCL_E_OUTPUT_OVERRUN); + fail(m_off > olen, UCL_E_LOOKBEHIND_OVERRUN); +#ifdef TEST_OVERLAP + olen += m_len + 1; + fail(olen > ilen, UCL_E_OVERLAP_OVERRUN); +#else + { + const ucl_byte *m_pos; + m_pos = dst + olen - m_off; + dst[olen++] = *m_pos++; + do dst[olen++] = *m_pos++; while (--m_len > 0); + } +#endif + } + *dst_len = olen; + return ilen == src_len ? UCL_E_OK : (ilen < src_len ? UCL_E_INPUT_NOT_CONSUMED : UCL_E_INPUT_OVERRUN); +} + +#undef fail + +#endif /* getbit */ + + +/*********************************************************************** +// decompressor entries for the different bit-buffer sizes +************************************************************************/ + +#ifndef getbit + +#include +#include "ucl_conf.h" +#include "getbit.h" + + +UCL_PUBLIC(int) +ucl_nrv2e_decompress_8 ( const ucl_byte *src, ucl_uint src_len, + ucl_byte *dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2e_decompress_le16 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2e_decompress_le32 ( const ucl_bytep src, ucl_uint src_len, + ucl_bytep dst, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +#endif /* !getbit */ + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2e_ds.c b/tools/ucl/src/n2e_ds.c new file mode 100644 index 0000000000..4afe3899f0 --- /dev/null +++ b/tools/ucl/src/n2e_ds.c @@ -0,0 +1,40 @@ +/* n2e_ds.c -- implementation of the NRV2E decompression algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#define SAFE +#define ucl_nrv2e_decompress_8 ucl_nrv2e_decompress_safe_8 +#define ucl_nrv2e_decompress_le16 ucl_nrv2e_decompress_safe_le16 +#define ucl_nrv2e_decompress_le32 ucl_nrv2e_decompress_safe_le32 +#include "n2e_d.c" +#undef SAFE + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/n2e_to.c b/tools/ucl/src/n2e_to.c new file mode 100644 index 0000000000..33bcd07b19 --- /dev/null +++ b/tools/ucl/src/n2e_to.c @@ -0,0 +1,79 @@ +/* n2e_to.c -- implementation of the NRV2E test overlap algorithm + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + + +/*********************************************************************** +// entries for the different bit-buffer sizes +************************************************************************/ + +#include +#include "ucl_conf.h" +#include "getbit.h" + +#define SAFE +#define TEST_OVERLAP + + +UCL_PUBLIC(int) +ucl_nrv2e_test_overlap_8 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_8(bb,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2e_test_overlap_le16 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ +#define getbit(bb) getbit_le16(bb,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +UCL_PUBLIC(int) +ucl_nrv2e_test_overlap_le32 ( const ucl_bytep src, ucl_uint src_off, + ucl_uint src_len, ucl_uintp dst_len, + ucl_voidp wrkmem ) +{ + unsigned bc = 0; +#define getbit(bb) getbit_le32(bb,bc,src,ilen) +#include "n2e_d.c" +#undef getbit +} + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/ucl_conf.h b/tools/ucl/src/ucl_conf.h new file mode 100644 index 0000000000..37e81c6e03 --- /dev/null +++ b/tools/ucl/src/ucl_conf.h @@ -0,0 +1,359 @@ +/* ucl_conf.h -- main internal configuration file for the the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __UCL_CONF_H +#define __UCL_CONF_H + +#if !defined(__UCL_IN_MINIUCL) +# ifndef __UCLCONF_H +# include +# endif +#endif + + +/*********************************************************************** +// memory checkers +************************************************************************/ + +#if defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + + +/*********************************************************************** +// autoconf section +************************************************************************/ + +#if !defined(UCL_HAVE_CONFIG_H) +# include /* ptrdiff_t, size_t */ +# include /* memcpy, memmove, memcmp, memset */ +# if !defined(NO_STDLIB_H) +# include +# endif +# define HAVE_MEMCMP +# define HAVE_MEMCPY +# define HAVE_MEMMOVE +# define HAVE_MEMSET +#else +# include +# if defined(STDC_HEADERS) +# include +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_MEMORY_H) +# include +# endif +#endif + +#if defined(__UCL_DOS16) || defined(__UCL_WIN16) +# define HAVE_MALLOC_H +# define HAVE_HALLOC +#endif + + +#undef NDEBUG +#if !defined(UCL_DEBUG) +# define NDEBUG +#endif +#if 1 || defined(UCL_DEBUG) || !defined(NDEBUG) +# if !defined(NO_STDIO_H) +# include +# endif +#endif +#include + + +#if !defined(UCL_UNUSED) +# define UCL_UNUSED(parm) (parm = parm) +#endif + + +#if !defined(__inline__) && !defined(__GNUC__) +# if defined(__cplusplus) +# define __inline__ inline +# else +# define __inline__ /* nothing */ +# endif +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#if 1 +# define UCL_BYTE(x) ((unsigned char) (x)) +#else +# define UCL_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif +#if 0 +# define UCL_USHORT(x) ((unsigned short) (x)) +#else +# define UCL_USHORT(x) ((unsigned short) ((x) & 0xffff)) +#endif + +#define UCL_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define UCL_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define UCL_MAX3(a,b,c) ((a) >= (b) ? UCL_MAX(a,c) : UCL_MAX(b,c)) +#define UCL_MIN3(a,b,c) ((a) <= (b) ? UCL_MIN(a,c) : UCL_MIN(b,c)) + +#define ucl_sizeof(type) ((ucl_uint) (sizeof(type))) + +#define UCL_HIGH(array) ((ucl_uint) (sizeof(array)/sizeof(*(array)))) + +/* this always fits into 16 bits */ +#define UCL_SIZE(bits) (1u << (bits)) +#define UCL_MASK(bits) (UCL_SIZE(bits) - 1) + +#define UCL_LSIZE(bits) (1ul << (bits)) +#define UCL_LMASK(bits) (UCL_LSIZE(bits) - 1) + +#define UCL_USIZE(bits) ((ucl_uint) 1 << (bits)) +#define UCL_UMASK(bits) (UCL_USIZE(bits) - 1) + +/* Maximum value of a signed/unsigned type. + Do not use casts, avoid overflows ! */ +#define UCL_STYPE_MAX(b) (((1l << (8*(b)-2)) - 1l) + (1l << (8*(b)-2))) +#define UCL_UTYPE_MAX(b) (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1))) + + +/*********************************************************************** +// +************************************************************************/ + +#if !defined(SIZEOF_UNSIGNED) +# if (UINT_MAX == 0xffff) +# define SIZEOF_UNSIGNED 2 +# elif (UINT_MAX == UCL_0xffffffffL) +# define SIZEOF_UNSIGNED 4 +# elif (UINT_MAX >= UCL_0xffffffffL) +# define SIZEOF_UNSIGNED 8 +# else +# error "SIZEOF_UNSIGNED" +# endif +#endif + +#if !defined(SIZEOF_UNSIGNED_LONG) +# if (ULONG_MAX == UCL_0xffffffffL) +# define SIZEOF_UNSIGNED_LONG 4 +# elif (ULONG_MAX >= UCL_0xffffffffL) +# define SIZEOF_UNSIGNED_LONG 8 +# else +# error "SIZEOF_UNSIGNED_LONG" +# endif +#endif + + +#if !defined(SIZEOF_SIZE_T) +# define SIZEOF_SIZE_T SIZEOF_UNSIGNED +#endif +#if !defined(SIZE_T_MAX) +# define SIZE_T_MAX UCL_UTYPE_MAX(SIZEOF_SIZE_T) +#endif + + +/*********************************************************************** +// section +************************************************************************/ + +#if defined(NO_MEMCMP) +# undef HAVE_MEMCMP +#endif + +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP) +# define ucl_memcmp memcmp +#endif +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY) +# define ucl_memcpy memcpy +#endif +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE) +# define ucl_memmove memmove +#endif +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) +# define ucl_memset memset +#endif + +#if !defined(HAVE_MEMCMP) +# undef memcmp +# define memcmp ucl_memcmp +#endif +#if !defined(HAVE_MEMCPY) +# undef memcpy +# define memcpy ucl_memcpy +#endif +#if !defined(HAVE_MEMMOVE) +# undef memmove +# define memmove ucl_memmove +#endif +#if !defined(HAVE_MEMSET) +# undef memset +# define memset ucl_memset +#endif + + +/*********************************************************************** +// compiler and architecture specific stuff +************************************************************************/ + +/* Some defines that indicate if memory can be accessed at unaligned + * memory addresses. You should also test that this is actually faster + * even if it is allowed by your system. + */ + +#if 1 && defined(__UCL_i386) && (UINT_MAX == UCL_0xffffffffL) +# if !defined(UCL_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff) +# define UCL_UNALIGNED_OK_2 +# endif +# if !defined(UCL_UNALIGNED_OK_4) && (UCL_UINT32_MAX == UCL_0xffffffffL) +# define UCL_UNALIGNED_OK_4 +# endif +#endif + +#if defined(UCL_UNALIGNED_OK_2) || defined(UCL_UNALIGNED_OK_4) +# if !defined(UCL_UNALIGNED_OK) +# define UCL_UNALIGNED_OK +# endif +#endif + +#if defined(__UCL_NO_UNALIGNED) +# undef UCL_UNALIGNED_OK +# undef UCL_UNALIGNED_OK_2 +# undef UCL_UNALIGNED_OK_4 +#endif + +#if defined(UCL_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff) +# error "UCL_UNALIGNED_OK_2 must not be defined on this system" +#endif +#if defined(UCL_UNALIGNED_OK_4) && (UCL_UINT32_MAX != UCL_0xffffffffL) +# error "UCL_UNALIGNED_OK_4 must not be defined on this system" +#endif + + +/* Many modern processors can transfer 32bit words much faster than + * bytes - this can significantly speed decompression. + */ + +#if defined(__UCL_NO_ALIGNED) +# undef UCL_ALIGNED_OK_4 +#endif + +#if defined(UCL_ALIGNED_OK_4) && (UCL_UINT32_MAX != UCL_0xffffffffL) +# error "UCL_ALIGNED_OK_4 must not be defined on this system" +#endif + + +/* Definitions for byte order, according to significance of bytes, from low + * addresses to high addresses. The value is what you get by putting '4' + * in the most significant byte, '3' in the second most significant byte, + * '2' in the second least significant byte, and '1' in the least + * significant byte. + * The byte order is only needed if we use UCL_UNALIGNED_OK. + */ + +#define UCL_LITTLE_ENDIAN 1234 +#define UCL_BIG_ENDIAN 4321 +#define UCL_PDP_ENDIAN 3412 + +#if !defined(UCL_BYTE_ORDER) +# if defined(MFX_BYTE_ORDER) +# define UCL_BYTE_ORDER MFX_BYTE_ORDER +# elif defined(__UCL_i386) +# define UCL_BYTE_ORDER UCL_LITTLE_ENDIAN +# elif defined(BYTE_ORDER) +# define UCL_BYTE_ORDER BYTE_ORDER +# elif defined(__BYTE_ORDER) +# define UCL_BYTE_ORDER __BYTE_ORDER +# endif +#endif + +#if defined(UCL_BYTE_ORDER) +# if (UCL_BYTE_ORDER != UCL_LITTLE_ENDIAN) && \ + (UCL_BYTE_ORDER != UCL_BIG_ENDIAN) +# error "invalid UCL_BYTE_ORDER" +# endif +#endif + +#if defined(UCL_UNALIGNED_OK) && !defined(UCL_BYTE_ORDER) +# error "UCL_BYTE_ORDER is not defined" +#endif + + +/*********************************************************************** +// some globals +************************************************************************/ + +__UCL_EXTERN_C int __ucl_init_done; +__UCL_EXTERN_C const ucl_byte __ucl_copyright[]; +UCL_EXTERN(const ucl_byte *) ucl_copyright(void); +__UCL_EXTERN_C const ucl_uint32 _ucl_crc32_table[256]; + + +/*********************************************************************** +// ANSI C preprocessor macros +************************************************************************/ + +#define _UCL_STRINGIZE(x) #x +#define _UCL_MEXPAND(x) _UCL_STRINGIZE(x) + +/* concatenate */ +#define _UCL_CONCAT2(a,b) a ## b +#define _UCL_CONCAT3(a,b,c) a ## b ## c +#define _UCL_CONCAT4(a,b,c,d) a ## b ## c ## d +#define _UCL_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e + +/* expand and concatenate (by using one level of indirection) */ +#define _UCL_ECONCAT2(a,b) _UCL_CONCAT2(a,b) +#define _UCL_ECONCAT3(a,b,c) _UCL_CONCAT3(a,b,c) +#define _UCL_ECONCAT4(a,b,c,d) _UCL_CONCAT4(a,b,c,d) +#define _UCL_ECONCAT5(a,b,c,d,e) _UCL_CONCAT5(a,b,c,d,e) + + +/*********************************************************************** +// +************************************************************************/ + +#include "ucl_ptr.h" + + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/ucl_crc.c b/tools/ucl/src/ucl_crc.c new file mode 100644 index 0000000000..7608ecffb6 --- /dev/null +++ b/tools/ucl/src/ucl_crc.c @@ -0,0 +1,135 @@ +/* ucl_crc.c -- crc checksum for the the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" +#include "ucl_util.h" + + +/*********************************************************************** +// crc32 checksum +// adapted from free code by Mark Adler +// see http://www.cdrom.com/pub/infozip/zlib/ +************************************************************************/ + +const ucl_uint32 _ucl_crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + + +#if 1 +#define UCL_DO1(buf,i) \ + crc = _ucl_crc32_table[((int)crc ^ buf[i]) & 0xff] ^ (crc >> 8) +#else +#define UCL_DO1(buf,i) \ + crc = _ucl_crc32_table[(unsigned char)((unsigned char)crc ^ buf[i])] ^ (crc >> 8) +#endif +#define UCL_DO2(buf,i) UCL_DO1(buf,i); UCL_DO1(buf,i+1); +#define UCL_DO4(buf,i) UCL_DO2(buf,i); UCL_DO2(buf,i+2); +#define UCL_DO8(buf,i) UCL_DO4(buf,i); UCL_DO4(buf,i+4); +#define UCL_DO16(buf,i) UCL_DO8(buf,i); UCL_DO8(buf,i+8); + + +UCL_PUBLIC(ucl_uint32) +ucl_crc32(ucl_uint32 c, const ucl_bytep buf, ucl_uint len) +{ + ucl_uint32 crc = (c & UCL_UINT32_C(0xffffffff)) ^ UCL_UINT32_C(0xffffffff); + + if (buf == NULL) + return 0; + + if (len >= 16) do + { + UCL_DO16(buf,0); + buf += 16; + len -= 16; + } while (len >= 16); + if (len != 0) do + { + UCL_DO1(buf,0); + buf += 1; + len -= 1; + } while (len > 0); + + return crc ^ UCL_UINT32_C(0xffffffff); +} + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_dll.c b/tools/ucl/src/ucl_dll.c new file mode 100644 index 0000000000..ec9df43e73 --- /dev/null +++ b/tools/ucl/src/ucl_dll.c @@ -0,0 +1,61 @@ +/* ucl_dll.c -- DLL initialization of the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" + + +/*********************************************************************** +// Windows 16 bit + Watcom C + DLL +************************************************************************/ + +#if defined(__UCL_WIN16) && defined(__WATCOMC__) && defined(__SW_BD) + +/* don't pull in - we don't need it */ +#if 0 +#include +#endif + +#pragma off (unreferenced); +#if 0 && defined(WINVER) +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +#pragma on (unreferenced); +{ + return 1; +} + +#endif + + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_init.c b/tools/ucl/src/ucl_init.c new file mode 100644 index 0000000000..4798acae97 --- /dev/null +++ b/tools/ucl/src/ucl_init.c @@ -0,0 +1,500 @@ +/* ucl_init.c -- initialization of the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" +#include "ucl_util.h" +#include + + +#if 0 +# define IS_SIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) < 0) +# define IS_UNSIGNED(type) (((type) (1ul << (8 * sizeof(type) - 1))) > 0) +#else +# define IS_SIGNED(type) (((type) (-1)) < ((type) 0)) +# define IS_UNSIGNED(type) (((type) (-1)) > ((type) 0)) +#endif + + +/*********************************************************************** +// Runtime check of the assumptions about the size of builtin types, +// memory model, byte order and other low-level constructs. +// +// We are really paranoid here - UCL should either fail (or crash) +// at startup or not at all. +// +// Because of inlining much of these functions evaluates to nothing. +************************************************************************/ + +static ucl_bool schedule_insns_bug(void); /* avoid inlining */ +static ucl_bool strength_reduce_bug(int *); /* avoid inlining */ + + +#if 0 || defined(UCL_DEBUG) +static ucl_bool __ucl_assert_fail(const char *s, unsigned line) +{ +#if defined(__palmos__) + printf("UCL assertion failed in line %u: '%s'\n",line,s); +#else + fprintf(stderr,"UCL assertion failed in line %u: '%s'\n",line,s); +#endif + return 0; +} +# define __ucl_assert(x) ((x) ? 1 : __ucl_assert_fail(#x,__LINE__)) +#else +# define __ucl_assert(x) ((x) ? 1 : 0) +#endif + + +/*********************************************************************** +// The next two functions should get completely optimized out of existance. +// Some assertions are redundant - but included for clarity. +************************************************************************/ + +static ucl_bool basic_integral_check(void) +{ + ucl_bool r = 1; + ucl_bool sanity; + + /* paranoia */ + r &= __ucl_assert(CHAR_BIT == 8); + r &= __ucl_assert(sizeof(char) == 1); + r &= __ucl_assert(sizeof(short) >= 2); + r &= __ucl_assert(sizeof(long) >= 4); + r &= __ucl_assert(sizeof(int) >= sizeof(short)); + r &= __ucl_assert(sizeof(long) >= sizeof(int)); + + r &= __ucl_assert(sizeof(ucl_uint32) >= 4); + r &= __ucl_assert(sizeof(ucl_uint32) >= sizeof(unsigned)); +#if defined(__UCL_STRICT_16BIT) + r &= __ucl_assert(sizeof(ucl_uint) == 2); +#else + r &= __ucl_assert(sizeof(ucl_uint) >= 4); + r &= __ucl_assert(sizeof(ucl_uint) >= sizeof(unsigned)); +#endif + +#if defined(SIZEOF_UNSIGNED) + r &= __ucl_assert(SIZEOF_UNSIGNED == sizeof(unsigned)); +#endif +#if defined(SIZEOF_UNSIGNED_LONG) + r &= __ucl_assert(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long)); +#endif +#if defined(SIZEOF_UNSIGNED_SHORT) + r &= __ucl_assert(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short)); +#endif +#if !defined(__UCL_IN_MINIUCL) +#if defined(SIZEOF_SIZE_T) + r &= __ucl_assert(SIZEOF_SIZE_T == sizeof(size_t)); +#endif +#endif + + /* assert the signedness of our integral types */ + sanity = IS_UNSIGNED(unsigned short) && IS_UNSIGNED(unsigned) && + IS_UNSIGNED(unsigned long) && + IS_SIGNED(short) && IS_SIGNED(int) && IS_SIGNED(long); + if (sanity) + { + r &= __ucl_assert(IS_UNSIGNED(ucl_uint32)); + r &= __ucl_assert(IS_UNSIGNED(ucl_uint)); + r &= __ucl_assert(IS_SIGNED(ucl_int32)); + r &= __ucl_assert(IS_SIGNED(ucl_int)); + + r &= __ucl_assert(INT_MAX == UCL_STYPE_MAX(sizeof(int))); + r &= __ucl_assert(UINT_MAX == UCL_UTYPE_MAX(sizeof(unsigned))); + r &= __ucl_assert(LONG_MAX == UCL_STYPE_MAX(sizeof(long))); + r &= __ucl_assert(ULONG_MAX == UCL_UTYPE_MAX(sizeof(unsigned long))); + r &= __ucl_assert(SHRT_MAX == UCL_STYPE_MAX(sizeof(short))); + r &= __ucl_assert(USHRT_MAX == UCL_UTYPE_MAX(sizeof(unsigned short))); + r &= __ucl_assert(UCL_UINT32_MAX == UCL_UTYPE_MAX(sizeof(ucl_uint32))); + r &= __ucl_assert(UCL_UINT_MAX == UCL_UTYPE_MAX(sizeof(ucl_uint))); +#if !defined(__UCL_IN_MINIUCL) + r &= __ucl_assert(SIZE_T_MAX == UCL_UTYPE_MAX(sizeof(size_t))); +#endif + } + + return r; +} + + +static ucl_bool basic_ptr_check(void) +{ + ucl_bool r = 1; + ucl_bool sanity; + + r &= __ucl_assert(sizeof(char *) >= sizeof(int)); + r &= __ucl_assert(sizeof(ucl_byte *) >= sizeof(char *)); + + r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_byte *)); + r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_voidpp)); + r &= __ucl_assert(sizeof(ucl_voidp) == sizeof(ucl_bytepp)); + r &= __ucl_assert(sizeof(ucl_voidp) >= sizeof(ucl_uint)); + + r &= __ucl_assert(sizeof(ucl_ptr_t) == sizeof(ucl_voidp)); + r &= __ucl_assert(sizeof(ucl_ptr_t) >= sizeof(ucl_uint)); + + r &= __ucl_assert(sizeof(ucl_ptrdiff_t) >= 4); + r &= __ucl_assert(sizeof(ucl_ptrdiff_t) >= sizeof(ptrdiff_t)); + +#if defined(SIZEOF_CHAR_P) + r &= __ucl_assert(SIZEOF_CHAR_P == sizeof(char *)); +#endif +#if defined(SIZEOF_PTRDIFF_T) + r &= __ucl_assert(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)); +#endif + + /* assert the signedness of our integral types */ + sanity = IS_UNSIGNED(unsigned short) && IS_UNSIGNED(unsigned) && + IS_UNSIGNED(unsigned long) && + IS_SIGNED(short) && IS_SIGNED(int) && IS_SIGNED(long); + if (sanity) + { + r &= __ucl_assert(IS_UNSIGNED(ucl_ptr_t)); + r &= __ucl_assert(IS_SIGNED(ucl_ptrdiff_t)); + r &= __ucl_assert(IS_SIGNED(ucl_sptr_t)); + } + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +static ucl_bool ptr_check(void) +{ + ucl_bool r = 1; + int i; + char _wrkmem[10 * sizeof(ucl_byte *) + sizeof(ucl_align_t)]; + ucl_bytep wrkmem; + ucl_bytepp dict; + unsigned char x[4 * sizeof(ucl_align_t)]; + long d; + ucl_align_t a; + ucl_align_t u; + + for (i = 0; i < (int) sizeof(x); i++) + x[i] = UCL_BYTE(i); + + wrkmem = UCL_PTR_ALIGN_UP((ucl_byte *)_wrkmem,sizeof(ucl_align_t)); + +#if 0 + dict = (ucl_bytepp) wrkmem; +#else + /* Avoid a compiler warning on architectures that + * do not allow unaligned access. */ + u.a_ucl_bytep = wrkmem; dict = u.a_ucl_bytepp; +#endif + + d = (long) ((const ucl_bytep) dict - (const ucl_bytep) _wrkmem); + r &= __ucl_assert(d >= 0); + r &= __ucl_assert(d < (long) sizeof(ucl_align_t)); + + memset(&a,0xff,sizeof(a)); + r &= __ucl_assert(a.a_ushort == USHRT_MAX); + r &= __ucl_assert(a.a_uint == UINT_MAX); + r &= __ucl_assert(a.a_ulong == ULONG_MAX); + r &= __ucl_assert(a.a_ucl_uint == UCL_UINT_MAX); + + /* sanity check of the memory model */ + if (r == 1) + { + for (i = 0; i < 8; i++) + r &= __ucl_assert((const ucl_voidp) (&dict[i]) == (const ucl_voidp) (&wrkmem[i * sizeof(ucl_byte *)])); + } + + /* check BZERO8_PTR and that NULL == 0 */ + memset(&a,0,sizeof(a)); + r &= __ucl_assert(a.a_char_p == NULL); + r &= __ucl_assert(a.a_ucl_bytep == NULL); + r &= __ucl_assert(NULL == (void*)0); + if (r == 1) + { + for (i = 0; i < 10; i++) + dict[i] = wrkmem; + BZERO8_PTR(dict+1,sizeof(dict[0]),8); + r &= __ucl_assert(dict[0] == wrkmem); + for (i = 1; i < 9; i++) + r &= __ucl_assert(dict[i] == NULL); + r &= __ucl_assert(dict[9] == wrkmem); + } + + /* check that the pointer constructs work as expected */ + if (r == 1) + { + unsigned k = 1; + const unsigned n = (unsigned) sizeof(ucl_uint32); + ucl_byte *p0; + ucl_byte *p1; + + k += __ucl_align_gap(&x[k],n); + p0 = (ucl_bytep) &x[k]; +#if defined(PTR_LINEAR) + r &= __ucl_assert((PTR_LINEAR(p0) & (n-1)) == 0); +#else + r &= __ucl_assert(n == 4); + r &= __ucl_assert(PTR_ALIGNED_4(p0)); +#endif + + r &= __ucl_assert(k >= 1); + p1 = (ucl_bytep) &x[1]; + r &= __ucl_assert(PTR_GE(p0,p1)); + + r &= __ucl_assert(k < 1+n); + p1 = (ucl_bytep) &x[1+n]; + r &= __ucl_assert(PTR_LT(p0,p1)); + + /* now check that aligned memory access doesn't core dump */ + if (r == 1) + { + ucl_uint32 v0, v1; +#if 0 + v0 = * (ucl_uint32 *) &x[k]; + v1 = * (ucl_uint32 *) &x[k+n]; +#else + /* Avoid compiler warnings on architectures that + * do not allow unaligned access. */ + u.a_uchar_p = &x[k]; + v0 = *u.a_ucl_uint32_p; + u.a_uchar_p = &x[k+n]; + v1 = *u.a_ucl_uint32_p; +#endif + r &= __ucl_assert(v0 > 0); + r &= __ucl_assert(v1 > 0); + } + } + + return r; +} + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(int) +_ucl_config_check(void) +{ + ucl_bool r = 1; + int i; + union { + ucl_uint32 a; + unsigned short b; + ucl_uint32 aa[4]; + unsigned char x[4*sizeof(ucl_align_t)]; + } u; + +#if 0 + /* paranoia - the following is guaranteed by definition anyway */ + r &= __ucl_assert((const void *)&u == (const void *)&u.a); + r &= __ucl_assert((const void *)&u == (const void *)&u.b); + r &= __ucl_assert((const void *)&u == (const void *)&u.x[0]); + r &= __ucl_assert((const void *)&u == (const void *)&u.aa[0]); +#endif + + r &= basic_integral_check(); + r &= basic_ptr_check(); + if (r != 1) + return UCL_E_ERROR; + + u.a = 0; u.b = 0; + for (i = 0; i < (int) sizeof(u.x); i++) + u.x[i] = UCL_BYTE(i); + +#if 0 + /* check if the compiler correctly casts signed to unsigned */ + r &= __ucl_assert( (int) (unsigned char) ((char) -1) == 255); +#endif + + /* check UCL_BYTE_ORDER */ +#if defined(UCL_BYTE_ORDER) + if (r == 1) + { +# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) + ucl_uint32 a = (ucl_uint32) (u.a & UCL_UINT32_C(0xffffffff)); + unsigned short b = (unsigned short) (u.b & 0xffff); + r &= __ucl_assert(a == UCL_UINT32_C(0x03020100)); + r &= __ucl_assert(b == 0x0100); +# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN) + ucl_uint32 a = u.a >> (8 * sizeof(u.a) - 32); + unsigned short b = u.b >> (8 * sizeof(u.b) - 16); + r &= __ucl_assert(a == UCL_UINT32_C(0x00010203)); + r &= __ucl_assert(b == 0x0001); +# else +# error "invalid UCL_BYTE_ORDER" +# endif + } +#endif + + /* check that unaligned memory access works as expected */ +#if defined(UCL_UNALIGNED_OK_2) + r &= __ucl_assert(sizeof(short) == 2); + if (r == 1) + { + unsigned short b[4]; + + for (i = 0; i < 4; i++) + b[i] = * (const unsigned short *) &u.x[i]; + +# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) + r &= __ucl_assert(b[0] == 0x0100); + r &= __ucl_assert(b[1] == 0x0201); + r &= __ucl_assert(b[2] == 0x0302); + r &= __ucl_assert(b[3] == 0x0403); +# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN) + r &= __ucl_assert(b[0] == 0x0001); + r &= __ucl_assert(b[1] == 0x0102); + r &= __ucl_assert(b[2] == 0x0203); + r &= __ucl_assert(b[3] == 0x0304); +# endif + } +#endif + +#if defined(UCL_UNALIGNED_OK_4) + r &= __ucl_assert(sizeof(ucl_uint32) == 4); + if (r == 1) + { + ucl_uint32 a[4]; + + for (i = 0; i < 4; i++) + a[i] = * (const ucl_uint32 *) &u.x[i]; + +# if (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) + r &= __ucl_assert(a[0] == UCL_UINT32_C(0x03020100)); + r &= __ucl_assert(a[1] == UCL_UINT32_C(0x04030201)); + r &= __ucl_assert(a[2] == UCL_UINT32_C(0x05040302)); + r &= __ucl_assert(a[3] == UCL_UINT32_C(0x06050403)); +# elif (UCL_BYTE_ORDER == UCL_BIG_ENDIAN) + r &= __ucl_assert(a[0] == UCL_UINT32_C(0x00010203)); + r &= __ucl_assert(a[1] == UCL_UINT32_C(0x01020304)); + r &= __ucl_assert(a[2] == UCL_UINT32_C(0x02030405)); + r &= __ucl_assert(a[3] == UCL_UINT32_C(0x03040506)); +# endif + } +#endif + +#if defined(UCL_ALIGNED_OK_4) + r &= __ucl_assert(sizeof(ucl_uint32) == 4); +#endif + + /* check the ucl_adler32() function */ + if (r == 1) + { + ucl_uint32 adler; + adler = ucl_adler32(0, NULL, 0); + adler = ucl_adler32(adler, ucl_copyright(), 186); + r &= __ucl_assert(adler == UCL_UINT32_C(0x47fb39fc)); + } + + /* check for the gcc schedule-insns optimization bug */ + if (r == 1) + { + r &= __ucl_assert(!schedule_insns_bug()); + } + + /* check for the gcc strength-reduce optimization bug */ + if (r == 1) + { + static int x[3]; + static unsigned xn = 3; + register unsigned j; + + for (j = 0; j < xn; j++) + x[j] = (int)j - 3; + r &= __ucl_assert(!strength_reduce_bug(x)); + } + + /* now for the low-level pointer checks */ + if (r == 1) + { + r &= ptr_check(); + } + + return r == 1 ? UCL_E_OK : UCL_E_ERROR; +} + + +static ucl_bool schedule_insns_bug(void) +{ +#if defined(__UCL_CHECKER) + /* for some reason checker complains about uninitialized memory access */ + return 0; +#else + const int clone[] = {1, 2, 0}; + const int *q; + q = clone; + return (*q) ? 0 : 1; +#endif +} + + +static ucl_bool strength_reduce_bug(int *x) +{ + return x[0] != -3 || x[1] != -2 || x[2] != -1; +} + + +/*********************************************************************** +// +************************************************************************/ + +int __ucl_init_done = 0; + +UCL_PUBLIC(int) +__ucl_init2(ucl_uint32 v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + + __ucl_init_done = 1; + + if (v == 0) + return UCL_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(ucl_uint32)) && + (s5 == -1 || s5 == (int) sizeof(ucl_uint)) && + (s6 == -1 || s6 > 0) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(ucl_voidp)) && + (s9 == -1 || s9 == (int) sizeof(ucl_compress_t)); + if (!r) + return UCL_E_ERROR; + + r = _ucl_config_check(); + if (r != UCL_E_OK) + return r; + + return r; +} + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_mchw.ch b/tools/ucl/src/ucl_mchw.ch new file mode 100755 index 0000000000..f2bcc9506f --- /dev/null +++ b/tools/ucl/src/ucl_mchw.ch @@ -0,0 +1,313 @@ +/* ucl_mchw.ch -- matching functions using a window + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + + + +/*********************************************************************** +// +************************************************************************/ + +typedef struct +{ + int init; + + ucl_uint look; /* bytes in lookahead buffer */ + + ucl_uint m_len; + ucl_uint m_off; + + ucl_uint last_m_len; + ucl_uint last_m_off; + + const ucl_byte *bp; + const ucl_byte *ip; + const ucl_byte *in; + const ucl_byte *in_end; + ucl_byte *out; + + ucl_uint32 bb_b; + unsigned bb_k; + unsigned bb_c_endian; + unsigned bb_c_s; + unsigned bb_c_s8; + ucl_byte *bb_p; + ucl_byte *bb_op; + + struct ucl_compress_config_t conf; + ucl_uintp result; + + ucl_progress_callback_p cb; + + ucl_uint textsize; /* text size counter */ + ucl_uint codesize; /* code size counter */ + ucl_uint printcount; /* counter for reporting progress every 1K bytes */ + + /* some stats */ + unsigned long lit_bytes; + unsigned long match_bytes; + unsigned long rep_bytes; + unsigned long lazy; +} +UCL_COMPRESS_T; + + + +#if defined(__PUREC__) && defined(__UCL_TOS16) +/* the cast is needed to work around a bug in Pure C */ +#define getbyte(c) ((c).ip < (c).in_end ? (unsigned) *((c).ip)++ : (-1)) +#else +#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) +#endif + +#include "ucl_swd.ch" + + + +/*********************************************************************** +// +************************************************************************/ + +static int +init_match ( UCL_COMPRESS_T *c, ucl_swd_t *s, + const ucl_byte *dict, ucl_uint dict_len, + ucl_uint32 flags ) +{ + int r; + + assert(!c->init); + c->init = 1; + + s->c = c; + + c->last_m_len = c->last_m_off = 0; + + c->textsize = c->codesize = c->printcount = 0; + c->lit_bytes = c->match_bytes = c->rep_bytes = 0; + c->lazy = 0; + + r = swd_init(s,dict,dict_len); + if (r != UCL_E_OK) + { + swd_exit(s); + return r; + } + + s->use_best_off = (flags & 1) ? 1 : 0; + return UCL_E_OK; +} + + +/*********************************************************************** +// +************************************************************************/ + +static int +find_match ( UCL_COMPRESS_T *c, ucl_swd_t *s, + ucl_uint this_len, ucl_uint skip ) +{ + assert(c->init); + + if (skip > 0) + { + assert(this_len >= skip); + swd_accept(s, this_len - skip); + c->textsize += this_len - skip + 1; + } + else + { + assert(this_len <= 1); + c->textsize += this_len - skip; + } + + s->m_len = THRESHOLD; +#ifdef SWD_BEST_OFF + if (s->use_best_off) + memset(s->best_pos,0,sizeof(s->best_pos)); +#endif + swd_findbest(s); + c->m_len = s->m_len; +#if defined(__UCL_CHECKER) + /* s->m_off may be uninitialized if we didn't find a match, + * but then its value will never be used. + */ + c->m_off = (s->m_len == THRESHOLD) ? 0 : s->m_off; +#else + c->m_off = s->m_off; +#endif + + swd_getbyte(s); + + if (s->b_char < 0) + { + c->look = 0; + c->m_len = 0; + swd_exit(s); + } + else + { + c->look = s->look + 1; + } + c->bp = c->ip - c->look; + +#if 0 + /* brute force match search */ + if (c->m_len > THRESHOLD && c->m_len + 1 <= c->look) + { + const ucl_byte *ip = c->bp; + const ucl_byte *m = c->bp - c->m_off; + const ucl_byte *in = c->in; + + if (ip - in > N) + in = ip - N; + for (;;) + { + while (*in != *ip) + in++; + if (in == ip) + break; + if (in != m) + if (memcmp(in,ip,c->m_len+1) == 0) + printf("%p %p %p %5d\n",in,ip,m,c->m_len); + in++; + } + } +#endif + + if (c->cb && c->textsize > c->printcount) + { + (*c->cb->callback)(c->textsize,c->codesize,3,c->cb->user); + c->printcount += 1024; + } + + return UCL_E_OK; +} + + +/*********************************************************************** +// bit buffer +************************************************************************/ + +static int bbConfig(UCL_COMPRESS_T *c, int endian, int bitsize) +{ + if (endian != -1) + { + if (endian != 0) + return UCL_E_ERROR; + c->bb_c_endian = endian; + } + if (bitsize != -1) + { + if (bitsize != 8 && bitsize != 16 && bitsize != 32) + return UCL_E_ERROR; + c->bb_c_s = bitsize; + c->bb_c_s8 = bitsize / 8; + } + c->bb_b = 0; c->bb_k = 0; + c->bb_p = NULL; + c->bb_op = NULL; + return UCL_E_OK; +} + + +static void bbWriteBits(UCL_COMPRESS_T *c) +{ + ucl_byte *p = c->bb_p; + ucl_uint32 b = c->bb_b; + + p[0] = UCL_BYTE(b >> 0); + if (c->bb_c_s >= 16) + { + p[1] = UCL_BYTE(b >> 8); + if (c->bb_c_s == 32) + { + p[2] = UCL_BYTE(b >> 16); + p[3] = UCL_BYTE(b >> 24); + } + } +} + + +static void bbPutBit(UCL_COMPRESS_T *c, unsigned bit) +{ + assert(bit == 0 || bit == 1); + assert(c->bb_k <= c->bb_c_s); + + if (c->bb_k < c->bb_c_s) + { + if (c->bb_k == 0) + { + assert(c->bb_p == NULL); + c->bb_p = c->bb_op; + c->bb_op += c->bb_c_s8; + } + assert(c->bb_p != NULL); + assert(c->bb_p + c->bb_c_s8 <= c->bb_op); + + c->bb_b = (c->bb_b << 1) + bit; + c->bb_k++; + } + else + { + assert(c->bb_p != NULL); + assert(c->bb_p + c->bb_c_s8 <= c->bb_op); + + bbWriteBits(c); + c->bb_p = c->bb_op; + c->bb_op += c->bb_c_s8; + c->bb_b = bit; + c->bb_k = 1; + } +} + + +static void bbPutByte(UCL_COMPRESS_T *c, unsigned b) +{ + /**printf("putbyte %p %p %x (%d)\n", op, bb_p, x, bb_k);*/ + assert(c->bb_p == NULL || c->bb_p + c->bb_c_s8 <= c->bb_op); + *c->bb_op++ = UCL_BYTE(b); +} + + +static void bbFlushBits(UCL_COMPRESS_T *c, unsigned filler_bit) +{ + if (c->bb_k > 0) + { + assert(c->bb_k <= c->bb_c_s); + while (c->bb_k != c->bb_c_s) + bbPutBit(c, filler_bit); + bbWriteBits(c); + c->bb_k = 0; + } + c->bb_p = NULL; +} + + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/ucl_ptr.c b/tools/ucl/src/ucl_ptr.c new file mode 100644 index 0000000000..b092d2440f --- /dev/null +++ b/tools/ucl/src/ucl_ptr.c @@ -0,0 +1,81 @@ +/* ucl_ptr.c -- low-level pointer constructs + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(ucl_ptr_t) +__ucl_ptr_linear(const ucl_voidp ptr) +{ + ucl_ptr_t p; + +#if defined(__UCL_DOS16) || defined(__UCL_WIN16) + p = (((ucl_ptr_t)(_FP_SEG(ptr))) << (16 - __UCL_HShift)) + (_FP_OFF(ptr)); +#else + p = PTR_LINEAR(ptr); +#endif + + return p; +} + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(unsigned) +__ucl_align_gap(const ucl_voidp ptr, ucl_uint size) +{ + ucl_ptr_t p, s, n; + + assert(size > 0); + + p = __ucl_ptr_linear(ptr); + s = (ucl_ptr_t) (size - 1); +#if 0 + assert((size & (size - 1)) == 0); + n = ((p + s) & ~s) - p; +#else + n = (((p + s) / size) * size) - p; +#endif + + assert((long)n >= 0); + assert(n <= s); + + return (unsigned)n; +} + + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_ptr.h b/tools/ucl/src/ucl_ptr.h new file mode 100644 index 0000000000..86221b9ac1 --- /dev/null +++ b/tools/ucl/src/ucl_ptr.h @@ -0,0 +1,211 @@ +/* ucl_ptr.h -- low-level pointer constructs + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __UCL_PTR_H +#define __UCL_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is the lowest part of the UCL library. + * It deals with pointer representations at bit level. + */ + + +/*********************************************************************** +// Includes +************************************************************************/ + +#if defined(__UCL_DOS16) || defined(__UCL_WIN16) +# include +# if 1 && defined(__WATCOMC__) +# include + __UCL_EXTERN_C unsigned char _HShift; +# define __UCL_HShift _HShift +# elif 1 && defined(_MSC_VER) + __UCL_EXTERN_C unsigned short __near _AHSHIFT; +# define __UCL_HShift ((unsigned) &_AHSHIFT) +# elif defined(__UCL_WIN16) +# define __UCL_HShift 3 +# else +# define __UCL_HShift 12 +# endif +# if !defined(_FP_SEG) && defined(FP_SEG) +# define _FP_SEG FP_SEG +# endif +# if !defined(_FP_OFF) && defined(FP_OFF) +# define _FP_OFF FP_OFF +# endif +#endif + + +/*********************************************************************** +// Integral types +************************************************************************/ + +/* ptrdiff_t */ +#if !defined(ucl_ptrdiff_t) + #if (UINT_MAX >= UCL_0xffffffffL) + typedef ptrdiff_t ucl_ptrdiff_t; + #else + typedef long ucl_ptrdiff_t; + #endif +#endif + + +/* Unsigned type that has *exactly* the same number of bits as a ucl_voidp */ +#if !defined(__UCL_HAVE_PTR_T) +# if defined(ucl_ptr_t) +# define __UCL_HAVE_PTR_T +# endif +#endif +#if !defined(__UCL_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG) + typedef unsigned long ucl_ptr_t; + typedef long ucl_sptr_t; +# define __UCL_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__UCL_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED) + typedef unsigned int ucl_ptr_t; + typedef int ucl_sptr_t; +# define __UCL_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__UCL_HAVE_PTR_T) +# if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT) +# if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT) + typedef unsigned short ucl_ptr_t; + typedef short ucl_sptr_t; +# define __UCL_HAVE_PTR_T +# endif +# endif +#endif +#if !defined(__UCL_HAVE_PTR_T) +# if defined(UCL_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P) +# error "no suitable type for ucl_ptr_t" +# else + typedef unsigned long ucl_ptr_t; + typedef long ucl_sptr_t; +# define __UCL_HAVE_PTR_T +# endif +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Always use the safe (=integral) version for pointer-comparisions. + * The compiler should optimize away the additional casts anyway. + * + * Note that this only works if the representation and ordering + * of the pointer and the integral is the same (at bit level). + * + * Most 16-bit compilers have their own view about pointers - + * fortunately they don't care about comparing pointers + * that are pointing to Nirvana. + */ + +#if defined(__UCL_DOS16) || defined(__UCL_WIN16) +#define PTR(a) ((ucl_bytep) (a)) +/* only need the low bits of the pointer -> offset is ok */ +#define PTR_ALIGNED_4(a) ((_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0) +#else +#define PTR(a) ((ucl_ptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) ((ucl_ptrdiff_t) (PTR(a) - PTR(b))) + + +UCL_EXTERN(ucl_ptr_t) +__ucl_ptr_linear(const ucl_voidp ptr); + + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + ucl_int a_ucl_int; + ucl_uint a_ucl_uint; + ucl_int32 a_ucl_int32; + ucl_uint32 a_ucl_uint32; + ptrdiff_t a_ptrdiff_t; + ucl_ptrdiff_t a_ucl_ptrdiff_t; + ucl_ptr_t a_ucl_ptr_t; + ucl_voidp a_ucl_voidp; + void * a_void_p; + ucl_bytep a_ucl_bytep; + ucl_bytepp a_ucl_bytepp; + ucl_uintp a_ucl_uintp; + ucl_uint * a_ucl_uint_p; + ucl_uint32p a_ucl_uint32p; + ucl_uint32 * a_ucl_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +ucl_align_t; + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/ucl_str.c b/tools/ucl/src/ucl_str.c new file mode 100644 index 0000000000..5866fb6377 --- /dev/null +++ b/tools/ucl/src/ucl_str.c @@ -0,0 +1,133 @@ +/* ucl_str.c -- string functions for the the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" + +#undef ucl_memcmp +#undef ucl_memcpy +#undef ucl_memmove +#undef ucl_memset + + +/*********************************************************************** +// slow but portable stuff, only used in assertions +************************************************************************/ + +UCL_PUBLIC(int) +ucl_memcmp(const ucl_voidp s1, const ucl_voidp s2, ucl_uint len) +{ +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP) + return memcmp(s1,s2,len); +#else + const ucl_byte *p1 = (const ucl_byte *) s1; + const ucl_byte *p2 = (const ucl_byte *) s2; + int d; + + if (len > 0) do + { + d = *p1 - *p2; + if (d != 0) + return d; + p1++; + p2++; + } + while (--len > 0); + return 0; +#endif +} + + +UCL_PUBLIC(ucl_voidp) +ucl_memcpy(ucl_voidp dest, const ucl_voidp src, ucl_uint len) +{ +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY) + return memcpy(dest,src,len); +#else + ucl_byte *p1 = (ucl_byte *) dest; + const ucl_byte *p2 = (const ucl_byte *) src; + + if (len <= 0 || p1 == p2) + return dest; + do + *p1++ = *p2++; + while (--len > 0); + return dest; +#endif +} + + +UCL_PUBLIC(ucl_voidp) +ucl_memmove(ucl_voidp dest, const ucl_voidp src, ucl_uint len) +{ +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE) + return memmove(dest,src,len); +#else + ucl_byte *p1 = (ucl_byte *) dest; + const ucl_byte *p2 = (const ucl_byte *) src; + + if (len <= 0 || p1 == p2) + return dest; + + if (p1 < p2) + { + do + *p1++ = *p2++; + while (--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while (--len > 0); + } + return dest; +#endif +} + + +UCL_PUBLIC(ucl_voidp) +ucl_memset(ucl_voidp s, int c, ucl_uint len) +{ +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) + return memset(s,c,len); +#else + ucl_byte *p = (ucl_byte *) s; + + if (len > 0) do + *p++ = UCL_BYTE(c); + while (--len > 0); + return s; +#endif +} + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_swd.ch b/tools/ucl/src/ucl_swd.ch new file mode 100755 index 0000000000..e40b4a4662 --- /dev/null +++ b/tools/ucl/src/ucl_swd.ch @@ -0,0 +1,665 @@ +/* ucl_swd.c -- sliding window dictionary + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#if (UCL_UINT_MAX < UCL_0xffffffffL) +# error "UCL_UINT_MAX" +#endif + + +/*********************************************************************** +// +************************************************************************/ + +#ifndef SWD_N +# define SWD_N N +#endif +#ifndef SWD_F +# define SWD_F F +#endif +#ifndef SWD_THRESHOLD +# define SWD_THRESHOLD THRESHOLD +#endif + +/* unsigned type for dictionary access - don't waste memory here */ +#if (SWD_N + SWD_F + SWD_F < USHRT_MAX) + typedef unsigned short swd_uint; +# define SWD_UINT_MAX USHRT_MAX +#else + typedef ucl_uint swd_uint; +# define SWD_UINT_MAX UCL_UINT_MAX +#endif +#define SWD_UINT(x) ((swd_uint)(x)) + + +#ifndef SWD_HSIZE +# define SWD_HSIZE 16384 +#endif +#ifndef SWD_MAX_CHAIN +# define SWD_MAX_CHAIN 2048 +#endif + +#if !defined(HEAD3) +#if 1 +# define HEAD3(b,p) \ + (((0x9f5f*(((((ucl_uint32)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1)) +#else +# define HEAD3(b,p) \ + (((0x9f5f*(((((ucl_uint32)b[p+2]<<5)^b[p+1])<<5)^b[p]))>>5) & (SWD_HSIZE-1)) +#endif +#endif + +#if (SWD_THRESHOLD == 1) && !defined(HEAD2) +# if 1 && defined(UCL_UNALIGNED_OK_2) +# define HEAD2(b,p) (* (const ucl_ushortp) &(b[p])) +# else +# define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) +# endif +# define NIL2 SWD_UINT_MAX +#endif + + +#if defined(__UCL_CHECKER) + /* malloc arrays of the exact size to detect any overrun */ +# ifndef SWD_USE_MALLOC +# define SWD_USE_MALLOC +# endif +#endif + + +typedef struct +{ +/* public - "built-in" */ + ucl_uint n; + ucl_uint f; + ucl_uint threshold; + +/* public - configuration */ + ucl_uint max_chain; + ucl_uint nice_length; + ucl_bool use_best_off; + ucl_uint lazy_insert; + +/* public - output */ + ucl_uint m_len; + ucl_uint m_off; + ucl_uint look; + int b_char; +#if defined(SWD_BEST_OFF) + ucl_uint best_off[ SWD_BEST_OFF ]; +#endif + +/* semi public */ + UCL_COMPRESS_T *c; + ucl_uint m_pos; +#if defined(SWD_BEST_OFF) + ucl_uint best_pos[ SWD_BEST_OFF ]; +#endif + +/* private */ + const ucl_byte *dict; + const ucl_byte *dict_end; + ucl_uint dict_len; + +/* private */ + ucl_uint ip; /* input pointer (lookahead) */ + ucl_uint bp; /* buffer pointer */ + ucl_uint rp; /* remove pointer */ + ucl_uint b_size; + + unsigned char *b_wrap; + + ucl_uint node_count; + ucl_uint first_rp; + +#if defined(SWD_USE_MALLOC) + unsigned char *b; + swd_uint *head3; + swd_uint *succ3; + swd_uint *best3; + swd_uint *llen3; +#ifdef HEAD2 + swd_uint *head2; +#endif +#else + unsigned char b [ SWD_N + SWD_F + SWD_F ]; + swd_uint head3 [ SWD_HSIZE ]; + swd_uint succ3 [ SWD_N + SWD_F ]; + swd_uint best3 [ SWD_N + SWD_F ]; + swd_uint llen3 [ SWD_HSIZE ]; +#ifdef HEAD2 + swd_uint head2 [ UCL_UINT32_C(65536) ]; +#endif +#endif +} +ucl_swd_t; + + +/* Access macro for head3. + * head3[key] may be uninitialized if the list is emtpy, + * but then its value will never be used. + */ +#if defined(__UCL_CHECKER) +# define s_head3(s,key) \ + ((s->llen3[key] == 0) ? SWD_UINT_MAX : s->head3[key]) +#else +# define s_head3(s,key) s->head3[key] +#endif + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_initdict(ucl_swd_t *s, const ucl_byte *dict, ucl_uint dict_len) +{ + s->dict = s->dict_end = NULL; + s->dict_len = 0; + + if (!dict || dict_len <= 0) + return; + if (dict_len > s->n) + { + dict += dict_len - s->n; + dict_len = s->n; + } + + s->dict = dict; + s->dict_len = dict_len; + s->dict_end = dict + dict_len; + ucl_memcpy(s->b,dict,dict_len); + s->ip = dict_len; +} + + +static +void swd_insertdict(ucl_swd_t *s, ucl_uint node, ucl_uint len) +{ + ucl_uint key; + + s->node_count = s->n - len; + s->first_rp = node; + + while (len-- > 0) + { + key = HEAD3(s->b,node); + s->succ3[node] = s_head3(s,key); + s->head3[key] = SWD_UINT(node); + s->best3[node] = SWD_UINT(s->f + 1); + s->llen3[key]++; + assert(s->llen3[key] <= s->n); + +#ifdef HEAD2 + key = HEAD2(s->b,node); + s->head2[key] = SWD_UINT(node); +#endif + + node++; + } +} + + +/*********************************************************************** +// +************************************************************************/ + +static +int swd_init(ucl_swd_t *s, const ucl_byte *dict, ucl_uint dict_len) +{ + ucl_uint i = 0; + int c = 0; + + if (s->n == 0) + s->n = SWD_N; + if (s->f == 0) + s->f = SWD_F; + s->threshold = SWD_THRESHOLD; + if (s->n > SWD_N || s->f > SWD_F) + return UCL_E_INVALID_ARGUMENT; + +#if defined(SWD_USE_MALLOC) + s->b = (unsigned char *) ucl_alloc(s->n + s->f + s->f, 1); + s->head3 = (swd_uint *) ucl_alloc(SWD_HSIZE, sizeof(*s->head3)); + s->succ3 = (swd_uint *) ucl_alloc(s->n + s->f, sizeof(*s->succ3)); + s->best3 = (swd_uint *) ucl_alloc(s->n + s->f, sizeof(*s->best3)); + s->llen3 = (swd_uint *) ucl_alloc(SWD_HSIZE, sizeof(*s->llen3)); + if (!s->b || !s->head3 || !s->succ3 || !s->best3 || !s->llen3) + return UCL_E_OUT_OF_MEMORY; +#ifdef HEAD2 + s->head2 = (swd_uint *) ucl_alloc(UCL_UINT32_C(65536), sizeof(*s->head2)); + if (!s->head2) + return UCL_E_OUT_OF_MEMORY; +#endif +#endif + + /* defaults */ + s->max_chain = SWD_MAX_CHAIN; + s->nice_length = s->f; + s->use_best_off = 0; + s->lazy_insert = 0; + + s->b_size = s->n + s->f; + if (s->b_size + s->f >= SWD_UINT_MAX) + return UCL_E_ERROR; + s->b_wrap = s->b + s->b_size; + s->node_count = s->n; + + ucl_memset(s->llen3, 0, sizeof(s->llen3[0]) * SWD_HSIZE); +#ifdef HEAD2 +#if 1 + ucl_memset(s->head2, 0xff, sizeof(s->head2[0]) * UCL_UINT32_C(65536)); + assert(s->head2[0] == NIL2); +#else + for (i = 0; i < UCL_UINT32_C(65536); i++) + s->head2[i] = NIL2; +#endif +#endif + + s->ip = 0; + swd_initdict(s,dict,dict_len); + s->bp = s->ip; + s->first_rp = s->ip; + + assert(s->ip + s->f <= s->b_size); +#if 1 + s->look = (ucl_uint) (s->c->in_end - s->c->ip); + if (s->look > 0) + { + if (s->look > s->f) + s->look = s->f; + ucl_memcpy(&s->b[s->ip],s->c->ip,s->look); + s->c->ip += s->look; + s->ip += s->look; + } +#else + s->look = 0; + while (s->look < s->f) + { + if ((c = getbyte(*(s->c))) < 0) + break; + s->b[s->ip] = UCL_BYTE(c); + s->ip++; + s->look++; + } +#endif + if (s->ip == s->b_size) + s->ip = 0; + + if (s->look >= 2 && s->dict_len > 0) + swd_insertdict(s,0,s->dict_len); + + s->rp = s->first_rp; + if (s->rp >= s->node_count) + s->rp -= s->node_count; + else + s->rp += s->b_size - s->node_count; + +#if defined(__UCL_CHECKER) + /* initialize memory for the first few HEAD3 (if s->ip is not far + * enough ahead to do this job for us). The value doesn't matter. */ + if (s->look < 3) + ucl_memset(&s->b[s->bp+s->look],0,3); +#endif + + UCL_UNUSED(i); + UCL_UNUSED(c); + return UCL_E_OK; +} + + +static +void swd_exit(ucl_swd_t *s) +{ +#if defined(SWD_USE_MALLOC) + /* free in reverse order of allocations */ +#ifdef HEAD2 + ucl_free(s->head2); s->head2 = NULL; +#endif + ucl_free(s->llen3); s->llen3 = NULL; + ucl_free(s->best3); s->best3 = NULL; + ucl_free(s->succ3); s->succ3 = NULL; + ucl_free(s->head3); s->head3 = NULL; + ucl_free(s->b); s->b = NULL; +#else + UCL_UNUSED(s); +#endif +} + + +#define swd_pos2off(s,pos) \ + (s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp)) + + +/*********************************************************************** +// +************************************************************************/ + +static __inline__ +void swd_getbyte(ucl_swd_t *s) +{ + int c; + + if ((c = getbyte(*(s->c))) < 0) + { + if (s->look > 0) + --s->look; +#if defined(__UCL_CHECKER) + /* initialize memory - value doesn't matter */ + s->b[s->ip] = 0; + if (s->ip < s->f) + s->b_wrap[s->ip] = 0; +#endif + } + else + { + s->b[s->ip] = UCL_BYTE(c); + if (s->ip < s->f) + s->b_wrap[s->ip] = UCL_BYTE(c); + } + if (++s->ip == s->b_size) + s->ip = 0; + if (++s->bp == s->b_size) + s->bp = 0; + if (++s->rp == s->b_size) + s->rp = 0; +} + + +/*********************************************************************** +// remove node from lists +************************************************************************/ + +static __inline__ +void swd_remove_node(ucl_swd_t *s, ucl_uint node) +{ + if (s->node_count == 0) + { + ucl_uint key; + +#ifdef UCL_DEBUG + if (s->first_rp != UCL_UINT_MAX) + { + if (node != s->first_rp) + printf("Remove %5d: %5d %5d %5d %5d %6d %6d\n", + node, s->rp, s->ip, s->bp, s->first_rp, + s->ip - node, s->ip - s->bp); + assert(node == s->first_rp); + s->first_rp = UCL_UINT_MAX; + } +#endif + + key = HEAD3(s->b,node); + assert(s->llen3[key] > 0); + --s->llen3[key]; + +#ifdef HEAD2 + key = HEAD2(s->b,node); + assert(s->head2[key] != NIL2); + if ((ucl_uint) s->head2[key] == node) + s->head2[key] = NIL2; +#endif + } + else + --s->node_count; +} + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_accept(ucl_swd_t *s, ucl_uint n) +{ + assert(n <= s->look); + + if (n > 0) do + { + ucl_uint key; + + swd_remove_node(s,s->rp); + + /* add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + s->succ3[s->bp] = s_head3(s,key); + s->head3[key] = SWD_UINT(s->bp); + s->best3[s->bp] = SWD_UINT(s->f + 1); + s->llen3[key]++; + assert(s->llen3[key] <= s->n); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = SWD_UINT(s->bp); +#endif + + swd_getbyte(s); + } while (--n > 0); +} + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_search(ucl_swd_t *s, ucl_uint node, ucl_uint cnt) +{ +#if 0 && defined(__GNUC__) && defined(__i386__) + register const unsigned char *p1 __asm__("%edi"); + register const unsigned char *p2 __asm__("%esi"); + register const unsigned char *px __asm__("%edx"); +#else + const unsigned char *p1; + const unsigned char *p2; + const unsigned char *px; +#endif + ucl_uint m_len = s->m_len; + const unsigned char * b = s->b; + const unsigned char * bp = s->b + s->bp; + const unsigned char * bx = s->b + s->bp + s->look; + unsigned char scan_end1; + + assert(s->m_len > 0); + + scan_end1 = bp[m_len - 1]; + for ( ; cnt-- > 0; node = s->succ3[node]) + { + p1 = bp; + p2 = b + node; + px = bx; + + assert(m_len < s->look); + + if ( +#if 1 + p2[m_len - 1] == scan_end1 && + p2[m_len] == p1[m_len] && +#endif + p2[0] == p1[0] && + p2[1] == p1[1]) + { + ucl_uint i; + assert(ucl_memcmp(bp,&b[node],3) == 0); + +#if 0 && defined(UCL_UNALIGNED_OK_4) + p1 += 3; p2 += 3; + while (p1 < px && * (const ucl_uint32p) p1 == * (const ucl_uint32p) p2) + p1 += 4, p2 += 4; + while (p1 < px && *p1 == *p2) + p1 += 1, p2 += 1; +#else + p1 += 2; p2 += 2; + do {} while (++p1 < px && *p1 == *++p2); +#endif + i = p1 - bp; + +#ifdef UCL_DEBUG + if (ucl_memcmp(bp,&b[node],i) != 0) + printf("%5ld %5ld %02x%02x %02x%02x\n", + (long)s->bp, (long) node, + bp[0], bp[1], b[node], b[node+1]); +#endif + assert(ucl_memcmp(bp,&b[node],i) == 0); + +#if defined(SWD_BEST_OFF) + if (i < SWD_BEST_OFF) + { + if (s->best_pos[i] == 0) + s->best_pos[i] = node + 1; + } +#endif + if (i > m_len) + { + s->m_len = m_len = i; + s->m_pos = node; + if (m_len == s->look) + return; + if (m_len >= s->nice_length) + return; + if (m_len > (ucl_uint) s->best3[node]) + return; + scan_end1 = bp[m_len - 1]; + } + } + } +} + + +/*********************************************************************** +// +************************************************************************/ + +#ifdef HEAD2 + +static +ucl_bool swd_search2(ucl_swd_t *s) +{ + ucl_uint key; + + assert(s->look >= 2); + assert(s->m_len > 0); + + key = s->head2[ HEAD2(s->b,s->bp) ]; + if (key == NIL2) + return 0; +#ifdef UCL_DEBUG + if (ucl_memcmp(&s->b[s->bp],&s->b[key],2) != 0) + printf("%5ld %5ld %02x%02x %02x%02x\n", (long)s->bp, (long)key, + s->b[s->bp], s->b[s->bp+1], s->b[key], s->b[key+1]); +#endif + assert(ucl_memcmp(&s->b[s->bp],&s->b[key],2) == 0); +#if defined(SWD_BEST_OFF) + if (s->best_pos[2] == 0) + s->best_pos[2] = key + 1; +#endif + + if (s->m_len < 2) + { + s->m_len = 2; + s->m_pos = key; + } + return 1; +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ + +static +void swd_findbest(ucl_swd_t *s) +{ + ucl_uint key; + ucl_uint cnt, node; + ucl_uint len; + + assert(s->m_len > 0); + + /* get current head, add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + node = s->succ3[s->bp] = s_head3(s,key); + cnt = s->llen3[key]++; + assert(s->llen3[key] <= s->n + s->f); + if (cnt > s->max_chain && s->max_chain > 0) + cnt = s->max_chain; + s->head3[key] = SWD_UINT(s->bp); + + s->b_char = s->b[s->bp]; + len = s->m_len; + if (s->m_len >= s->look) + { + if (s->look == 0) + s->b_char = -1; + s->m_off = 0; + s->best3[s->bp] = SWD_UINT(s->f + 1); + } + else + { +#ifdef HEAD2 + if (swd_search2(s)) +#endif + if (s->look >= 3) + swd_search(s,node,cnt); + if (s->m_len > len) + s->m_off = swd_pos2off(s,s->m_pos); + s->best3[s->bp] = SWD_UINT(s->m_len); + +#if defined(SWD_BEST_OFF) + if (s->use_best_off) + { + int i; + for (i = 2; i < SWD_BEST_OFF; i++) + if (s->best_pos[i] > 0) + s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1); + else + s->best_off[i] = 0; + } +#endif + } + + swd_remove_node(s,s->rp); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = SWD_UINT(s->bp); +#endif +} + + +#undef HEAD3 +#undef HEAD2 +#undef s_head3 + + +/* +vi:ts=4:et +*/ + diff --git a/tools/ucl/src/ucl_util.c b/tools/ucl/src/ucl_util.c new file mode 100644 index 0000000000..93b7298302 --- /dev/null +++ b/tools/ucl/src/ucl_util.c @@ -0,0 +1,204 @@ +/* ucl_util.c -- utilities for the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/ucl/ + */ + + +#include "ucl_conf.h" +#include "ucl_util.h" + + +/*********************************************************************** +// +************************************************************************/ + +UCL_PUBLIC(ucl_bool) +ucl_assert(int expr) +{ + return (expr) ? 1 : 0; +} + + +/*********************************************************************** +// +************************************************************************/ + +/* If you use the UCL library in a product, you *must* keep this + * copyright string in the executable of your product. +.*/ + +const ucl_byte __ucl_copyright[] = + "\n\n\n" + "UCL real-time data compression library.\n" + "$Copyright: UCL (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n" + "\n" + "http://www.oberhumer.com\n" + "\n" + "UCL version: v" UCL_VERSION_STRING ", " UCL_VERSION_DATE "\n" + "UCL build date: " __DATE__ " " __TIME__ "\n\n" + "UCL special compilation options:\n" +#ifdef __cplusplus + " __cplusplus\n" +#endif +#if defined(__PIC__) + " __PIC__\n" +#elif defined(__pic__) + " __pic__\n" +#endif +#if (UINT_MAX < UCL_0xffffffffL) + " 16BIT\n" +#endif +#if defined(__UCL_STRICT_16BIT) + " __UCL_STRICT_16BIT\n" +#endif +#if (UINT_MAX > UCL_0xffffffffL) + " UINT_MAX=" _UCL_MEXPAND(UINT_MAX) "\n" +#endif +#if (ULONG_MAX > UCL_0xffffffffL) + " ULONG_MAX=" _UCL_MEXPAND(ULONG_MAX) "\n" +#endif +#if defined(UCL_BYTE_ORDER) + " UCL_BYTE_ORDER=" _UCL_MEXPAND(UCL_BYTE_ORDER) "\n" +#endif +#if defined(UCL_UNALIGNED_OK_2) + " UCL_UNALIGNED_OK_2\n" +#endif +#if defined(UCL_UNALIGNED_OK_4) + " UCL_UNALIGNED_OK_4\n" +#endif +#if defined(UCL_ALIGNED_OK_4) + " UCL_ALIGNED_OK_4\n" +#endif +#if defined(__UCL_IN_MINIUCL) + " __UCL_IN_MINIUCL\n" +#endif + "\n\n" +/* RCS information */ + "$Id: UCL " UCL_VERSION_STRING " built " __DATE__ " " __TIME__ +#if defined(__GNUC__) && defined(__VERSION__) + " by gcc " __VERSION__ +#elif defined(__BORLANDC__) + " by Borland C " _UCL_MEXPAND(__BORLANDC__) +#elif defined(_MSC_VER) + " by Microsoft C " _UCL_MEXPAND(_MSC_VER) +#elif defined(__PUREC__) + " by Pure C " _UCL_MEXPAND(__PUREC__) +#elif defined(__SC__) + " by Symantec C " _UCL_MEXPAND(__SC__) +#elif defined(__TURBOC__) + " by Turbo C " _UCL_MEXPAND(__TURBOC__) +#elif defined(__WATCOMC__) + " by Watcom C " _UCL_MEXPAND(__WATCOMC__) +#endif + " $\n"; + +UCL_PUBLIC(const ucl_byte *) +ucl_copyright(void) +{ + return __ucl_copyright; +} + +UCL_PUBLIC(ucl_uint32) +ucl_version(void) +{ + return UCL_VERSION; +} + +UCL_PUBLIC(const char *) +ucl_version_string(void) +{ + return UCL_VERSION_STRING; +} + +UCL_PUBLIC(const char *) +ucl_version_date(void) +{ + return UCL_VERSION_DATE; +} + +UCL_PUBLIC(const ucl_charp) +_ucl_version_string(void) +{ + return UCL_VERSION_STRING; +} + +UCL_PUBLIC(const ucl_charp) +_ucl_version_date(void) +{ + return UCL_VERSION_DATE; +} + + +/*********************************************************************** +// adler32 checksum +// adapted from free code by Mark Adler +// see http://www.cdrom.com/pub/infozip/zlib/ +************************************************************************/ + +#define UCL_BASE 65521u /* largest prime smaller than 65536 */ +#define UCL_NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define UCL_DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define UCL_DO2(buf,i) UCL_DO1(buf,i); UCL_DO1(buf,i+1); +#define UCL_DO4(buf,i) UCL_DO2(buf,i); UCL_DO2(buf,i+2); +#define UCL_DO8(buf,i) UCL_DO4(buf,i); UCL_DO4(buf,i+4); +#define UCL_DO16(buf,i) UCL_DO8(buf,i); UCL_DO8(buf,i+8); + +UCL_PUBLIC(ucl_uint32) +ucl_adler32(ucl_uint32 adler, const ucl_byte *buf, ucl_uint len) +{ + ucl_uint32 s1 = adler & 0xffff; + ucl_uint32 s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < UCL_NMAX ? (int) len : UCL_NMAX; + len -= k; + if (k >= 16) do + { + UCL_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= UCL_BASE; + s2 %= UCL_BASE; + } + return (s2 << 16) | s1; +} + + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/src/ucl_util.h b/tools/ucl/src/ucl_util.h new file mode 100644 index 0000000000..2292716e4c --- /dev/null +++ b/tools/ucl/src/ucl_util.h @@ -0,0 +1,180 @@ +/* ucl_util.h -- utilities for the UCL library + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the library and is subject + to change. + */ + + +#ifndef __UCL_UTIL_H +#define __UCL_UTIL_H + +#ifndef __UCL_CONF_H +# include "ucl_conf.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// fast memcpy that copies multiples of 8 byte chunks. +// len is the number of bytes. +// note: all parameters must be lvalues, len >= 8 +// dest and src advance, len is undefined afterwards +************************************************************************/ + +#if 1 && defined(HAVE_MEMCPY) +#if !defined(__UCL_DOS16) && !defined(__UCL_WIN16) + +#define MEMCPY8_DS(dest,src,len) \ + memcpy(dest,src,len); \ + dest += len; \ + src += len + +#endif +#endif + + +#if 0 && !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ + { do { \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + len -= 8; \ + } while (len > 0); } + +#endif + + +#if !defined(MEMCPY8_DS) + +#define MEMCPY8_DS(dest,src,len) \ + { register ucl_uint __l = (len) / 8; \ + do { \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + *dest++ = *src++; \ + } while (--__l > 0); } + +#endif + + +/*********************************************************************** +// memcpy and pseudo-memmove +// len is the number of bytes. +// note: all parameters must be lvalues, len > 0 +// dest and src advance, len is undefined afterwards +************************************************************************/ + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; \ + while (--len > 0) + +#define MEMMOVE_DS(dest,src,len) \ + do *dest++ = *src++; \ + while (--len > 0) + + +/*********************************************************************** +// fast bzero that clears multiples of 8 pointers +// n is the number of pointers. +// note: n > 0 +// s and n are undefined afterwards +************************************************************************/ + +#if (UCL_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET) + +#if 1 +#define BZERO8_PTR(s,l,n) memset((s),0,(ucl_uint)(l)*(n)) +#else +#define BZERO8_PTR(s,l,n) memset((ucl_voidp)(s),0,(ucl_uint)(l)*(n)) +#endif + +#else + +#define BZERO8_PTR(s,l,n) \ + ucl_memset((ucl_voidp)(s),0,(ucl_uint)(l)*(n)) + +#endif + + +/*********************************************************************** +// rotate (not used at the moment) +************************************************************************/ + +#if 0 +#if defined(__GNUC__) && defined(__i386__) + +unsigned char ucl_rotr8(unsigned char value, int shift); +extern __inline__ unsigned char ucl_rotr8(unsigned char value, int shift) +{ + unsigned char result; + + __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0" + : "=a"(result) : "g"(value), "c"(shift)); + return result; +} + +unsigned short ucl_rotr16(unsigned short value, int shift); +extern __inline__ unsigned short ucl_rotr16(unsigned short value, int shift) +{ + unsigned short result; + + __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0" + : "=a"(result) : "g"(value), "c"(shift)); + return result; +} + +#endif +#endif + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + +/* +vi:ts=4:et +*/ diff --git a/tools/ucl/uclpack.c b/tools/ucl/uclpack.c new file mode 100644 index 0000000000..08b33af48d --- /dev/null +++ b/tools/ucl/uclpack.c @@ -0,0 +1,660 @@ +/* uclpack.c -- example program: a simple file packer + + This file is part of the UCL data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The UCL library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The UCL library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the UCL library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +/************************************************************************* +// NOTE: this is an example program, so do not use to backup your data +// +// This program lacks things like sophisticated file handling but is +// pretty complete regarding compression - it should provide a good +// starting point for adaption for you applications. +**************************************************************************/ + +#include +#include "lutil.h" + +static const char *progname = NULL; + +static unsigned long total_in = 0; +static unsigned long total_out = 0; +static ucl_bool opt_debug = 0; + +/* don't compute or verify checksum, always use fast decompressor */ +static ucl_bool opt_fast = 0; + +/* magic file header for compressed files */ +static const unsigned char magic[8] = + { 0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a }; + + +/************************************************************************* +// file IO +**************************************************************************/ + +ucl_uint xread(FILE *f, ucl_voidp buf, ucl_uint len, ucl_bool allow_eof) +{ + ucl_uint l; + + l = ucl_fread(f,buf,len); + if (l > len) + { + fprintf(stderr,"\nsomething's wrong with your C library !!!\n"); + exit(1); + } + if (l != len && !allow_eof) + { + fprintf(stderr,"\nread error - premature end of file\n"); + exit(1); + } + total_in += l; + return l; +} + +ucl_uint xwrite(FILE *f, const ucl_voidp buf, ucl_uint len) +{ + ucl_uint l; + + if (f != NULL) + { + l = ucl_fwrite(f,buf,len); + if (l != len) + { + fprintf(stderr,"\nwrite error [%ld %ld] (disk full ?)\n", + (long)len, (long)l); + exit(1); + } + } + total_out += len; + return len; +} + + +int xgetc(FILE *f) +{ + unsigned char c; + xread(f,(ucl_voidp) &c,1,0); + return c; +} + +void xputc(FILE *f, int c) +{ + unsigned char cc = (unsigned char) c; + xwrite(f,(const ucl_voidp) &cc,1); +} + +/* read and write portable 32-bit integers */ + +ucl_uint32 xread32(FILE *f) +{ + unsigned char b[4]; + ucl_uint32 v; + + xread(f,b,4,0); + v = (ucl_uint32) b[3] << 0; + v |= (ucl_uint32) b[2] << 8; + v |= (ucl_uint32) b[1] << 16; + v |= (ucl_uint32) b[0] << 24; + return v; +} + +void xwrite32(FILE *f, ucl_uint32 v) +{ + unsigned char b[4]; + + b[3] = (unsigned char) (v >> 0); + b[2] = (unsigned char) (v >> 8); + b[1] = (unsigned char) (v >> 16); + b[0] = (unsigned char) (v >> 24); + xwrite(f,b,4); +} + + +/************************************************************************* +// util +**************************************************************************/ + +static ucl_uint get_overhead(int method, ucl_uint size) +{ + if (method == 0x2b || method == 0x2d || method == 0x2e) + return size / 8 + 256; + return 0; +} + + +static char method_name[64]; + +static ucl_bool set_method_name(int method, int level) +{ + method_name[0] = 0; + if (level < 1 || level > 10) + return 0; + if (method == 0x2b) + sprintf(method_name,"NRV2B-99/%d", level); + else if (method == 0x2d) + sprintf(method_name,"NRV2D-99/%d", level); + else if (method == 0x2e) + sprintf(method_name,"NRV2E-99/%d", level); + else + return 0; + return 1; +} + + +/************************************************************************* +// compress +**************************************************************************/ + +int do_compress(FILE *fi, FILE *fo, int method, int level, ucl_uint block_size) +{ + int r = 0; + ucl_byte *in = NULL; + ucl_byte *out = NULL; + ucl_uint in_len; + ucl_uint out_len; + ucl_uint32 flags = opt_fast ? 0 : 1; + ucl_uint32 checksum; + ucl_uint overhead = 0; + + total_in = total_out = 0; + +/* + * Step 1: write magic header, flags & block size, init checksum + */ + xwrite(fo,magic,sizeof(magic)); + xwrite32(fo,flags); + xputc(fo,method); /* compression method */ + xputc(fo,level); /* compression level */ + xwrite32(fo,block_size); + checksum = ucl_adler32(0,NULL,0); + +/* + * Step 2: allocate compression buffers and work-memory + */ + overhead = get_overhead(method,block_size); + in = (ucl_byte *) ucl_malloc(block_size); + out = (ucl_byte *) ucl_malloc(block_size + overhead); + if (in == NULL || out == NULL) + { + printf("%s: out of memory\n", progname); + r = 1; + goto err; + } + +/* + * Step 3: process blocks + */ + for (;;) + { + /* read block */ + in_len = xread(fi,in,block_size,1); + if (in_len <= 0) + break; + + /* update checksum */ + if (flags & 1) + checksum = ucl_adler32(checksum,in,in_len); + + /* compress block */ + r = UCL_E_ERROR; + if (method == 0x2b) + r = ucl_nrv2b_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL); + else if (method == 0x2d) + r = ucl_nrv2d_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL); + else if (method == 0x2e) + r = ucl_nrv2e_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL); + if (r != UCL_E_OK || out_len > in_len + get_overhead(method,in_len)) + { + /* this should NEVER happen */ + printf("internal error - compression failed: %d\n", r); + r = 2; + goto err; + } + + /* write uncompressed block size */ + xwrite32(fo,in_len); + + if (out_len < in_len) + { + /* write compressed block */ + xwrite32(fo,out_len); + xwrite(fo,out,out_len); + } + else + { + /* not compressible - write uncompressed block */ + xwrite32(fo,in_len); + xwrite(fo,in,in_len); + } + } + + /* write EOF marker */ + xwrite32(fo,0); + + /* write checksum */ + if (flags & 1) + xwrite32(fo,checksum); + + r = 0; +err: + ucl_free(out); + ucl_free(in); + return r; +} + + +/************************************************************************* +// decompress / test +// +// We are using overlapping (in-place) decompression to save some +// memory - see overlap.c. +**************************************************************************/ + +int do_decompress(FILE *fi, FILE *fo) +{ + int r = 0; + ucl_byte *buf = NULL; + ucl_uint buf_len; + unsigned char m [ sizeof(magic) ]; + ucl_uint32 flags; + int method; + int level; + ucl_uint block_size; + ucl_uint32 checksum; + ucl_uint overhead = 0; + + total_in = total_out = 0; + +/* + * Step 1: check magic header, read flags & block size, init checksum + */ + if (xread(fi,m,sizeof(magic),1) != sizeof(magic) || + memcmp(m,magic,sizeof(magic)) != 0) + { + printf("%s: header error - this file is not compressed by uclpack\n", progname); + r = 1; + goto err; + } + flags = xread32(fi); + method = xgetc(fi); + level = xgetc(fi); + block_size = xread32(fi); + overhead = get_overhead(method,block_size); + if (overhead == 0 || !set_method_name(method, level)) + { + printf("%s: header error - invalid method %d (level %d)\n", + progname, method, level); + r = 2; + goto err; + } + if (block_size < 1024 || block_size > 8*1024*1024L) + { + printf("%s: header error - invalid block size %ld\n", + progname, (long) block_size); + r = 3; + goto err; + } + checksum = ucl_adler32(0,NULL,0); + +/* + * Step 2: allocate buffer for in-place decompression + */ + buf_len = block_size + overhead; + buf = (ucl_byte *) ucl_malloc(buf_len); + if (buf == NULL) + { + printf("%s: out of memory\n", progname); + r = 4; + goto err; + } + +/* + * Step 3: process blocks + */ + for (;;) + { + ucl_byte *in; + ucl_byte *out; + ucl_uint in_len; + ucl_uint out_len; + + /* read uncompressed size */ + out_len = xread32(fi); + + /* exit if last block (EOF marker) */ + if (out_len == 0) + break; + + /* read compressed size */ + in_len = xread32(fi); + + /* sanity check of the size values */ + if (in_len > block_size || out_len > block_size || + in_len == 0 || in_len > out_len) + { + printf("%s: block size error - data corrupted\n", progname); + r = 5; + goto err; + } + + /* place compressed block at the top of the buffer */ + in = buf + buf_len - in_len; + out = buf; + + /* read compressed block data */ + xread(fi,in,in_len,0); + + if (in_len < out_len) + { + /* decompress - use safe decompressor as data might be corrupted */ + ucl_uint new_len = out_len; + + if (method == 0x2b) + { + if (opt_fast) + r = ucl_nrv2b_decompress_8(in,in_len,out,&new_len,NULL); + else + r = ucl_nrv2b_decompress_safe_8(in,in_len,out,&new_len,NULL); + } + else if (method == 0x2d) + { + if (opt_fast) + r = ucl_nrv2d_decompress_8(in,in_len,out,&new_len,NULL); + else + r = ucl_nrv2d_decompress_safe_8(in,in_len,out,&new_len,NULL); + } + else if (method == 0x2e) + { + if (opt_fast) + r = ucl_nrv2e_decompress_8(in,in_len,out,&new_len,NULL); + else + r = ucl_nrv2e_decompress_safe_8(in,in_len,out,&new_len,NULL); + } + if (r != UCL_E_OK || new_len != out_len) + { + printf("%s: compressed data violation: error %d (0x%x: %ld/%ld/%ld)\n", progname, r, method, (long) in_len, (long) out_len, (long) new_len); + r = 6; + goto err; + } + /* write decompressed block */ + xwrite(fo,out,out_len); + /* update checksum */ + if ((flags & 1) && !opt_fast) + checksum = ucl_adler32(checksum,out,out_len); + } + else + { + /* write original (incompressible) block */ + xwrite(fo,in,in_len); + /* update checksum */ + if ((flags & 1) && !opt_fast) + checksum = ucl_adler32(checksum,in,in_len); + } + } + + /* read and verify checksum */ + if (flags & 1) + { + ucl_uint32 c = xread32(fi); + if (!opt_fast && c != checksum) + { + printf("%s: checksum error - data corrupted\n", progname); + r = 7; + goto err; + } + } + + r = 0; +err: + ucl_free(buf); + return r; +} + + +/************************************************************************* +// +**************************************************************************/ + +static void usage(void) +{ + printf("usage: %s [-123456789] input-file output-file (compress)\n", progname); + printf("usage: %s -d input-file output-file (decompress)\n", progname); + printf("usage: %s -t input-file... (test)\n", progname); + exit(1); +} + + +/* open input file */ +static FILE *xopen_fi(const char *name) +{ + FILE *f; + + f = fopen(name,"rb"); + if (f == NULL) + { + printf("%s: cannot open input file %s\n", progname, name); + exit(1); + } +#if defined(HAVE_STAT) && defined(S_ISREG) + { + struct stat st; +#if defined(HAVE_LSTAT) + if (lstat(name,&st) != 0 || !S_ISREG(st.st_mode)) +#else + if (stat(name,&st) != 0 || !S_ISREG(st.st_mode)) +#endif + { + printf("%s: %s is not a regular file\n", progname, name); + fclose(f); + exit(1); + } + } +#endif + return f; +} + + +/* open output file */ +static FILE *xopen_fo(const char *name) +{ + FILE *f; + +#if 0 + /* this is an example program, so make sure we don't overwrite a file */ + f = fopen(name,"rb"); + if (f != NULL) + { + printf("%s: file %s already exists -- not overwritten\n", progname, name); + fclose(f); + exit(1); + } +#endif + f = fopen(name,"wb"); + if (f == NULL) + { + printf("%s: cannot open output file %s\n", progname, name); + exit(1); + } + return f; +} + + +/************************************************************************* +// +**************************************************************************/ + +int main(int argc, char *argv[]) +{ + int i = 1; + int r = 0; + FILE *fi = NULL; + FILE *fo = NULL; + const char *in_name = NULL; + const char *out_name = NULL; + ucl_bool opt_decompress = 0; + ucl_bool opt_test = 0; + int opt_method = 0x2b; + int opt_level = 7; +#if defined(MAINT) + ucl_uint opt_block_size = (2*1024*1024L); +#else + ucl_uint opt_block_size = (256*1024L); +#endif + const char *s; + +#if defined(__EMX__) + _response(&argc,&argv); + _wildcard(&argc,&argv); +#endif + progname = argv[0]; + for (s = progname; *s; s++) + if (*s == '/' || *s == '\\') + progname = s + 1; + + printf("\nUCL real-time data compression library (v%s, %s).\n", + ucl_version_string(), ucl_version_date()); + printf("Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer\n\n"); + + printf( +"*** WARNING ***\n" +" This is an example program, do not use to backup your data !\n" +"\n"); + +/* + * Step 1: initialize the UCL library + */ + if (ucl_init() != UCL_E_OK) + { + printf("ucl_init() failed !!!\n"); + exit(1); + } + +/* + * Step 2: get options + */ + + while (i < argc && argv[i][0] == '-') + { + if (strcmp(argv[i],"-d") == 0) + opt_decompress = 1; + else if (strcmp(argv[i],"-t") == 0) + opt_test = 1; + else if (strcmp(argv[i],"-F") == 0) + opt_fast = 1; + else if (strcmp(argv[i],"--2b") == 0) + opt_method = 0x2b; + else if (strcmp(argv[i],"--nrv2b") == 0) + opt_method = 0x2b; + else if (strcmp(argv[i],"--2d") == 0) + opt_method = 0x2d; + else if (strcmp(argv[i],"--nrv2d") == 0) + opt_method = 0x2d; + else if (strcmp(argv[i],"--2e") == 0) + opt_method = 0x2e; + else if (strcmp(argv[i],"--nrv2e") == 0) + opt_method = 0x2e; + else if ((argv[i][1] >= '1' && argv[i][1] <= '9') && !argv[i][2]) + opt_level = argv[i][1] - '0'; + else if (strcmp(argv[i],"--10") == 0) + opt_level = 10; + else if (strcmp(argv[i],"--best") == 0) + opt_level = 10; + else if (argv[i][1] == 'b' && argv[i][2]) + { +#if (UCL_UINT_MAX > UINT_MAX) && defined(HAVE_ATOL) + ucl_int b = (ucl_int) atol(&argv[i][2]); +#else + ucl_int b = (ucl_int) atoi(&argv[i][2]); +#endif + if (b >= 1024L && b <= 8*1024*1024L) + opt_block_size = b; + } + else if (strcmp(argv[i],"--debug") == 0) + opt_debug = 1; + else + usage(); + i++; + } + if (opt_test && i >= argc) + usage(); + if (!opt_test && i + 2 != argc) + usage(); + +/* + * Step 3: process file(s) + */ + if (opt_test) + { + while (i < argc && r == 0) + { + in_name = argv[i++]; + fi = xopen_fi(in_name); + r = do_decompress(fi,NULL); + if (r == 0) + printf("%s: tested ok: %-10s %-11s: %6ld -> %6ld bytes\n", + progname, in_name, method_name, total_in, total_out); + fclose(fi); + fi = NULL; + } + } + else if (opt_decompress) + { + in_name = argv[i++]; + out_name = argv[i++]; + fi = xopen_fi(in_name); + fo = xopen_fo(out_name); + r = do_decompress(fi,fo); + if (r == 0) + printf("%s: decompressed %ld into %ld bytes\n", + progname, total_in, total_out); + } + else /* compress */ + { + if (!set_method_name(opt_method, opt_level)) + { + printf("%s: internal error - invalid method %d (level %d)\n", + progname, opt_method, opt_level); + goto quit; + } + in_name = argv[i++]; + out_name = argv[i++]; + fi = xopen_fi(in_name); + fo = xopen_fo(out_name); + r = do_compress(fi,fo,opt_method,opt_level,opt_block_size); + if (r == 0) + printf("%s: algorithm %s, compressed %ld into %ld bytes\n", + progname, method_name, total_in, total_out); + } + +quit: + if (fi) fclose(fi); + if (fo) fclose(fo); + return r; +} + +/* +vi:ts=4:et +*/ + -- cgit v1.2.3