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
This commit is contained in:
Jens Arnold 2005-11-27 23:41:55 +00:00
parent f04577377d
commit 7c21a96e9a
33 changed files with 6325 additions and 0 deletions

235
tools/ucl/include/ucl/ucl.h Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#ifndef __UCL_H
#define __UCL_H
#ifndef __UCLCONF_H
#include <ucl/uclconf.h>
#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 */

View file

@ -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
<markus@oberhumer.com>
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 <config.h>
#endif
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
// UCL requires a conforming <limits.h>
************************************************************************/
#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 <ucl/ucl16bit.h>
# 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 */

View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#ifndef __UCLUTIL_H
#define __UCLUTIL_H
#ifndef __UCLCONF_H
#include <ucl/uclconf.h>
#endif
#include <stdio.h>
#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 */

151
tools/ucl/src/alloc.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#include "ucl_conf.h"
#if defined(HAVE_MALLOC_H)
# include <malloc.h>
#endif
#if defined(__palmos__)
# include <System/MemoryMgr.h>
#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
*/

81
tools/ucl/src/fake16.h Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/*
* 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 <ucl/ucl16bit.h>
*
* Usage: #include "src/fake16.h" at the top of <ucl/uclconf.h>
*/
#ifndef __UCLFAKE16BIT_H
#define __UCLFAKE16BIT_H
#ifdef __UCLCONF_H
# error "include this file before uclconf.h"
#endif
#include <limits.h>
#if (USHRT_MAX == 0xffff)
#ifdef __cplusplus
extern "C" {
#endif
#define __UCL16BIT_H /* do not use <ucl/ucl16bit.h> */
#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 */

64
tools/ucl/src/getbit.h Normal file
View file

@ -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
<markus@oberhumer.com>
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
*/

48
tools/ucl/src/internal.h Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/* 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
*/

105
tools/ucl/src/io.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#include "ucl_conf.h"
#if !defined(NO_STDIO_H)
#include <stdio.h>
#include <ucl/uclutil.h>
#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
*/

643
tools/ucl/src/n2_99.ch Executable file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#include <ucl/uclconf.h>
#include <ucl/ucl.h>
#include "ucl_conf.h"
#if 0
#undef UCL_DEBUG
#define UCL_DEBUG
#endif
#include <stdio.h>
#if 0 && !defined(UCL_DEBUG)
#undef NDEBUG
#include <assert.h>
#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
*/

38
tools/ucl/src/n2b_99.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#define NRV2B
#include "n2_99.ch"
#undef NRV2B
/*
vi:ts=4:et
*/

178
tools/ucl/src/n2b_d.c Normal file
View file

@ -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
<markus@oberhumer.com>
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 <ucl/ucl.h>
#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
*/

40
tools/ucl/src/n2b_ds.c Normal file
View file

@ -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
<markus@oberhumer.com>
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
*/

79
tools/ucl/src/n2b_to.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
/***********************************************************************
// entries for the different bit-buffer sizes
************************************************************************/
#include <ucl/ucl.h>
#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
*/

38
tools/ucl/src/n2d_99.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#define NRV2D
#include "n2_99.ch"
#undef NRV2D
/*
vi:ts=4:et
*/

183
tools/ucl/src/n2d_d.c Normal file
View file

@ -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
<markus@oberhumer.com>
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 <ucl/ucl.h>
#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
*/

40
tools/ucl/src/n2d_ds.c Normal file
View file

@ -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
<markus@oberhumer.com>
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
*/

79
tools/ucl/src/n2d_to.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
/***********************************************************************
// entries for the different bit-buffer sizes
************************************************************************/
#include <ucl/ucl.h>
#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
*/

38
tools/ucl/src/n2e_99.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#define NRV2E
#include "n2_99.ch"
#undef NRV2E
/*
vi:ts=4:et
*/

186
tools/ucl/src/n2e_d.c Normal file
View file

@ -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
<markus@oberhumer.com>
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 <ucl/ucl.h>
#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
*/

40
tools/ucl/src/n2e_ds.c Normal file
View file

@ -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
<markus@oberhumer.com>
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
*/

79
tools/ucl/src/n2e_to.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
/***********************************************************************
// entries for the different bit-buffer sizes
************************************************************************/
#include <ucl/ucl.h>
#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
*/

359
tools/ucl/src/ucl_conf.h Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/* 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 <ucl/uclconf.h>
# endif
#endif
/***********************************************************************
// memory checkers
************************************************************************/
#if defined(__BOUNDS_CHECKING_ON)
# include <unchecked.h>
#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 <stddef.h> /* ptrdiff_t, size_t */
# include <string.h> /* memcpy, memmove, memcmp, memset */
# if !defined(NO_STDLIB_H)
# include <stdlib.h>
# endif
# define HAVE_MEMCMP
# define HAVE_MEMCPY
# define HAVE_MEMMOVE
# define HAVE_MEMSET
#else
# include <sys/types.h>
# if defined(STDC_HEADERS)
# include <string.h>
# include <stdlib.h>
# endif
# if defined(HAVE_STDDEF_H)
# include <stddef.h>
# endif
# if defined(HAVE_MEMORY_H)
# include <memory.h>
# 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 <stdio.h>
# endif
#endif
#include <assert.h>
#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
/***********************************************************************
// <string.h> 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
*/

135
tools/ucl/src/ucl_crc.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#include "ucl_conf.h"
#include "ucl_util.h"
/***********************************************************************
// crc32 checksum
// adapted from free code by Mark Adler <madler@alumni.caltech.edu>
// 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
*/

61
tools/ucl/src/ucl_dll.c Normal file
View file

@ -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
<markus@oberhumer.com>
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 <windows.h> - we don't need it */
#if 0
#include <windows.h>
#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
*/

500
tools/ucl/src/ucl_init.c Normal file
View file

@ -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
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/ucl/
*/
#include "ucl_conf.h"
#include "ucl_util.h"
#include <stdio.h>
#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
*/

313
tools/ucl/src/ucl_mchw.ch Executable file
View file

@ -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
<markus@oberhumer.com>
*/
/***********************************************************************
//
************************************************************************/
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
*/

81
tools/ucl/src/ucl_ptr.c Normal file
View file

@ -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
<markus@oberhumer.com>
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
*/

211
tools/ucl/src/ucl_ptr.h Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/* 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 <dos.h>
# if 1 && defined(__WATCOMC__)
# include <i86.h>
__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
*/

133
tools/ucl/src/ucl_str.c Normal file
View file

@ -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
<markus@oberhumer.com>
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 <string.h> 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
*/

665
tools/ucl/src/ucl_swd.ch Executable file
View file

@ -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
<markus@oberhumer.com>
*/
#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
*/

204
tools/ucl/src/ucl_util.c Normal file
View file

@ -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
<markus@oberhumer.com>
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"
"<markus@oberhumer.com>\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 <madler@alumni.caltech.edu>
// 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
*/

180
tools/ucl/src/ucl_util.h Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/* 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
*/

660
tools/ucl/uclpack.c Normal file
View file

@ -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
<markus@oberhumer.com>
*/
/*************************************************************************
// 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 <ucl/ucl.h>
#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
*/