@@ -1,4 +1,4 @@
-' Copyright (c) 2022 Bruce A Henderson
+' Copyright (c) 2022-2023 Bruce A Henderson
' All rights reserved.
'
' Redistribution and use in source and binary forms, with or without
@@ -22,7 +22,7 @@
SuperStrict
-Import Pub.zlib
+Import Archive.zlib
Import "../../pub.mod/zlib.mod/*.h"
@@ -22,10 +22,9 @@
Import Archive.BZip2
Import Archive.Xz
Import "../bzip2.mod/bzip2/*.h"
-' Copyright (c) 2023 Bruce A Henderson
@@ -0,0 +1,86 @@
+SuperStrict
+
+Rem
+bbdoc: Miscellaneous/ZLib compression
+End Rem
+Module Archive.ZLib
+ModuleInfo "Version: 1.08"
+ModuleInfo "Author: Jean-loup Gailly, Mark Adler"
+ModuleInfo "License: zlib/libpng"
+ModuleInfo "Modserver: BRL"
+ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly"
+ModuleInfo "History: 1.08"
+ModuleInfo "History: Moved to archive.zlib"
+ModuleInfo "History: Updated zlib to 1.2.13"
+ModuleInfo "History: 1.07"
+ModuleInfo "History: Updated zlib to 1.2.12.1.5752b17"
+ModuleInfo "History: 1.06"
+ModuleInfo "History: Updated zlib to 1.2.12"
+ModuleInfo "History: 1.05"
+ModuleInfo "History: Updated zlib to 1.2.11"
+ModuleInfo "History: 1.04"
+ModuleInfo "History: Updated zlib to 1.2.10"
+ModuleInfo "History: 1.03"
+ModuleInfo "History: Updated zlib to 1.2.8"
+ModuleInfo "History: 1.02"
+ModuleInfo "History: Updated zlib to 1.2.3"
+?macos
+ModuleInfo "CC_OPTS: -DHAVE_UNISTD_H"
+?
+Import "zlib/*.h"
+Import "zlib/adler32.c"
+Import "zlib/compress.c"
+Import "zlib/crc32.c"
+Import "zlib/deflate.c"
+Import "zlib/gzclose.c"
+Import "zlib/gzlib.c"
+Import "zlib/gzread.c"
+Import "zlib/gzwrite.c"
+Import "zlib/infback.c"
+Import "zlib/inffast.c"
+Import "zlib/inflate.c"
+Import "zlib/inftrees.c"
+Import "zlib/trees.c"
+Import "zlib/uncompr.c"
+Import "zlib/zutil.c"
+'
+' Build notes:
+' gzguts.h
+' Added unistd.h include for emscripten target
+Extern
+bbdoc: Compress a block of data at default compression level
+?win32 Or ptr32
+Function compress:Int( dest:Byte Ptr,dest_len:UInt Var,source:Byte Ptr,source_len:UInt )="int compress(void *, unsigned long *, const void *, unsigned long)"
+?ptr64 And Not win32
+Function compress:Int( dest:Byte Ptr,dest_len:ULong Var,source:Byte Ptr,source_len:ULong )="int compress(void *, unsigned long *, const void *, unsigned long)"
+bbdoc: Compress a block of data at specified compression level
+end rem
+Function compress2:Int( dest:Byte Ptr,dest_len:UInt Var,source:Byte Ptr,source_len:UInt,level:Int )="int compress2(void *, unsigned long *, const void *, unsigned long , int)"
+Function compress2:Int( dest:Byte Ptr,dest_len:ULong Var,source:Byte Ptr,source_len:ULong,level:Int )="int compress2(void *, unsigned long *, const void *, unsigned long , int)"
+bbdoc: Uncompress a block of data
+Function uncompress:Int( dest:Byte Ptr,dest_len:UInt Var,source:Byte Ptr,source_len:UInt )="int uncompress(void *, unsigned long *, const void *, unsigned long)"
+Function uncompress:Int( dest:Byte Ptr,dest_len:ULong Var,source:Byte Ptr,source_len:ULong )="int uncompress(void *, unsigned long *, const void *, unsigned long)"
+End Extern
@@ -0,0 +1,213 @@
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+project(zlib C)
+set(VERSION "1.2.13")
+set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
+set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
+set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
+set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+enable_testing()
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h HAVE_STDINT_H)
+check_include_file(stddef.h HAVE_STDDEF_H)
+#
+# Check to see if we have large file support
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+if(HAVE_STDDEF_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+ add_definitions(-D_LARGEFILE64_SOURCE=1)
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+# Check for fseeko
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+ add_definitions(-DNO_FSEEKO)
+# Check for unistd.h
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
+if(MSVC)
+ set(CMAKE_DEBUG_POSTFIX "d")
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+ add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
+ # If we're doing an out of source build and the user has a zconf.h
+ # in their source tree...
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
+ message(STATUS "Renaming")
+ message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
+ message(STATUS "to 'zconf.h.included' because this file is included with zlib")
+ message(STATUS "but CMake generates it automatically in the build directory.")
+ file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
+ endif()
+set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
+ ${ZLIB_PC} @ONLY)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
+#============================================================================
+# zlib
+set(ZLIB_PUBLIC_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+ zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+ crc32.h
+ deflate.h
+ gzguts.h
+ inffast.h
+ inffixed.h
+ inflate.h
+ inftrees.h
+ trees.h
+ zutil.h
+set(ZLIB_SRCS
+ adler32.c
+ compress.c
+ crc32.c
+ deflate.c
+ gzclose.c
+ gzlib.c
+ gzread.c
+ gzwrite.c
+ inflate.c
+ infback.c
+ inftrees.c
+ inffast.c
+ trees.c
+ uncompr.c
+ zutil.c
+if(NOT MINGW)
+ set(ZLIB_DLL_SRCS
+ win32/zlib1.rc # If present will override custom build rule below.
+ )
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
+ "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+if(MINGW)
+ # This gets us DLL resource information when compiling on MinGW.
+ if(NOT CMAKE_RC_COMPILER)
+ set(CMAKE_RC_COMPILER windres.exe)
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+ COMMAND ${CMAKE_RC_COMPILER}
+ -D GCC_WINDRES
+ -I ${CMAKE_CURRENT_SOURCE_DIR}
+ -I ${CMAKE_CURRENT_BINARY_DIR}
+ -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+ -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
+ set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+endif(MINGW)
+add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
+set_target_properties(zlib PROPERTIES SOVERSION 1)
+if(NOT CYGWIN)
+ # This property causes shared libraries on Linux to have the full version
+ # encoded into their final filename. We disable this on Cygwin because
+ # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+ # seems to be the default.
+ #
+ # This has no effect with MSVC, on that platform the version info for
+ # the DLL comes from the resource file win32/zlib1.rc
+ set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+if(UNIX)
+ # On unix-like platforms the library is almost always called libz
+ set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
+ if(NOT APPLE)
+ set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+elseif(BUILD_SHARED_LIBS AND WIN32)
+ # Creates zlib1.dll when building shared library version
+ set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+ install(TARGETS zlib zlibstatic
+ RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
+ ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
+ LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+ install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
+ install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
+# Example binaries
+add_executable(example test/example.c)
+target_link_libraries(example zlib)
+add_test(example example)
+add_executable(minigzip test/minigzip.c)
+target_link_libraries(minigzip zlib)
+ add_executable(example64 test/example.c)
+ target_link_libraries(example64 zlib)
+ set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+ add_test(example64 example64)
+ add_executable(minigzip64 test/minigzip.c)
+ target_link_libraries(minigzip64 zlib)
+ set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
@@ -0,0 +1,1590 @@
+ ChangeLog file for zlib
+Changes in 1.2.13 (13 Oct 2022)
+- Fix configure issue that discarded provided CC definition
+- Correct incorrect inputs provided to the CRC functions
+- Repair prototypes and exporting of new CRC functions
+- Fix inflateBack to detect invalid input with distances too far
+- Have infback() deliver all of the available output up to any error
+- Fix a bug when getting a gzip header extra field with inflate()
+- Fix bug in block type selection when Z_FIXED used
+- Tighten deflateBound bounds
+- Remove deleted assembler code references
+- Various portability and appearance improvements
+Changes in 1.2.12 (27 Mar 2022)
+- Cygwin does not have _wopen(), so do not create gzopen_w() there
+- Permit a deflateParams() parameter change as soon as possible
+- Limit hash table inserts after switch from stored deflate
+- Fix bug when window full in deflate_stored()
+- Fix CLEAR_HASH macro to be usable as a single statement
+- Avoid a conversion error in gzseek when off_t type too small
+- Have Makefile return non-zero error code on test failure
+- Avoid some conversion warnings in gzread.c and gzwrite.c
+- Update use of errno for newer Windows CE versions
+- Small speedup to inflate [psumbera]
+- Return an error if the gzputs string length can't fit in an int
+- Add address checking in clang to -w option of configure
+- Don't compute check value for raw inflate if asked to validate
+- Handle case where inflateSync used when header never processed
+- Avoid the use of ptrdiff_t
+- Avoid an undefined behavior of memcpy() in gzappend()
+- Avoid undefined behaviors of memcpy() in gz*printf()
+- Avoid an undefined behavior of memcpy() in _tr_stored_block()
+- Make the names in functions declarations identical to definitions
+- Remove old assembler code in which bugs have manifested
+- Fix deflateEnd() to not report an error at start of raw deflate
+- Add legal disclaimer to README
+- Emphasize the need to continue decompressing gzip members
+- Correct the initialization requirements for deflateInit2()
+- Fix a bug that can crash deflate on some input when using Z_FIXED
+- Assure that the number of bits for deflatePrime() is valid
+- Use a structure to make globals in enough.c evident
+- Use a macro for the printf format of big_t in enough.c
+- Clean up code style in enough.c, update version
+- Use inline function instead of macro for index in enough.c
+- Clarify that prefix codes are counted in enough.c
+- Show all the codes for the maximum tables size in enough.c
+- Add gznorm.c example, which normalizes gzip files
+- Fix the zran.c example to work on a multiple-member gzip file
+- Add tables for crc32_combine(), to speed it up by a factor of 200
+- Add crc32_combine_gen() and crc32_combine_op() for fast combines
+- Speed up software CRC-32 computation by a factor of 1.5 to 3
+- Use atomic test and set, if available, for dynamic CRC tables
+- Don't bother computing check value after successful inflateSync()
+- Correct comment in crc32.c
+- Add use of the ARMv8 crc32 instructions when requested
+- Use ARM crc32 instructions if the ARM architecture has them
+- Explicitly note that the 32-bit check values are 32 bits
+- Avoid adding empty gzip member after gzflush with Z_FINISH
+- Fix memory leak on error in gzlog.c
+- Fix error in comment on the polynomial representation of a byte
+- Clarify gz* function interfaces, referring to parameter names
+- Change macro name in inflate.c to avoid collision in VxWorks
+- Correct typo in blast.c
+- Improve portability of contrib/minizip
+- Fix indentation in minizip's zip.c
+- Replace black/white with allow/block. (theresa-m)
+- minizip warning fix if MAXU32 already defined. (gvollant)
+- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner)
+- Clean up minizip to reduce warnings for testing
+- Add fallthrough comments for gcc
+- Eliminate use of ULL constants
+- Separate out address sanitizing from warnings in configure
+- Remove destructive aspects of make distclean
+- Check for cc masquerading as gcc or clang in configure
+- Fix crc32.c to compile local functions only if used
+Changes in 1.2.11 (15 Jan 2017)
+- Fix deflate stored bug when pulling last block from window
+- Permit immediate deflateParams changes before any deflate input
+Changes in 1.2.10 (2 Jan 2017)
+- Avoid warnings on snprintf() return value
+- Fix bug in deflate_stored() for zero-length input
+- Fix bug in gzwrite.c that produced corrupt gzip files
+- Remove files to be installed before copying them in Makefile.in
+- Add warnings when compiling with assembler code
+Changes in 1.2.9 (31 Dec 2016)
+- Fix contrib/minizip to permit unzipping with desktop API [Zouzou]
+- Improve contrib/blast to return unused bytes
+- Assure that gzoffset() is correct when appending
+- Improve compress() and uncompress() to support large lengths
+- Fix bug in test/example.c where error code not saved
+- Remedy Coverity warning [Randers-Pehrson]
+- Improve speed of gzprintf() in transparent mode
+- Fix inflateInit2() bug when windowBits is 16 or 32
+- Change DEBUG macro to ZLIB_DEBUG
+- Avoid uninitialized access by gzclose_w()
+- Allow building zlib outside of the source directory
+- Fix bug that accepted invalid zlib header when windowBits is zero
+- Fix gzseek() problem on MinGW due to buggy _lseeki64 there
+- Loop on write() calls in gzwrite.c in case of non-blocking I/O
+- Add --warn (-w) option to ./configure for more compiler warnings
+- Reject a window size of 256 bytes if not using the zlib wrapper
+- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE
+- Add --debug (-d) option to ./configure to define ZLIB_DEBUG
+- Fix bugs in creating a very large gzip header
+- Add uncompress2() function, which returns the input size used
+- Assure that deflateParams() will not switch functions mid-block
+- Dramatically speed up deflation for level 0 (storing)
+- Add gzfread(), duplicating the interface of fread()
+- Add gzfwrite(), duplicating the interface of fwrite()
+- Add deflateGetDictionary() function
+- Use snprintf() for later versions of Microsoft C
+- Fix *Init macros to use z_ prefix when requested
+- Replace as400 with os400 for OS/400 support [Monnerat]
+- Add crc32_z() and adler32_z() functions with size_t lengths
+- Update Visual Studio project files [AraHaan]
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Roß]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix uninitialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Support i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no library use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminacy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assembler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to root
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+ Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+ _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+ binary compatibility -- a normal version and a 64-bit offset version,
+ per the Large File Support Extension when _LARGEFILE64_SOURCE is
+ defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+ is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+ [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+ trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+ gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+ Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+ the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+ for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+ doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+ that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+ un-versioned, the patch adds versioning only for symbols introduced in
+ zlib-1.2.0 or later. It also declares as local those symbols which are
+ not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+ NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+Changes in 1.2.0.4 (10 August 2003)
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enhance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5)
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles Vollant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test"
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+ Andy Buckler for finding this one)
+- In minigzip, pass transparently also the first byte for .Z files
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <[email protected]>
+ 386 asm code replacing longest_match()
+ contrib/iostream/ by Kevin Ruland <[email protected]>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <[email protected]>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <[email protected]>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <[email protected]>
+ How to use compress(), uncompress() and the gz* functions from VB
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code
+- Use default memcpy for Symantec MSDOS compiler
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch)
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generate bad compressed data
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count)
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?)
+- define enum out of inflate_blocks_state to allow compilation with C++
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions)
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h)
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model)
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks
+- untabify all sources to simplify patches
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model
+Changes in 0.7 (14 April 95)
+- Added full inflate support
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose)
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2
+- added inflateInit2
+- simplified considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression
+- added Z_HUFFMAN_ONLY
+- added gzerror()
@@ -0,0 +1,368 @@
+ Frequently Asked Questions about zlib
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+ 1. Is zlib Y2K-compliant?
+ Yes. zlib doesn't handle dates.
+ 2. Where can I get a Windows DLL version?
+ The zlib sources can be compiled without change to produce a DLL. See the
+ file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
+ precompiled DLL are found in the zlib web site at http://zlib.net/ .
+ 3. Where can I get a Visual Basic interface to zlib?
+ See
+ * http://marknelson.us/1997/01/01/zlib-engine/
+ * win32/DLL_FAQ.txt in the zlib distribution
+ 4. compress() returns Z_BUF_ERROR.
+ Make sure that before the call of compress(), the length of the compressed
+ buffer is equal to the available size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+ Before making the call, make sure that avail_in and avail_out are not zero.
+ When setting the parameter flush equal to Z_FINISH, also make sure that
+ avail_out is big enough to allow processing all pending input. Note that a
+ Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+ made with more input or output space. A Z_BUF_ERROR may in fact be
+ unavoidable depending on how the functions are used, since it is not
+ possible to tell whether or not there is more output pending when
+ strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
+ heavily annotated example.
+ 6. Where's the zlib documentation (man pages, etc.)?
+ It's in zlib.h . Examples of zlib usage are in the files test/example.c
+ and test/minigzip.c, with more in examples/ .
+ 7. Why don't you use GNU autoconf or libtool or ...?
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
+ 8. I found a bug in zlib.
+ Most of the time, such problems are due to an incorrect usage of zlib.
+ Please try to reproduce the problem with a small program and send the
+ corresponding source to us at [email protected] . Do not send multi-megabyte
+ data files without prior agreement.
+ 9. Why do I get "undefined reference to gzputc"?
+ If "make test" produces something like
+ example.o(.text+0x154): undefined reference to `gzputc'
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+10. I need a Delphi interface to zlib.
+ See the contrib/delphi directory in the zlib distribution.
+11. Can zlib handle .zip archives?
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+12. Can zlib handle .Z files?
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+13. How can I make a Unix shared library?
+ By default a shared (and a static) library is built for Unix. So:
+ make distclean
+ ./configure
+ make
+14. How do I install a shared zlib library on Unix?
+ After the above, then:
+ make install
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to
+ it. You can check the version at the top of zlib.h or with the
+ ZLIB_VERSION symbol defined in zlib.h .
+15. I have a question about OttoPDF.
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, [email protected].
+16. Can zlib decode Flate data in an Adobe PDF file?
+ Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+ http://sourceforge.net/projects/acroformtool/ .
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+18. Why does gzip give an error on a file I make with compress/deflate?
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip formats
+ use the same compressed data format internally, but have different headers
+ and trailers around the compressed data.
+19. Ok, so why are there two different formats?
+ The gzip format was designed to retain the directory information about a
+ single file, such as the name and last modification date. The zlib format
+ on the other hand was designed for in-memory and communication channel
+ applications, and has a much more compact header and trailer and uses a
+ faster integrity check than gzip.
+20. Well that's nice, but how do I make a gzip file in memory?
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode the
+ gzip format using inflateInit2(). Read zlib.h for more details.
+21. Is zlib thread-safe?
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's *Init* functions
+ allow for the application to provide custom memory allocation routines.
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+22. Can I use zlib in my commercial application?
+ Yes. Please read the license in zlib.h.
+23. Is zlib under the GNU license?
+ No. Please read the license in zlib.h.
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+ Yes and yes.
+26. Will zlib work on a 64-bit machine?
+ Yes. It has been tested on 64-bit machines, and has no dependence on any
+ data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to [email protected]
+27. Will zlib decompress data from the PKWare Data Compression Library?
+ No. The PKWare DCL uses a completely different compressed data format than
+ does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+28. Can I access data randomly in a compressed stream?
+ No, not without some preparation. If when compressing you periodically use
+ Z_FULL_FLUSH, carefully write all the pending data at those points, and
+ keep an index of those locations, then you can start decompression at those
+ points. You have to be careful to not use Z_FULL_FLUSH too often, since it
+ can significantly degrade compression. Alternatively, you can scan a
+ deflate stream once to generate an index, and then use that index for
+ random access. See examples/zran.c .
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+ It has in the past, but we have not heard of any recent evidence. There
+ were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+ If you know of recent, successful applications of zlib on these operating
+ systems, please let us know. Thanks.
+30. Is there some simpler, easier to read version of inflate I can look at to
+ understand the deflate format?
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+31. Does zlib infringe on any patents?
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+ http://www.gzip.org/#faq11
+32. Can zlib work with greater than 4 GB of data?
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+ The word "may" appears several times above since there is a 4 GB limit only
+ if the compiler's "long" type is 32 bits. If the compiler's "long" type is
+ 64 bits, then the limit is 16 exabytes.
+33. Does zlib have any security vulnerabilities?
+ The only one that we are aware of is potentially in gzprintf(). If zlib is
+ compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of an 8K string space (or other value as set by
+ gzbuffer()), other than the caller of gzprintf() assuring that the output
+ will not exceed 8K. On the other hand, if zlib is compiled to use
+ snprintf() or vsnprintf(), which should normally be the case, then there is
+ no vulnerability. The ./configure script will display warnings if an
+ insecure variation of sprintf() will be used by gzprintf(). Also the
+ zlibCompileFlags() function will return information on what variant of
+ sprintf() is used by gzprintf().
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+ http://www.ijs.si/software/snprintf/
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability, and versions
+ 1.2.1 and 1.2.2 were subject to an access exception when decompressing
+ invalid compressed data.
+34. Is there a Java version of zlib?
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://zlib.net/ .
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly as well as contradicted each other. So now, we simply
+ make sure that the code always works.
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+ No. That is intentional for performance reasons, and the output of deflate
+ is not affected. This only started showing up recently since zlib 1.2.x
+ uses malloc() by default for allocations, whereas earlier versions used
+ calloc(), which zeros out the allocated memory. Even though the code was
+ correct, versions 1.2.4 and later was changed to not stimulate these
+ checkers.
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+38. How can I encrypt/decrypt zip files with zlib?
+ zlib doesn't support encryption. The original PKZIP encryption is very
+ weak and can be broken with freely available programs. To get strong
+ encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+ compression. For PKZIP compatible "encryption", look at
+ http://www.info-zip.org/
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion with
+ the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specification in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats. In
+ any case, the compression improvements are so modest compared to other more
+ modern approaches, that it's not worth the effort to implement.
+41. I'm having a problem with the zip functions in zlib, can you help?
+ There are no zip functions in zlib. You are probably using minizip by
+ Giles Vollant, which is found in the contrib directory of zlib. It is not
+ part of zlib. In fact none of the stuff in contrib is part of zlib. The
+ files in there are not supported by the zlib authors. You need to contact
+ the authors of the respective contribution for help.
+42. The match.asm code in contrib is under the GNU General Public License.
+ Since it's part of zlib, doesn't that mean that all of zlib falls under the
+ GNU GPL?
+ No. The files in contrib are not part of zlib. They were contributed by
+ other authors and are provided as a convenience to the user within the zlib
+ distribution. Each item in contrib has its own license.
+43. Is zlib subject to export controls? What is its ECCN?
+ zlib is not subject to export controls, and so is classified as EAR99.
+44. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+ No. Go away. Shoo.
@@ -0,0 +1,68 @@
+CMakeLists.txt cmake build file
+ChangeLog history of changes
+FAQ Frequently Asked Questions about zlib
+INDEX this file
+Makefile dummy Makefile that tells you to ./configure
+Makefile.in template for Unix Makefile
+README guess what
+configure configure script for Unix
+make_vms.com makefile for VMS
+test/example.c zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
+treebuild.xml XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in zconf.h template for configure
+zlib.3 Man page for zlib
+zlib.3.pdf Man page in PDF format
+zlib.map Linux symbol information
+zlib.pc.in Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
+zlib2ansi perl script to convert source files for C++ compilation
+amiga/ makefiles for Amiga SAS C
+as400/ makefiles for AS/400
+doc/ documentation for formats and algorithms
+msdos/ makefiles for MSDOS
+nintendods/ makefile for Nintendo DS
+old/ makefiles for various architectures and zlib documentation
+ files that have not yet been updated for zlib 1.2.x
+qnx/ makefiles for QNX
+watcom/ makefiles for OpenWatcom
+win32/ makefiles for Windows
+ zlib public header files (required for library use):
+zconf.h
+zlib.h
+ private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+ source files for sample programs
+See examples/README.examples
+ unsupported contributions by third parties
+See contrib/README.contrib
@@ -0,0 +1,22 @@
+Copyright notice:
+ (C) 1995-2022 Jean-loup Gailly and Mark Adler
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ Jean-loup Gailly Mark Adler
+ [email protected] [email protected]
@@ -0,0 +1,5 @@
+all:
+ -@echo "Please use ./configure first. Thank you."
+distclean:
+ make -f Makefile.in distclean
@@ -0,0 +1,404 @@
+# Makefile for zlib
+# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler
+# For conditions of distribution and use, see copyright notice in zlib.h
+# To compile and test, type:
+# ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+# make install
+# To install in $HOME instead of /usr/local, use:
+# make install prefix=$HOME
+CC=cc
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+SFLAGS=-O
+LDFLAGS=
+TEST_LDFLAGS=$(LDFLAGS) -L. libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+STATICLIB=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.13
+SHAREDLIBM=libz.so.1
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+AR=ar
+ARFLAGS=rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+sharedlibdir = ${libdir}
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+SRCDIR=
+ZINC=
+ZINCOUT=-I.
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+OBJS = $(OBJC) $(OBJA)
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+all: static shared
+static: example$(EXE) minigzip$(EXE)
+shared: examplesh$(EXE) minigzipsh$(EXE)
+all64: example64$(EXE) minigzip64$(EXE)
+check: test
+test: all teststatic testshared
+teststatic: static
+ @TMPST=tmpst_$$; \
+ if echo hello world | ${QEMU_RUN} ./minigzip | ${QEMU_RUN} ./minigzip -d && ${QEMU_RUN} ./example $$TMPST ; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; false; \
+ fi
+ @rm -f tmpst_$$
+testshared: shared
+ @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+ DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+ SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+ TMPSH=tmpsh_$$; \
+ if echo hello world | ${QEMU_RUN} ./minigzipsh | ${QEMU_RUN} ./minigzipsh -d && ${QEMU_RUN} ./examplesh $$TMPSH; then \
+ echo ' *** zlib shared test OK ***'; \
+ echo ' *** zlib shared test FAILED ***'; false; \
+ @rm -f tmpsh_$$
+test64: all64
+ @TMP64=tmp64_$$; \
+ if echo hello world | ${QEMU_RUN} ./minigzip64 | ${QEMU_RUN} ./minigzip64 -d && ${QEMU_RUN} ./example64 $$TMP64; then \
+ echo ' *** zlib 64-bit test OK ***'; \
+ echo ' *** zlib 64-bit test FAILED ***'; false; \
+ @rm -f tmp64_$$
+infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
+infcover: infcover.o libz.a
+ $(CC) $(CFLAGS) -o $@ infcover.o libz.a
+cover: infcover
+ rm -f *.gcda
+ ${QEMU_RUN} ./infcover
+ gcov inf*.c
+libz.a: $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+match.lo: match.S
+ $(CC) -c -fPIC _match.s
+ mv _match.o match.lo
+example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c
+minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c
+example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c
+minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c
+adler32.o: $(SRCDIR)adler32.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c
+crc32.o: $(SRCDIR)crc32.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c
+deflate.o: $(SRCDIR)deflate.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
+infback.o: $(SRCDIR)infback.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c
+inffast.o: $(SRCDIR)inffast.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c
+inflate.o: $(SRCDIR)inflate.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c
+inftrees.o: $(SRCDIR)inftrees.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c
+trees.o: $(SRCDIR)trees.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c
+zutil.o: $(SRCDIR)zutil.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c
+compress.o: $(SRCDIR)compress.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c
+uncompr.o: $(SRCDIR)uncompr.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c
+gzclose.o: $(SRCDIR)gzclose.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c
+gzlib.o: $(SRCDIR)gzlib.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c
+gzread.o: $(SRCDIR)gzread.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c
+gzwrite.o: $(SRCDIR)gzwrite.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c
+adler32.lo: $(SRCDIR)adler32.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c
+ -@mv objs/adler32.o $@
+crc32.lo: $(SRCDIR)crc32.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c
+ -@mv objs/crc32.o $@
+deflate.lo: $(SRCDIR)deflate.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c
+ -@mv objs/deflate.o $@
+infback.lo: $(SRCDIR)infback.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c
+ -@mv objs/infback.o $@
+inffast.lo: $(SRCDIR)inffast.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c
+ -@mv objs/inffast.o $@
+inflate.lo: $(SRCDIR)inflate.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c
+ -@mv objs/inflate.o $@
+inftrees.lo: $(SRCDIR)inftrees.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c
+ -@mv objs/inftrees.o $@
+trees.lo: $(SRCDIR)trees.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c
+ -@mv objs/trees.o $@
+zutil.lo: $(SRCDIR)zutil.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c
+ -@mv objs/zutil.o $@
+compress.lo: $(SRCDIR)compress.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c
+ -@mv objs/compress.o $@
+uncompr.lo: $(SRCDIR)uncompr.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c
+ -@mv objs/uncompr.o $@
+gzclose.lo: $(SRCDIR)gzclose.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c
+ -@mv objs/gzclose.o $@
+gzlib.lo: $(SRCDIR)gzlib.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c
+ -@mv objs/gzlib.o $@
+gzread.lo: $(SRCDIR)gzread.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c
+ -@mv objs/gzread.o $@
+gzwrite.lo: $(SRCDIR)gzwrite.c
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c
+ -@mv objs/gzwrite.o $@
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
+ $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+ rm -f $(SHAREDLIB) $(SHAREDLIBM)
+ ln -s $@ $(SHAREDLIB)
+ ln -s $@ $(SHAREDLIBM)
+ -@rmdir objs
+example$(EXE): example.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+minigzip$(EXE): minigzip.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+examplesh$(EXE): example.o $(SHAREDLIBV)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) -L. $(SHAREDLIBV)
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) -L. $(SHAREDLIBV)
+example64$(EXE): example64.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+install-libs: $(LIBS)
+ -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+ -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi
+ -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+ -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+ -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+ rm -f $(DESTDIR)$(libdir)/$(STATICLIB)
+ cp $(STATICLIB) $(DESTDIR)$(libdir)
+ chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+ -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+ -@if test -n "$(SHAREDLIBV)"; then \
+ rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+ cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+ echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+ chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+ echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+ rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+ ($(LDCONFIG) || true) >/dev/null 2>&1; \
+ rm -f $(DESTDIR)$(man3dir)/zlib.3
+ cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir)
+ chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+ rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc
+ cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+ chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+install: install-libs
+ -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi
+ rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+ cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir)
+ chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+uninstall:
+ cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+ cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+ if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+ cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+ cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
+docs: zlib.3.pdf
+zlib.3.pdf: $(SRCDIR)zlib.3
+ groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@
+zconf.h.cmakein: $(SRCDIR)zconf.h.in
+ -@ TEMPFILE=zconfh_$$; \
+ echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+ sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\
+ touch -r $(SRCDIR)zconf.h.in $@ &&\
+ rm $$TEMPFILE
+zconf: $(SRCDIR)zconf.h.in
+ cp -p $(SRCDIR)zconf.h.in zconf.h
+mostlyclean: clean
+clean:
+ rm -f *.o *.lo *~ \
+ example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+ example64$(EXE) minigzip64$(EXE) \
+ infcover \
+ libz.* foo.gz so_locations \
+ _match.s maketree contrib/infback9/*.o
+ rm -rf objs
+ rm -f *.gcda *.gcno *.gcov
+ rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
+maintainer-clean: distclean
+distclean: clean zconf zconf.h.cmakein
+ rm -f Makefile zlib.pc configure.log
+ -@rm -f .DS_Store
+ @if [ -f Makefile.in ]; then \
+ printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \
+ printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \
+ touch -r $(SRCDIR)Makefile.in Makefile ; fi
+tags:
+ etags $(SRCDIR)*.[ch]
+adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h
+crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
+adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h
+crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
@@ -0,0 +1,118 @@
+ZLIB DATA COMPRESSION LIBRARY
+zlib 1.2.13 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact [email protected]). A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
+Questions about zlib should be sent to <[email protected]>, or to Gilles Vollant
+<[email protected]> for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+Mark Nelson <[email protected]> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+The changes made in version 1.2.13 are documented in the file ChangeLog.
+Unsupported third party contributions are provided in directory contrib/ .
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+A Perl interface to zlib written by Paul Marquess <[email protected]> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+A Python interface to zlib written by A.M. Kuchling <[email protected]> is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <[email protected]>, is available in the
+contrib/minizip directory of zlib.
+Notes for some targets:
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+- gzdopen is not supported on RISCOS or BEOS.
+- For PalmOs, see http://palmzlib.sourceforge.net/
+Acknowledgments:
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code. We make all
+contributions to and distributions of this project solely in our personal
+capacity, and are not conveying any rights to any intellectual property of
+any third parties.
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
@@ -0,0 +1,186 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+/* @(#) $Id$ */
+#include "zutil.h"
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+#define BASE 65521U /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
+ CHOP(a); \
+ if (a >= BASE) a -= BASE; \
+# define MOD(a) \
+ MOD28(a); \
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+#else
+# define MOD(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
+#endif
+/* ========================================================================= */
+uLong ZEXPORT adler32_z(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ z_size_t len;
+{
+ unsigned long sum2;
+ unsigned n;
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ MOD28(sum2); /* only added so many BASE's */
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ /* return recombined sums */
+}
+uLong ZEXPORT adler32(adler, buf, len)
+ uInt len;
+ return adler32_z(adler, buf, len);
+local uLong adler32_combine_(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+ unsigned long sum1;
+ unsigned rem;
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+ /* the derivation of this formula is left as an exercise for the reader */
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ z_off_t len2;
+ return adler32_combine_(adler1, adler2, len2);
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
@@ -0,0 +1,69 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+LIBNAME = libzip.a
+CC = scppc
+CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
+ OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
+AR = ppc-amigaos-ar cr
+RANLIB = ppc-amigaos-ranlib
+LD = ppc-amigaos-ld -r
+LDFLAGS = -o
+LDLIBS = LIB:scppc.a LIB:end.o
+RM = delete quiet
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+TEST_OBJS = example.o minigzip.o
+all: example minigzip
+test: all
+ example
+ echo hello world | minigzip | minigzip -d
+$(LIBNAME): $(OBJS)
+ $(AR) $@ $(OBJS)
+ -$(RANLIB) $@
+example: example.o $(LIBNAME)
+ $(LD) $(LDFLAGS) $@ LIB:c_ppc.o [email protected] $(LIBNAME) $(LDLIBS)
+minigzip: minigzip.o $(LIBNAME)
+ $(RM) *.o example minigzip $(LIBNAME) foo.gz
+zip:
+ zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
+ descrip.mms *.[ch]
+tgz:
+ cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+ zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi <[email protected]>
+# Amiga, SAS/C 6.56 & Smake
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+ NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
+ DEF=POSTINC
+all: SCOPTIONS example minigzip
+install: z.lib
+ copy clone zlib.h zconf.h INCLUDE:
+ copy clone z.lib LIB:
+z.lib: $(OBJS)
+ oml z.lib r $(OBJS)
+example: example.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+minigzip: minigzip.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+ -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
+SCOPTIONS: Makefile.sas
+ copy to $@ <from <
+$(SCOPTIONS)
+<
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
+#define ZLIB_INTERNAL
+#include "zlib.h"
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong left;
+ left = *destLen;
+ *destLen = 0;
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+ stream.next_out = dest;
+ stream.avail_out = 0;
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ if (stream.avail_in == 0) {
+ stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
+ sourceLen -= stream.avail_in;
+ err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+ } while (err == Z_OK);
+ *destLen = stream.total_out;
+ deflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK : err;
+int ZEXPORT compress(dest, destLen, source, sourceLen)
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+uLong ZEXPORT compressBound(sourceLen)
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
@@ -0,0 +1,922 @@
+#!/bin/sh
+# configure script for zlib.
+# To impose specific compiler or flags or install directory, use for example:
+# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+# start off configure.log
+echo -------------------- >> configure.log
+echo $0 $* >> configure.log
+date >> configure.log
+# get source directory
+SRCDIR=`dirname $0`
+if test $SRCDIR = "."; then
+ ZINC=""
+ ZINCOUT="-I."
+ SRCDIR=""
+else
+ ZINC='-include zconf.h'
+ ZINCOUT='-I. -I$(SRCDIR)'
+ SRCDIR="$SRCDIR/"
+fi
+# set command prefix for cross-compilation
+if [ -n "${CHOST}" ]; then
+ uname=${CHOST}
+ mname=${CHOST}
+ CROSS_PREFIX="${CHOST}-"
+ mname=`(uname -a || echo unknown) 2>/dev/null`
+# destination name for static library
+# extract zlib version numbers from zlib.h
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h`
+VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+# establish commands for library building
+if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ AR=${AR-"${CROSS_PREFIX}ar"}
+ test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+ AR=${AR-"ar"}
+ARFLAGS=${ARFLAGS-"rc"}
+if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
+ test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
+ RANLIB=${RANLIB-"ranlib"}
+if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ NM=${NM-"${CROSS_PREFIX}nm"}
+ test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
+ NM=${NM-"nm"}
+# set defaults before processing command line options
+LDCONFIG=${LDCONFIG-"ldconfig"}
+LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+ARCHS=
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+sharedlibdir=${sharedlibdir-'${libdir}'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=1
+solo=0
+cover=0
+zprefix=0
+zconst=0
+build64=0
+gcc=0
+warn=0
+debug=0
+sanitize=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+OBJC='$(OBJZ) $(OBJG)'
+PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
+# leave this script, optionally in a bad way
+leave()
+ if test "$*" != "0"; then
+ echo "** $0 aborting." | tee -a configure.log
+ rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+ echo -------------------- >> configure.log
+ echo >> configure.log
+ exit $1
+# process command line options
+while test $# -ge 1
+do
+case "$1" in
+ -h* | --help)
+ echo 'usage:' | tee -a configure.log
+ echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
+ echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
+ echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
+ exit 0 ;;
+ -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+ -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+ -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
+ --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
+ -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
+ -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
+ -p* | --prefix) prefix="$2"; shift; shift ;;
+ -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
+ -l* | --libdir) libdir="$2"; shift; shift ;;
+ -i* | --includedir) includedir="$2"; shift; shift ;;
+ -s* | --shared | --enable-shared) shared=1; shift ;;
+ -t | --static) shared=0; shift ;;
+ --solo) solo=1; shift ;;
+ --cover) cover=1; shift ;;
+ -z* | --zprefix) zprefix=1; shift ;;
+ -6* | --64) build64=1; shift ;;
+ -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
+ --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
+ --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
+ -c* | --const) zconst=1; shift ;;
+ -w* | --warn) warn=1; shift ;;
+ -d* | --debug) debug=1; shift ;;
+ --sanitize) sanitize=1; shift ;;
+ *)
+ echo "unknown option: $1" | tee -a configure.log
+ echo "$0 --help for help" | tee -a configure.log
+ leave 1;;
+ esac
+done
+# temporary file name
+test=ztest$$
+# put arguments in log, also put test file in log if used in arguments
+show()
+ case "$*" in
+ *$test.c*)
+ echo === $test.c === >> configure.log
+ cat $test.c >> configure.log
+ echo === >> configure.log;;
+ echo $* >> configure.log
+# check for gcc vs. cc and set compile and link flags based on the system identified by uname
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+if test -z "$CC"; then
+ echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
+ if ${CROSS_PREFIX}gcc -v >/dev/null 2>&1; then
+ cc=${CROSS_PREFIX}gcc
+ else
+ cc=${CROSS_PREFIX}cc
+ cc=${CC}
+case "$cc" in
+ *gcc*) gcc=1 ;;
+ *clang*) gcc=1 ;;
+esac
+case `$cc -v 2>&1` in
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
+ echo ... using gcc >> configure.log
+ CC="$cc"
+ CFLAGS="${CFLAGS--O3}"
+ SFLAGS="${CFLAGS--O3} -fPIC"
+ if test "$ARCHS"; then
+ CFLAGS="${CFLAGS} ${ARCHS}"
+ LDFLAGS="${LDFLAGS} ${ARCHS}"
+ if test $build64 -eq 1; then
+ CFLAGS="${CFLAGS} -m64"
+ SFLAGS="${SFLAGS} -m64"
+ if test "$warn" -eq 1; then
+ if test "$zconst" -eq 1; then
+ CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -DZLIB_CONST"
+ CFLAGS="${CFLAGS} -Wall -Wextra"
+ if test $sanitize -eq 1; then
+ CFLAGS="${CFLAGS} -g -fsanitize=address"
+ if test $debug -eq 1; then
+ CFLAGS="${CFLAGS} -DZLIB_DEBUG"
+ SFLAGS="${SFLAGS} -DZLIB_DEBUG"
+ if test -z "$uname"; then
+ uname=`(uname -s || echo unknown) 2>/dev/null`
+ case "$uname" in
+ Linux* | linux* | *-linux* | GNU | GNU/* | solaris*)
+ case "$mname" in
+ *sparc*)
+ LDFLAGS="${LDFLAGS} -Wl,--no-warn-rwx-segments" ;;
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;;
+ *BSD | *bsd* | DragonFly)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"}
+ LDCONFIG="ldconfig -m" ;;
+ CYGWIN* | Cygwin* | cygwin* | *-cygwin* | OS/2*)
+ EXE='.exe' ;;
+ MINGW* | mingw* | *-mingw*)
+ rm -f $test.[co] $test $test$shared_ext
+ echo "If this doesn't work for you, try win32/Makefile.gcc." | tee -a configure.log
+ LDSHARED=${LDSHARED-"$cc -shared"}
+ LDSHAREDLIBC=""
+ QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+ # ([email protected])
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
+ HP-UX*)
+ LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ ia64)
+ shared_ext='.so'
+ SHAREDLIB='libz.so' ;;
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl' ;;
+ esac ;;
+ AIX*)
+ LDFLAGS="${LDFLAGS} -Wl,-brtl" ;;
+ Darwin* | darwin* | *-darwin*)
+ shared_ext='.dylib'
+ SHAREDLIB=libz$shared_ext
+ SHAREDLIBV=libz.$VER$shared_ext
+ SHAREDLIBM=libz.$VER1$shared_ext
+ LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
+ if libtool -V 2>&1 | grep Apple > /dev/null; then
+ AR="libtool"
+ AR="/usr/bin/libtool"
+ ARFLAGS="-o" ;;
+ LDSHARED=${LDSHARED-"$cc -shared"} ;;
+ # find system name and corresponding cc options
+ CC=${CC-cc}
+ gcc=0
+ echo ... using $CC >> configure.log
+ uname=`(uname -sr || echo unknown) 2>/dev/null`
+ HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
+ CFLAGS=${CFLAGS-"-O"}
+# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+ LDSHARED=${LDSHARED-"ld -b"}
+ IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+ CFLAGS=${CFLAGS-"-ansi -O2"}
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+ OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDFLAGS="${LDFLAGS} -Wl,-rpath,."
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
+ OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
+ QNX*) SFLAGS=${CFLAGS-"-4 -O"}
+ CFLAGS=${CFLAGS-"-4 -O"}
+ LDSHARED=${LDSHARED-"cc"}
+ RANLIB=${RANLIB-"true"}
+ AR="cc"
+ ARFLAGS="-A" ;;
+ SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+ CFLAGS=${CFLAGS-"-O3"}
+ LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
+ SunOS\ 5* | solaris*)
+ LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
+ SFLAGS=${CFLAGS-"-fast -KPIC"}
+ CFLAGS=${CFLAGS-"-fast"}
+ # old versions of SunPRO/Workshop/Studio don't support -m64,
+ # but newer ones do. Check for it.
+ flag64=`$CC -flags | egrep -- '^-m64'`
+ if test x"$flag64" != x"" ; then
+ i86*)
+ SFLAGS="$SFLAGS -xarch=amd64"
+ CFLAGS="$CFLAGS -xarch=amd64" ;;
+ SFLAGS="$SFLAGS -xarch=v9"
+ CFLAGS="$CFLAGS -xarch=v9" ;;
+ if test -n "$ZINC"; then
+ ZINC='-I- -I. -I$(SRCDIR)'
+ ;;
+ SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+ CFLAGS=${CFLAGS-"-O2"}
+ LDSHARED=${LDSHARED-"ld"} ;;
+ SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+ CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
+ LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
+ UNIX_System_V\ 4.2.0)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ LDSHARED=${LDSHARED-"cc -G"} ;;
+ UNIX_SV\ 4.2MP)
+ SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+ OpenUNIX\ 5)
+ AIX*) # Courtesy of [email protected]
+ SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ LDSHARED=${LDSHARED-"xlc -G"} ;;
+ # send working options for other systems to [email protected]
+ *) SFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -shared"} ;;
+# destination names for shared library if not defined above
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+echo >> configure.log
+# define functions for testing compiler and library characteristics and logging the results
+#error error
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+ try()
+ {
+ show $*
+ test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+ echo - using any output from compiler to indicate an error >> configure.log
+ got=`( $* ) 2>&1`
+ ret=$?
+ if test "$got" != ""; then
+ printf "%s\n" "$got" >> configure.log
+ if test $ret -ne 0; then
+ echo "(exit code "$ret")" >> configure.log
+ return $ret
+tryboth()
+ test "$got" = ""
+cat > $test.c << EOF
+int foo() { return 0; }
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+ :
+ echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+ leave 1
+# see if shared library build supported
+if test $shared -eq 1; then
+ echo Checking for shared library support... | tee -a configure.log
+ # we must test in two steps (cc then ld), required at least on SunOS 4.x
+ if try $CC -w -c $SFLAGS $test.c &&
+ try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
+ echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
+ elif test -z "$old_cc" -a -z "$old_cflags"; then
+ echo No shared library support. | tee -a configure.log
+ shared=0;
+ echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
+if test $shared -eq 0; then
+ LDSHARED="$CC"
+ ALL="static"
+ TEST="all teststatic"
+ SHAREDLIB=""
+ SHAREDLIBV=""
+ SHAREDLIBM=""
+ echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
+ ALL="static shared"
+ TEST="all teststatic testshared"
+# check for size_t
+#include <stdio.h>
+#include <stdlib.h>
+size_t dummy = 0;
+ echo "Checking for size_t... Yes." | tee -a configure.log
+ echo "Checking for size_t... No." | tee -a configure.log
+ # find a size_t integer type
+ # check for long long
+ cat > $test.c << EOF
+long long dummy = 0;
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for long long... Yes." | tee -a configure.log
+ cat > $test.c <<EOF
+int main(void) {
+ if (sizeof(void *) <= sizeof(int)) puts("int");
+ else if (sizeof(void *) <= sizeof(long)) puts("long");
+ else puts("z_longlong");
+ return 0;
+ echo "Checking for long long... No." | tee -a configure.log
+ else puts("long");
+ if try $CC $CFLAGS -o $test $test.c; then
+ sizet=`./$test`
+ echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log
+ CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
+ SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
+ echo "Checking for a pointer-size integer type... not found." | tee -a configure.log
+# check for large file support, and if none, check for fseeko()
+#include <sys/types.h>
+off64_t dummy = 0;
+if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
+ CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
+ SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
+ ALL="${ALL} all64"
+ TEST="${TEST} test64"
+ echo "Checking for off64_t... Yes." | tee -a configure.log
+ echo "Checking for fseeko... Yes." | tee -a configure.log
+ echo "Checking for off64_t... No." | tee -a configure.log
+ fseeko(NULL, 0, 0);
+ CFLAGS="${CFLAGS} -DNO_FSEEKO"
+ SFLAGS="${SFLAGS} -DNO_FSEEKO"
+ echo "Checking for fseeko... No." | tee -a configure.log
+# check for strerror() for use by gz* functions
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for strerror... Yes." | tee -a configure.log
+ CFLAGS="${CFLAGS} -DNO_STRERROR"
+ SFLAGS="${SFLAGS} -DNO_STRERROR"
+ echo "Checking for strerror... No." | tee -a configure.log
+# copy clean zconf.h for subsequent edits
+cp -p ${SRCDIR}zconf.h.in zconf.h
+# check for unistd.h and save result in zconf.h
+#include <unistd.h>
+int main() { return 0; }
+ sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ mv zconf.temp.h zconf.h
+ echo "Checking for unistd.h... Yes." | tee -a configure.log
+ echo "Checking for unistd.h... No." | tee -a configure.log
+# check for stdarg.h and save result in zconf.h
+#include <stdarg.h>
+ sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ echo "Checking for stdarg.h... Yes." | tee -a configure.log
+ echo "Checking for stdarg.h... No." | tee -a configure.log
+# if the z_ prefix was requested, save that in zconf.h
+if test $zprefix -eq 1; then
+ sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ echo "Using z_ prefix on all symbols." | tee -a configure.log
+# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
+if test $solo -eq 1; then
+ sed '/#define ZCONF_H/a\
+#define Z_SOLO
+' < zconf.h > zconf.temp.h
+OBJC='$(OBJZ)'
+PIC_OBJC='$(PIC_OBJZ)'
+# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
+if test $cover -eq 1; then
+ CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
+ if test -n "$GCC_CLASSIC"; then
+ CC=$GCC_CLASSIC
+# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
+# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
+# return value. The most secure result is vsnprintf() with a return value. snprintf() with a
+# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
+#include "zconf.h"
+int main()
+#ifndef STDC
+ choke me
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
+int mytest(const char *fmt, ...)
+ char buf[20];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return (mytest("Hello%d\n", 1));
+ echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
+ cat >$test.c <<EOF
+ int n;
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ return n;
+ echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
+ CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+ SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
+ echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ CFLAGS="$CFLAGS -DNO_vsnprintf"
+ SFLAGS="$SFLAGS -DNO_vsnprintf"
+ echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
+ echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
+ n = vsprintf(buf, fmt, ap);
+ echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
+ CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+ SFLAGS="$SFLAGS -DHAS_vsprintf_void"
+ echo "Checking for return value of vsprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
+int mytest()
+ snprintf(buf, sizeof(buf), "%s", "foo");
+ return (mytest());
+ echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
+ return snprintf(buf, sizeof(buf), "%s", "foo");
+ echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
+ CFLAGS="$CFLAGS -DHAS_snprintf_void"
+ SFLAGS="$SFLAGS -DHAS_snprintf_void"
+ echo "Checking for return value of snprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
+ CFLAGS="$CFLAGS -DNO_snprintf"
+ SFLAGS="$SFLAGS -DNO_snprintf"
+ echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
+ return sprintf(buf, "%s", "foo");
+ echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
+ CFLAGS="$CFLAGS -DHAS_sprintf_void"
+ SFLAGS="$SFLAGS -DHAS_sprintf_void"
+ echo "Checking for return value of sprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
+# see if we can hide zlib internal symbols that are linked between separate source files
+if test "$gcc" -eq 1; then
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+int ZLIB_INTERNAL foo;
+ if tryboth $CC -c $CFLAGS $test.c; then
+ CFLAGS="$CFLAGS -DHAVE_HIDDEN"
+ SFLAGS="$SFLAGS -DHAVE_HIDDEN"
+ echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
+ echo "Checking for attribute(visibility) support... No." | tee -a configure.log
+# show the results in the log
+echo ALL = $ALL >> configure.log
+echo AR = $AR >> configure.log
+echo ARFLAGS = $ARFLAGS >> configure.log
+echo CC = $CC >> configure.log
+echo CFLAGS = $CFLAGS >> configure.log
+echo CPP = $CPP >> configure.log
+echo EXE = $EXE >> configure.log
+echo LDCONFIG = $LDCONFIG >> configure.log
+echo LDFLAGS = $LDFLAGS >> configure.log
+echo LDSHARED = $LDSHARED >> configure.log
+echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
+echo OBJC = $OBJC >> configure.log
+echo PIC_OBJC = $PIC_OBJC >> configure.log
+echo RANLIB = $RANLIB >> configure.log
+echo SFLAGS = $SFLAGS >> configure.log
+echo SHAREDLIB = $SHAREDLIB >> configure.log
+echo SHAREDLIBM = $SHAREDLIBM >> configure.log
+echo SHAREDLIBV = $SHAREDLIBV >> configure.log
+echo STATICLIB = $STATICLIB >> configure.log
+echo TEST = $TEST >> configure.log
+echo VER = $VER >> configure.log
+echo SRCDIR = $SRCDIR >> configure.log
+echo exec_prefix = $exec_prefix >> configure.log
+echo includedir = $includedir >> configure.log
+echo libdir = $libdir >> configure.log
+echo mandir = $mandir >> configure.log
+echo prefix = $prefix >> configure.log
+echo sharedlibdir = $sharedlibdir >> configure.log
+echo uname = $uname >> configure.log
+# udpate Makefile with the configure results
+sed < ${SRCDIR}Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^SFLAGS *=/s#=.*#=$SFLAGS#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^CPP *=/s#=.*#=$CPP#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^LDCONFIG *=/s#=.*#=$LDCONFIG#
+/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
+/^EXE *=/s#=.*#=$EXE#
+/^SRCDIR *=/s#=.*#=$SRCDIR#
+/^ZINC *=/s#=.*#=$ZINC#
+/^ZINCOUT *=/s#=.*#=$ZINCOUT#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^OBJC *=/s#=.*#= $OBJC#
+/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
+/^all: */s#:.*#: $ALL#
+/^test: */s#:.*#: $TEST#
+" > Makefile
+# create zlib.pc with the configure results
+sed < ${SRCDIR}zlib.pc.in "
+" | sed -e "
+s/\@VERSION\@/$VER/g;
+" > zlib.pc
+# done
+leave 0
@@ -0,0 +1,57 @@
+All files under this contrib directory are UNSUPPORTED. They were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+ada/ by Dmitriy Anisimkov <[email protected]>
+ Support for Ada
+ See http://zlib-ada.sourceforge.net/
+blast/ by Mark Adler <[email protected]>
+ Decompressor for output of PKWare Data Compression Library (DCL)
+delphi/ by Cosmin Truta <[email protected]>
+ Support for Delphi and C++ Builder
+dotzlib/ by Henrik Ravn <[email protected]>
+ Support for Microsoft .Net and Visual C++ .Net
+gcc_gvmat64/by Gilles Vollant <[email protected]>
+ GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+ assembler to replace longest_match() and inflate_fast()
+infback9/ by Mark Adler <[email protected]>
+ Unsupported diffs to infback to decode the deflate64 format
+iostream/ by Kevin Ruland <[email protected]>
+iostream2/ by Tyge Løvset <[email protected]>
+iostream3/ by Ludwig Schwardt <[email protected]>
+ and Kevin Ruland <[email protected]>
+ Yet another C++ I/O streams interface
+minizip/ by Gilles Vollant <[email protected]>
+ Mini zip and unzip based on zlib
+ Includes Zip64 support by Mathias Svensson <[email protected]>
+ See http://www.winimage.com/zLibDll/minizip.html
+pascal/ by Bob Dellaca <[email protected]> et al.
+ Support for Pascal
+puff/ by Mark Adler <[email protected]>
+ Small, low memory usage inflate. Also serves to provide an
+ unambiguous description of the deflate format.
+testzlib/ by Gilles Vollant <[email protected]>
+ Example of the use of zlib
+untgz/ by Pedro A. Aranda Gutierrez <[email protected]>
+vstudio/ by Gilles Vollant <[email protected]>
+ Building a minizip-enhanced zlib with Microsoft Visual Studio
+ Includes vc11 from kreuzerkrieg and vc12 from davispuh
@@ -0,0 +1,106 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2004 Dmitriy Anisimkov --
+-- Open source license information is in the zlib.ads file. --
+--
+-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
+-- This demo program provided by Dr Steve Sangwine <[email protected]>
+-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
+-- of exactly the correct size is used for decompressed data, and the last
+-- few bytes passed in to Zlib are checksum bytes.
+-- This program compresses a string of text, and then decompresses the
+-- compressed text into a buffer of the same size as the original text.
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+with ZLib; use ZLib;
+procedure Buffer_Demo is
+ EOL : Character renames ASCII.LF;
+ Text : constant String
+ := "Four score and seven years ago our fathers brought forth," & EOL &
+ "upon this continent, a new nation, conceived in liberty," & EOL &
+ "and dedicated to the proposition that `all men are created equal'.";
+ Source : Stream_Element_Array (1 .. Text'Length);
+ for Source'Address use Text'Address;
+begin
+ Ada.Text_IO.Put (Text);
+ Ada.Text_IO.New_Line;
+ Ada.Text_IO.Put_Line
+ ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
+ declare
+ Compressed_Data : Stream_Element_Array (1 .. Text'Length);
+ L : Stream_Element_Offset;
+ begin
+ Compress : declare
+ Compressor : Filter_Type;
+ I : Stream_Element_Offset;
+ Deflate_Init (Compressor);
+ -- Compress the whole of T at once.
+ Translate (Compressor, Source, I, Compressed_Data, L, Finish);
+ pragma Assert (I = Source'Last);
+ Close (Compressor);
+ ("Compressed size : "
+ & Stream_Element_Offset'Image (L) & " bytes");
+ end Compress;
+ -- Now we decompress the data, passing short blocks of data to Zlib
+ -- (because this demonstrates the problem - the last block passed will
+ -- contain checksum information and there will be no output, only a
+ -- check inside Zlib that the checksum is correct).
+ Decompress : declare
+ Decompressor : Filter_Type;
+ Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
+ Block_Size : constant := 4;
+ -- This makes sure that the last block contains
+ -- only Adler checksum data.
+ P : Stream_Element_Offset := Compressed_Data'First - 1;
+ O : Stream_Element_Offset;
+ Inflate_Init (Decompressor);
+ loop
+ Translate
+ (Decompressor,
+ Compressed_Data
+ (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
+ P,
+ Uncompressed_Data
+ (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
+ O,
+ No_Flush);
+ ("Total in : " & Count'Image (Total_In (Decompressor)) &
+ ", out : " & Count'Image (Total_Out (Decompressor)));
+ exit when P = L;
+ end loop;
+ ("Decompressed text matches original text : "
+ & Boolean'Image (Uncompressed_Data = Source));
+ end Decompress;
+ end;
+end Buffer_Demo;
@@ -0,0 +1,156 @@
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- Continuous test for ZLib multithreading. If the test would fail
+-- we should provide thread safe allocation routines for the Z_Stream.
+-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
+with ZLib;
+with Ada.Streams;
+with Ada.Numerics.Discrete_Random;
+with Ada.Exceptions;
+with Ada.Task_Identification;
+procedure MTest is
+ use Ada.Streams;
+ use ZLib;
+ Stop : Boolean := False;
+ pragma Atomic (Stop);
+ subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+ package Random_Elements is
+ new Ada.Numerics.Discrete_Random (Visible_Symbols);
+ task type Test_Task;
+ task body Test_Task is
+ Buffer : Stream_Element_Array (1 .. 100_000);
+ Gen : Random_Elements.Generator;
+ Buffer_First : Stream_Element_Offset;
+ Compare_First : Stream_Element_Offset;
+ Deflate : Filter_Type;
+ Inflate : Filter_Type;
+ procedure Further (Item : in Stream_Element_Array);
+ procedure Read_Buffer
+ (Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+ -------------
+ -- Further --
+ procedure Further (Item : in Stream_Element_Array) is
+ procedure Compare (Item : in Stream_Element_Array);
+ -- Compare --
+ procedure Compare (Item : in Stream_Element_Array) is
+ Next_First : Stream_Element_Offset := Compare_First + Item'Length;
+ if Buffer (Compare_First .. Next_First - 1) /= Item then
+ raise Program_Error;
+ end if;
+ Compare_First := Next_First;
+ end Compare;
+ procedure Compare_Write is new ZLib.Write (Write => Compare);
+ Compare_Write (Inflate, Item, No_Flush);
+ end Further;
+ -----------------
+ -- Read_Buffer --
+ Last : out Ada.Streams.Stream_Element_Offset)
+ is
+ Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First;
+ Next_First : Stream_Element_Offset;
+ if Item'Length <= Buff_Diff then
+ Last := Item'Last;
+ Next_First := Buffer_First + Item'Length;
+ Item := Buffer (Buffer_First .. Next_First - 1);
+ Buffer_First := Next_First;
+ Last := Item'First + Buff_Diff;
+ Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
+ Buffer_First := Buffer'Last + 1;
+ end Read_Buffer;
+ procedure Translate is new Generic_Translate
+ (Data_In => Read_Buffer,
+ Data_Out => Further);
+ Random_Elements.Reset (Gen);
+ Buffer := (others => 20);
+ Main : loop
+ for J in Buffer'Range loop
+ Buffer (J) := Random_Elements.Random (Gen);
+ Deflate_Init (Deflate);
+ Inflate_Init (Inflate);
+ Buffer_First := Buffer'First;
+ Compare_First := Buffer'First;
+ Translate (Deflate);
+ if Compare_First /= Buffer'Last + 1 then
+ (Ada.Task_Identification.Image
+ (Ada.Task_Identification.Current_Task)
+ & Stream_Element_Offset'Image (J)
+ & ZLib.Count'Image (Total_Out (Deflate)));
+ Close (Deflate);
+ Close (Inflate);
+ exit Main when Stop;
+ end loop Main;
+ exception
+ when E : others =>
+ Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
+ Stop := True;
+ end Test_Task;
+ Test : array (1 .. 4) of Test_Task;
+ pragma Unreferenced (Test);
+ Dummy : Character;
+ Ada.Text_IO.Get_Immediate (Dummy);
+end MTest;
+-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
+-- Test/demo program for the generic read interface.
+procedure Read is
+ ------------------------------------
+ -- Test configuration parameters --
+ File_Size : Stream_Element_Offset := 100_000;
+ Continuous : constant Boolean := False;
+ -- If this constant is True, the test would be repeated again and again,
+ -- with increment File_Size for every iteration.
+ Header : constant ZLib.Header_Type := ZLib.Default;
+ -- Do not use Header other than Default in ZLib versions 1.1.4 and older.
+ Init_Random : constant := 8;
+ -- We are using the same random sequence, in case of we catch bug,
+ -- so we would be able to reproduce it.
+ -- End --
+ Pack_Size : Stream_Element_Offset;
+ Offset : Stream_Element_Offset;
+ Filter : ZLib.Filter_Type;
+ subtype Visible_Symbols
+ is Stream_Element range 16#20# .. 16#7E#;
+ package Random_Elements is new
+ Ada.Numerics.Discrete_Random (Visible_Symbols);
+ Period : constant Stream_Element_Offset := 200;
+ -- Period constant variable for random generator not to be very random.
+ -- Bigger period, harder random.
+ Read_Buffer : Stream_Element_Array (1 .. 2048);
+ Read_First : Stream_Element_Offset;
+ Read_Last : Stream_Element_Offset;
+ procedure Reset;
+ procedure Read
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset);
+ -- this procedure is for generic instantiation of
+ -- ZLib.Read
+ -- reading data from the File_In.
+ procedure Read is new ZLib.Read
+ (Read,
+ Read_Buffer,
+ Rest_First => Read_First,
+ Rest_Last => Read_Last);
+ ----------
+ -- Read --
+ Last : out Stream_Element_Offset) is
+ Last := Stream_Element_Offset'Min
+ (Item'Last,
+ Item'First + File_Size - Offset);
+ for J in Item'First .. Last loop
+ if J < Item'First + Period then
+ Item (J) := Random_Elements.Random (Gen);
+ Item (J) := Item (J - Period);
+ Offset := Offset + 1;
+ end Read;
+ -----------
+ -- Reset --
+ procedure Reset is
+ Random_Elements.Reset (Gen, Init_Random);
+ Pack_Size := 0;
+ Offset := 1;
+ Read_First := Read_Buffer'Last + 1;
+ Read_Last := Read_Buffer'Last;
+ end Reset;
+ Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+ for Level in ZLib.Compression_Level'Range loop
+ Ada.Text_IO.Put ("Level ="
+ & ZLib.Compression_Level'Image (Level));
+ -- Deflate using generic instantiation.
+ ZLib.Deflate_Init
+ (Filter,
+ Level,
+ Header => Header);
+ Reset;
+ Ada.Text_IO.Put
+ (Stream_Element_Offset'Image (File_Size) & " ->");
+ Buffer : Stream_Element_Array (1 .. 1024);
+ Last : Stream_Element_Offset;
+ Read (Filter, Buffer, Last);
+ Pack_Size := Pack_Size + Last - Buffer'First + 1;
+ exit when Last < Buffer'Last;
+ Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
+ ZLib.Close (Filter);
+ exit when not Continuous;
+ File_Size := File_Size + 1;
+end Read;
@@ -0,0 +1,65 @@
+ ZLib for Ada thick binding (ZLib.Ada)
+ Release 1.3
+ZLib.Ada is a thick binding interface to the popular ZLib data
+compression library, available at http://www.gzip.org/zlib/.
+It provides Ada-style access to the ZLib C library.
+ Here are the main changes since ZLib.Ada 1.2:
+- Attension: ZLib.Read generic routine have a initialization requirement
+ for Read_Last parameter now. It is a bit incompartible with previous version,
+ but extends functionality, we could use new parameters Allow_Read_Some and
+ Flush now.
+- Added Is_Open routines to ZLib and ZLib.Streams packages.
+- Add pragma Assert to check Stream_Element is 8 bit.
+- Fix extraction to buffer with exact known decompressed size. Error reported by
+ Steve Sangwine.
+- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
+ computers. Patch provided by Pascal Obry.
+- Add Status_Error exception definition.
+- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
+ How to build ZLib.Ada under GNAT
+You should have the ZLib library already build on your computer, before
+building ZLib.Ada. Make the directory of ZLib.Ada sources current and
+issue the command:
+ gnatmake test -largs -L<directory where libz.a is> -lz
+Or use the GNAT project file build for GNAT 3.15 or later:
+ gnatmake -Pzlib.gpr -L<directory where libz.a is>
+ How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
+1. Make a project with all *.ads and *.adb files from the distribution.
+2. Build the libz.a library from the ZLib C sources.
+3. Rename libz.a to z.lib.
+4. Add the library z.lib to the project.
+5. Add the libc.lib library from the ObjectAda distribution to the project.
+6. Build the executable using test.adb as a main procedure.
+ How to use ZLib.Ada
+The source files test.adb and read.adb are small demo programs that show
+the main functionality of ZLib.Ada.
+The routines from the package specifications are commented.
+Homepage: http://zlib-ada.sourceforge.net/
+Author: Dmitriy Anisimkov <[email protected]>
+Contributors: Pascal Obry <[email protected]>, Steve Sangwine <[email protected]>
@@ -0,0 +1,463 @@
+-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
+-- The program has a few aims.
+-- 1. Test ZLib.Ada95 thick binding functionality.
+-- 2. Show the example of use main functionality of the ZLib.Ada95 binding.
+-- 3. Build this program automatically compile all ZLib.Ada95 packages under
+-- GNAT Ada95 compiler.
+with ZLib.Streams;
+with Ada.Streams.Stream_IO;
+with Ada.Calendar;
+procedure Test is
+ use Stream_IO;
+ File_Size : Count := 100_000;
+ -- ZLib.None;
+ -- ZLib.Auto;
+ -- ZLib.GZip;
+ -- Do not use Header other then Default in ZLib versions 1.1.4
+ -- and older.
+ Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
+ Init_Random : constant := 10;
+ In_File_Name : constant String := "testzlib.in";
+ -- Name of the input file
+ Z_File_Name : constant String := "testzlib.zlb";
+ -- Name of the compressed file.
+ Out_File_Name : constant String := "testzlib.out";
+ -- Name of the decompressed file.
+ File_In : File_Type;
+ File_Out : File_Type;
+ File_Back : File_Type;
+ File_Z : ZLib.Streams.Stream_Type;
+ Time_Stamp : Ada.Calendar.Time;
+ procedure Generate_File;
+ -- Generate file of spetsified size with some random data.
+ -- The random data is repeatable, for the good compression.
+ procedure Compare_Streams
+ (Left, Right : in out Root_Stream_Type'Class);
+ -- The procedure compearing data in 2 streams.
+ -- It is for compare data before and after compression/decompression.
+ procedure Compare_Files (Left, Right : String);
+ -- Compare files. Based on the Compare_Streams.
+ procedure Copy_Streams
+ (Source, Target : in out Root_Stream_Type'Class;
+ Buffer_Size : in Stream_Element_Offset := 1024);
+ -- Copying data from one stream to another. It is for test stream
+ -- interface of the library.
+ procedure Data_In
+ -- ZLib.Generic_Translate.
+ procedure Data_Out (Item : in Stream_Element_Array);
+ -- writing data to the File_Out.
+ procedure Stamp;
+ -- Store the timestamp to the local variable.
+ procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
+ -- Print the time statistic with the message.
+ procedure Translate is new ZLib.Generic_Translate
+ (Data_In => Data_In,
+ Data_Out => Data_Out);
+ -- This procedure is moving data from File_In to File_Out
+ -- with compression or decompression, depend on initialization of
+ -- Filter parameter.
+ -------------------
+ -- Compare_Files --
+ procedure Compare_Files (Left, Right : String) is
+ Left_File, Right_File : File_Type;
+ Open (Left_File, In_File, Left);
+ Open (Right_File, In_File, Right);
+ Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
+ Close (Left_File);
+ Close (Right_File);
+ end Compare_Files;
+ ---------------------
+ -- Compare_Streams --
+ (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
+ Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
+ Left_Last, Right_Last : Stream_Element_Offset;
+ Read (Left, Left_Buffer, Left_Last);
+ Read (Right, Right_Buffer, Right_Last);
+ if Left_Last /= Right_Last then
+ Ada.Text_IO.Put_Line ("Compare error :"
+ & Stream_Element_Offset'Image (Left_Last)
+ & " /= "
+ & Stream_Element_Offset'Image (Right_Last));
+ raise Constraint_Error;
+ elsif Left_Buffer (0 .. Left_Last)
+ /= Right_Buffer (0 .. Right_Last)
+ then
+ Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
+ exit when Left_Last < Left_Buffer'Last;
+ end Compare_Streams;
+ ------------------
+ -- Copy_Streams --
+ (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
+ Buffer_Size : in Stream_Element_Offset := 1024)
+ Buffer : Stream_Element_Array (1 .. Buffer_Size);
+ Read (Source, Buffer, Last);
+ Write (Target, Buffer (1 .. Last));
+ end Copy_Streams;
+ -- Data_In --
+ Read (File_In, Item, Last);
+ end Data_In;
+ --------------
+ -- Data_Out --
+ procedure Data_Out (Item : in Stream_Element_Array) is
+ Write (File_Out, Item);
+ end Data_Out;
+ -- Generate_File --
+ procedure Generate_File is
+ Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
+ Buffer_Count : constant Count := File_Size / Buffer'Length;
+ -- Number of same buffers in the packet.
+ Density : constant Count := 30; -- from 0 to Buffer'Length - 2;
+ procedure Fill_Buffer (J, D : in Count);
+ -- Change the part of the buffer.
+ -- Fill_Buffer --
+ procedure Fill_Buffer (J, D : in Count) is
+ for K in 0 .. D loop
+ Buffer
+ (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
+ := Random_Elements.Random (Gen);
+ end Fill_Buffer;
+ Create (File_In, Out_File, In_File_Name);
+ Fill_Buffer (1, Buffer'Length - 2);
+ for J in 1 .. Buffer_Count loop
+ Write (File_In, Buffer);
+ Fill_Buffer (J, Density);
+ -- fill remain size.
+ Write
+ (File_In,
+ (1 .. Stream_Element_Offset
+ (File_Size - Buffer'Length * Buffer_Count)));
+ Flush (File_In);
+ Close (File_In);
+ end Generate_File;
+ -- Print_Statistic --
+ procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
+ use Ada.Calendar;
+ use Ada.Text_IO;
+ package Count_IO is new Integer_IO (ZLib.Count);
+ Curr_Dur : Duration := Clock - Time_Stamp;
+ Put (Msg);
+ Set_Col (20);
+ Ada.Text_IO.Put ("size =");
+ Count_IO.Put
+ (Data_Size,
+ Width => Stream_IO.Count'Image (File_Size)'Length);
+ Put_Line (" duration =" & Duration'Image (Curr_Dur));
+ end Print_Statistic;
+ -- Stamp --
+ procedure Stamp is
+ Time_Stamp := Ada.Calendar.Clock;
+ end Stamp;
+ Generate_File;
+ Ada.Text_IO.Put_Line ("Level ="
+ -- Test generic interface.
+ Open (File_In, In_File, In_File_Name);
+ Create (File_Out, Out_File, Z_File_Name);
+ Stamp;
+ (Filter => Filter,
+ Level => Level,
+ Strategy => Strategy,
+ Translate (Filter);
+ Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
+ Close (File_Out);
+ Open (File_In, In_File, Z_File_Name);
+ Create (File_Out, Out_File, Out_File_Name);
+ -- Inflate using generic instantiation.
+ ZLib.Inflate_Init (Filter, Header => Header);
+ Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
+ Compare_Files (In_File_Name, Out_File_Name);
+ -- Test stream interface.
+ -- Compress to the back stream.
+ Create (File_Back, Out_File, Z_File_Name);
+ ZLib.Streams.Create
+ (Stream => File_Z,
+ Mode => ZLib.Streams.Out_Stream,
+ Back => ZLib.Streams.Stream_Access
+ (Stream (File_Back)),
+ Back_Compressed => True,
+ Copy_Streams
+ (Source => Stream (File_In).all,
+ Target => File_Z);
+ -- Flushing internal buffers to the back stream.
+ ZLib.Streams.Flush (File_Z, ZLib.Finish);
+ Print_Statistic ("Write compress",
+ ZLib.Streams.Write_Total_Out (File_Z));
+ ZLib.Streams.Close (File_Z);
+ Close (File_Back);
+ -- Compare reading from original file and from
+ -- decompression stream.
+ Open (File_Back, In_File, Z_File_Name);
+ Mode => ZLib.Streams.In_Stream,
+ Compare_Streams (Stream (File_In).all, File_Z);
+ Print_Statistic ("Read decompress",
+ ZLib.Streams.Read_Total_Out (File_Z));
+ -- Compress by reading from compression stream.
+ Open (File_Back, In_File, In_File_Name);
+ Back_Compressed => False,
+ (Source => File_Z,
+ Target => Stream (File_Out).all);
+ Print_Statistic ("Read compress",
+ -- Decompress to decompression stream.
+ Create (File_Back, Out_File, Out_File_Name);
+ Print_Statistic ("Write decompress",
+ Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
+end Test;
@@ -0,0 +1,225 @@
+-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
+with Ada.Unchecked_Deallocation;
+package body ZLib.Streams is
+ -- Close --
+ procedure Close (Stream : in out Stream_Type) is
+ procedure Free is new Ada.Unchecked_Deallocation
+ (Stream_Element_Array, Buffer_Access);
+ if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
+ -- We should flush the data written by the writer.
+ Flush (Stream, Finish);
+ Close (Stream.Writer);
+ if Stream.Mode = In_Stream or Stream.Mode = Duplex then
+ Close (Stream.Reader);
+ Free (Stream.Buffer);
+ end Close;
+ ------------
+ -- Create --
+ procedure Create
+ (Stream : out Stream_Type;
+ Mode : in Stream_Mode;
+ Back : in Stream_Access;
+ Back_Compressed : in Boolean;
+ Level : in Compression_Level := Default_Compression;
+ Strategy : in Strategy_Type := Default_Strategy;
+ Header : in Header_Type := Default;
+ Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size;
+ Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size)
+ subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
+ procedure Init_Filter
+ (Filter : in out Filter_Type;
+ Compress : in Boolean);
+ -- Init_Filter --
+ Compress : in Boolean) is
+ if Compress then
+ Deflate_Init
+ (Filter, Level, Strategy, Header => Header);
+ Inflate_Init (Filter, Header => Header);
+ end Init_Filter;
+ Stream.Back := Back;
+ Stream.Mode := Mode;
+ if Mode = Out_Stream or Mode = Duplex then
+ Init_Filter (Stream.Writer, Back_Compressed);
+ Stream.Buffer_Size := Write_Buffer_Size;
+ Stream.Buffer_Size := 0;
+ if Mode = In_Stream or Mode = Duplex then
+ Init_Filter (Stream.Reader, not Back_Compressed);
+ Stream.Buffer := new Buffer_Subtype;
+ Stream.Rest_First := Stream.Buffer'Last + 1;
+ Stream.Rest_Last := Stream.Buffer'Last;
+ end Create;
+ -- Flush --
+ procedure Flush
+ (Stream : in out Stream_Type;
+ Mode : in Flush_Mode := Sync_Flush)
+ Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
+ Flush (Stream.Writer, Buffer, Last, Mode);
+ Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
+ end Flush;
+ -- Is_Open --
+ function Is_Open (Stream : Stream_Type) return Boolean is
+ return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
+ end Is_Open;
+ Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset)
+ Ada.Streams.Read (Stream.Back.all, Item, Last);
+ (Read => Read,
+ Buffer => Stream.Buffer.all,
+ Rest_First => Stream.Rest_First,
+ Rest_Last => Stream.Rest_Last);
+ Read (Stream.Reader, Item, Last);
+ -- Read_Total_In --
+ function Read_Total_In (Stream : in Stream_Type) return Count is
+ return Total_In (Stream.Reader);
+ end Read_Total_In;
+ --------------------
+ -- Read_Total_Out --
+ function Read_Total_Out (Stream : in Stream_Type) return Count is
+ return Total_Out (Stream.Reader);
+ end Read_Total_Out;
+ -- Write --
+ procedure Write
+ Item : in Stream_Element_Array)
+ procedure Write (Item : in Stream_Element_Array);
+ procedure Write (Item : in Stream_Element_Array) is
+ Ada.Streams.Write (Stream.Back.all, Item);
+ end Write;
+ procedure Write is new ZLib.Write
+ (Write => Write,
+ Buffer_Size => Stream.Buffer_Size);
+ Write (Stream.Writer, Item, No_Flush);
+ -- Write_Total_In --
+ function Write_Total_In (Stream : in Stream_Type) return Count is
+ return Total_In (Stream.Writer);
+ end Write_Total_In;
+ -- Write_Total_Out --
+ function Write_Total_Out (Stream : in Stream_Type) return Count is
+ return Total_Out (Stream.Writer);
+ end Write_Total_Out;
+end ZLib.Streams;
@@ -0,0 +1,114 @@
+-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
+package ZLib.Streams is
+ type Stream_Mode is (In_Stream, Out_Stream, Duplex);
+ type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
+ type Stream_Type is
+ new Ada.Streams.Root_Stream_Type with private;
+ Item : out Ada.Streams.Stream_Element_Array;
+ Item : in Ada.Streams.Stream_Element_Array);
+ Mode : in Flush_Mode := Sync_Flush);
+ -- Flush the written data to the back stream,
+ -- all data placed to the compressor is flushing to the Back stream.
+ -- Should not be used until necessary, because it is decreasing
+ -- compression.
+ function Read_Total_In (Stream : in Stream_Type) return Count;
+ pragma Inline (Read_Total_In);
+ -- Return total number of bytes read from back stream so far.
+ function Read_Total_Out (Stream : in Stream_Type) return Count;
+ pragma Inline (Read_Total_Out);
+ -- Return total number of bytes read so far.
+ function Write_Total_In (Stream : in Stream_Type) return Count;
+ pragma Inline (Write_Total_In);
+ -- Return total number of bytes written so far.
+ function Write_Total_Out (Stream : in Stream_Type) return Count;
+ pragma Inline (Write_Total_Out);
+ -- Return total number of bytes written to the back stream.
+ := Default_Buffer_Size);
+ -- Create the Comression/Decompression stream.
+ -- If mode is In_Stream then Write operation is disabled.
+ -- If mode is Out_Stream then Read operation is disabled.
+ -- If Back_Compressed is true then
+ -- Data written to the Stream is compressing to the Back stream
+ -- and data read from the Stream is decompressed data from the Back stream.
+ -- If Back_Compressed is false then
+ -- Data written to the Stream is decompressing to the Back stream
+ -- and data read from the Stream is compressed data from the Back stream.
+ -- !!! When the Need_Header is False ZLib-Ada is using undocumented
+ -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
+ function Is_Open (Stream : Stream_Type) return Boolean;
+ procedure Close (Stream : in out Stream_Type);
+private
+ type Buffer_Access is access all Stream_Element_Array;
+ type Stream_Type
+ is new Root_Stream_Type with
+ record
+ Mode : Stream_Mode;
+ Buffer : Buffer_Access;
+ Rest_First : Stream_Element_Offset;
+ Rest_Last : Stream_Element_Offset;
+ -- Buffer for Read operation.
+ -- We need to have this buffer in the record
+ -- because not all read data from back stream
+ -- could be processed during the read operation.
+ Buffer_Size : Stream_Element_Offset;
+ -- Buffer size for write operation.
+ -- We do not need to have this buffer
+ -- in the record because all data could be
+ -- processed in the write operation.
+ Back : Stream_Access;
+ Reader : Filter_Type;
+ Writer : Filter_Type;
+ end record;
@@ -0,0 +1,141 @@
+-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
+package body ZLib.Thin is
+ ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
+ Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
+ -- Avail_In --
+ function Avail_In (Strm : in Z_Stream) return UInt is
+ return Strm.Avail_In;
+ end Avail_In;
+ ---------------
+ -- Avail_Out --
+ function Avail_Out (Strm : in Z_Stream) return UInt is
+ return Strm.Avail_Out;
+ end Avail_Out;
+ -- Deflate_Init --
+ function Deflate_Init
+ (strm : Z_Streamp;
+ level : Int;
+ method : Int;
+ windowBits : Int;
+ memLevel : Int;
+ strategy : Int)
+ return Int is
+ return deflateInit2
+ (strm,
+ level,
+ method,
+ windowBits,
+ memLevel,
+ strategy,
+ ZLIB_VERSION,
+ Z_Stream_Size);
+ end Deflate_Init;
+ -- Inflate_Init --
+ function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
+ return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
+ end Inflate_Init;
+ ------------------------
+ -- Last_Error_Message --
+ function Last_Error_Message (Strm : in Z_Stream) return String is
+ use Interfaces.C.Strings;
+ if Strm.msg = Null_Ptr then
+ return "";
+ return Value (Strm.msg);
+ end Last_Error_Message;
+ -- Set_In --
+ procedure Set_In
+ (Strm : in out Z_Stream;
+ Buffer : in Voidp;
+ Size : in UInt) is
+ Strm.Next_In := Buffer;
+ Strm.Avail_In := Size;
+ end Set_In;
+ -- Set_Mem_Func --
+ procedure Set_Mem_Func
+ Opaque : in Voidp;
+ Alloc : in alloc_func;
+ Free : in free_func) is
+ Strm.opaque := Opaque;
+ Strm.zalloc := Alloc;
+ Strm.zfree := Free;
+ end Set_Mem_Func;
+ -- Set_Out --
+ procedure Set_Out
+ Strm.Next_Out := Buffer;
+ Strm.Avail_Out := Size;
+ end Set_Out;
+ -- Total_In --
+ function Total_In (Strm : in Z_Stream) return ULong is
+ return Strm.Total_In;
+ end Total_In;
+ -- Total_Out --
+ function Total_Out (Strm : in Z_Stream) return ULong is
+ return Strm.Total_Out;
+ end Total_Out;
+end ZLib.Thin;
@@ -0,0 +1,450 @@
+-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
+with Interfaces.C.Strings;
+with System;
+private package ZLib.Thin is
+ -- From zconf.h
+ MAX_MEM_LEVEL : constant := 9; -- zconf.h:105
+ -- zconf.h:105
+ MAX_WBITS : constant := 15; -- zconf.h:115
+ -- 32K LZ77 window
+ -- zconf.h:115
+ SEEK_SET : constant := 8#0000#; -- zconf.h:244
+ -- Seek from beginning of file.
+ -- zconf.h:244
+ SEEK_CUR : constant := 1; -- zconf.h:245
+ -- Seek from current position.
+ -- zconf.h:245
+ SEEK_END : constant := 2; -- zconf.h:246
+ -- Set file pointer to EOF plus "offset"
+ -- zconf.h:246
+ type Byte is new Interfaces.C.unsigned_char; -- 8 bits
+ -- zconf.h:214
+ type UInt is new Interfaces.C.unsigned; -- 16 bits or more
+ -- zconf.h:216
+ type Int is new Interfaces.C.int;
+ type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
+ -- zconf.h:217
+ subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
+ type ULong_Access is access ULong;
+ type Int_Access is access Int;
+ subtype Voidp is System.Address; -- zconf.h:232
+ subtype Byte_Access is Voidp;
+ Nul : constant Voidp := System.Null_Address;
+ -- end from zconf
+ Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
+ -- zlib.h:125
+ Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126
+ -- will be removed, use
+ -- Z_SYNC_FLUSH instead
+ -- zlib.h:126
+ Z_SYNC_FLUSH : constant := 2; -- zlib.h:127
+ -- zlib.h:127
+ Z_FULL_FLUSH : constant := 3; -- zlib.h:128
+ -- zlib.h:128
+ Z_FINISH : constant := 4; -- zlib.h:129
+ -- zlib.h:129
+ Z_OK : constant := 8#0000#; -- zlib.h:132
+ -- zlib.h:132
+ Z_STREAM_END : constant := 1; -- zlib.h:133
+ -- zlib.h:133
+ Z_NEED_DICT : constant := 2; -- zlib.h:134
+ -- zlib.h:134
+ Z_ERRNO : constant := -1; -- zlib.h:135
+ -- zlib.h:135
+ Z_STREAM_ERROR : constant := -2; -- zlib.h:136
+ -- zlib.h:136
+ Z_DATA_ERROR : constant := -3; -- zlib.h:137
+ -- zlib.h:137
+ Z_MEM_ERROR : constant := -4; -- zlib.h:138
+ -- zlib.h:138
+ Z_BUF_ERROR : constant := -5; -- zlib.h:139
+ -- zlib.h:139
+ Z_VERSION_ERROR : constant := -6; -- zlib.h:140
+ -- zlib.h:140
+ Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145
+ -- zlib.h:145
+ Z_BEST_SPEED : constant := 1; -- zlib.h:146
+ -- zlib.h:146
+ Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147
+ -- zlib.h:147
+ Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148
+ -- zlib.h:148
+ Z_FILTERED : constant := 1; -- zlib.h:151
+ -- zlib.h:151
+ Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152
+ -- zlib.h:152
+ Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153
+ -- zlib.h:153
+ Z_BINARY : constant := 8#0000#; -- zlib.h:156
+ -- zlib.h:156
+ Z_ASCII : constant := 1; -- zlib.h:157
+ -- zlib.h:157
+ Z_UNKNOWN : constant := 2; -- zlib.h:158
+ -- zlib.h:158
+ Z_DEFLATED : constant := 8; -- zlib.h:161
+ -- zlib.h:161
+ Z_NULL : constant := 8#0000#; -- zlib.h:164
+ -- for initializing zalloc, zfree, opaque
+ -- zlib.h:164
+ type gzFile is new Voidp; -- zlib.h:646
+ type Z_Stream is private;
+ type Z_Streamp is access all Z_Stream; -- zlib.h:89
+ type alloc_func is access function
+ (Opaque : Voidp;
+ Items : UInt;
+ Size : UInt)
+ return Voidp; -- zlib.h:63
+ type free_func is access procedure (opaque : Voidp; address : Voidp);
+ function zlibVersion return Chars_Ptr;
+ function Deflate (strm : Z_Streamp; flush : Int) return Int;
+ function DeflateEnd (strm : Z_Streamp) return Int;
+ function Inflate (strm : Z_Streamp; flush : Int) return Int;
+ function InflateEnd (strm : Z_Streamp) return Int;
+ function deflateSetDictionary
+ dictionary : Byte_Access;
+ dictLength : UInt)
+ return Int;
+ function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
+ -- zlib.h:478
+ function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
+ function deflateParams
+ return Int; -- zlib.h:506
+ function inflateSetDictionary
+ return Int; -- zlib.h:548
+ function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565
+ function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580
+ function compress
+ (dest : Byte_Access;
+ destLen : ULong_Access;
+ source : Byte_Access;
+ sourceLen : ULong)
+ return Int; -- zlib.h:601
+ function compress2
+ sourceLen : ULong;
+ level : Int)
+ return Int; -- zlib.h:615
+ function uncompress
+ function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
+ function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
+ function gzsetparams
+ (file : gzFile;
+ function gzread
+ buf : Voidp;
+ len : UInt)
+ function gzwrite
+ (file : in gzFile;
+ buf : in Voidp;
+ len : in UInt)
+ function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
+ function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
+ function gzgets
+ buf : Chars_Ptr;
+ len : Int)
+ return Chars_Ptr;
+ function gzputc (file : gzFile; char : Int) return Int;
+ function gzgetc (file : gzFile) return Int;
+ function gzflush (file : gzFile; flush : Int) return Int;
+ function gzseek
+ offset : Int;
+ whence : Int)
+ function gzrewind (file : gzFile) return Int;
+ function gztell (file : gzFile) return Int;
+ function gzeof (file : gzFile) return Int;
+ function gzclose (file : gzFile) return Int;
+ function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
+ function adler32
+ (adler : ULong;
+ buf : Byte_Access;
+ return ULong;
+ function crc32
+ (crc : ULong;
+ function deflateInit
+ version : Chars_Ptr;
+ stream_size : Int)
+ function deflateInit2
+ strategy : Int;
+ pragma Inline (Deflate_Init);
+ function inflateInit
+ function inflateInit2
+ (strm : in Z_Streamp;
+ windowBits : in Int;
+ version : in Chars_Ptr;
+ stream_size : in Int)
+ function inflateBackInit
+ window : in Byte_Access;
+ -- Size of window have to be 2**windowBits.
+ function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
+ pragma Inline (Inflate_Init);
+ function zError (err : Int) return Chars_Ptr;
+ function inflateSyncPoint (z : Z_Streamp) return Int;
+ function get_crc_table return ULong_Access;
+ -- Interface to the available fields of the z_stream structure.
+ -- The application must update next_in and avail_in when avail_in has
+ -- dropped to zero. It must update next_out and avail_out when avail_out
+ -- has dropped to zero. The application must initialize zalloc, zfree and
+ -- opaque before calling the init function.
+ Size : in UInt);
+ pragma Inline (Set_In);
+ pragma Inline (Set_Out);
+ Free : in free_func);
+ pragma Inline (Set_Mem_Func);
+ function Last_Error_Message (Strm : in Z_Stream) return String;
+ pragma Inline (Last_Error_Message);
+ function Avail_Out (Strm : in Z_Stream) return UInt;
+ pragma Inline (Avail_Out);
+ function Avail_In (Strm : in Z_Stream) return UInt;
+ pragma Inline (Avail_In);
+ function Total_In (Strm : in Z_Stream) return ULong;
+ pragma Inline (Total_In);
+ function Total_Out (Strm : in Z_Stream) return ULong;
+ pragma Inline (Total_Out);
+ function inflateCopy
+ (dest : in Z_Streamp;
+ Source : in Z_Streamp)
+ function compressBound (Source_Len : in ULong) return ULong;
+ function deflateBound
+ (Strm : in Z_Streamp;
+ Source_Len : in ULong)
+ function gzungetc (C : in Int; File : in gzFile) return Int;
+ function zlibCompileFlags return ULong;
+ type Z_Stream is record -- zlib.h:68
+ Next_In : Voidp := Nul; -- next input byte
+ Avail_In : UInt := 0; -- number of bytes available at next_in
+ Total_In : ULong := 0; -- total nb of input bytes read so far
+ Next_Out : Voidp := Nul; -- next output byte should be put there
+ Avail_Out : UInt := 0; -- remaining free space at next_out
+ Total_Out : ULong := 0; -- total nb of bytes output so far
+ msg : Chars_Ptr; -- last error message, NULL if no error
+ state : Voidp; -- not visible by applications
+ zalloc : alloc_func := null; -- used to allocate the internal state
+ zfree : free_func := null; -- used to free the internal state
+ opaque : Voidp; -- private data object passed to
+ -- zalloc and zfree
+ data_type : Int; -- best guess about the data type:
+ -- ascii or binary
+ adler : ULong; -- adler32 value of the uncompressed
+ -- data
+ reserved : ULong; -- reserved for future use
+ pragma Convention (C, Z_Stream);
+ pragma Import (C, zlibVersion, "zlibVersion");
+ pragma Import (C, Deflate, "deflate");
+ pragma Import (C, DeflateEnd, "deflateEnd");
+ pragma Import (C, Inflate, "inflate");
+ pragma Import (C, InflateEnd, "inflateEnd");
+ pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
+ pragma Import (C, deflateCopy, "deflateCopy");
+ pragma Import (C, deflateReset, "deflateReset");
+ pragma Import (C, deflateParams, "deflateParams");
+ pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
+ pragma Import (C, inflateSync, "inflateSync");
+ pragma Import (C, inflateReset, "inflateReset");
+ pragma Import (C, compress, "compress");
+ pragma Import (C, compress2, "compress2");
+ pragma Import (C, uncompress, "uncompress");
+ pragma Import (C, gzopen, "gzopen");
+ pragma Import (C, gzdopen, "gzdopen");
+ pragma Import (C, gzsetparams, "gzsetparams");
+ pragma Import (C, gzread, "gzread");
+ pragma Import (C, gzwrite, "gzwrite");
+ pragma Import (C, gzprintf, "gzprintf");
+ pragma Import (C, gzputs, "gzputs");
+ pragma Import (C, gzgets, "gzgets");
+ pragma Import (C, gzputc, "gzputc");
+ pragma Import (C, gzgetc, "gzgetc");
+ pragma Import (C, gzflush, "gzflush");
+ pragma Import (C, gzseek, "gzseek");
+ pragma Import (C, gzrewind, "gzrewind");
+ pragma Import (C, gztell, "gztell");
+ pragma Import (C, gzeof, "gzeof");
+ pragma Import (C, gzclose, "gzclose");
+ pragma Import (C, gzerror, "gzerror");
+ pragma Import (C, adler32, "adler32");
+ pragma Import (C, crc32, "crc32");
+ pragma Import (C, deflateInit, "deflateInit_");
+ pragma Import (C, inflateInit, "inflateInit_");
+ pragma Import (C, deflateInit2, "deflateInit2_");
+ pragma Import (C, inflateInit2, "inflateInit2_");
+ pragma Import (C, zError, "zError");
+ pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
+ pragma Import (C, get_crc_table, "get_crc_table");
+ -- since zlib 1.2.0:
+ pragma Import (C, inflateCopy, "inflateCopy");
+ pragma Import (C, compressBound, "compressBound");
+ pragma Import (C, deflateBound, "deflateBound");
+ pragma Import (C, gzungetc, "gzungetc");
+ pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
+ pragma Import (C, inflateBackInit, "inflateBackInit_");
+ -- I stopped binding the inflateBack routines, because realize that
+ -- it does not support zlib and gzip headers for now, and have no
+ -- symmetric deflateBack routines.
+ -- ZLib-Ada is symmetric regarding deflate/inflate data transformation
+ -- and has a similar generic callback interface for the
+ -- deflate/inflate transformation based on the regular Deflate/Inflate
+ -- routines.
+ -- pragma Import (C, inflateBack, "inflateBack");
+ -- pragma Import (C, inflateBackEnd, "inflateBackEnd");
@@ -0,0 +1,701 @@
+-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
+with Ada.Unchecked_Conversion;
+with ZLib.Thin;
+package body ZLib is
+ use type Thin.Int;
+ type Z_Stream is new Thin.Z_Stream;
+ type Return_Code_Enum is
+ (OK,
+ STREAM_END,
+ NEED_DICT,
+ ERRNO,
+ STREAM_ERROR,
+ DATA_ERROR,
+ MEM_ERROR,
+ BUF_ERROR,
+ VERSION_ERROR);
+ type Flate_Step_Function is access
+ function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
+ pragma Convention (C, Flate_Step_Function);
+ type Flate_End_Function is access
+ function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
+ pragma Convention (C, Flate_End_Function);
+ type Flate_Type is record
+ Step : Flate_Step_Function;
+ Done : Flate_End_Function;
+ subtype Footer_Array is Stream_Element_Array (1 .. 8);
+ Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
+ := (16#1f#, 16#8b#, -- Magic header
+ 16#08#, -- Z_DEFLATED
+ 16#00#, -- Flags
+ 16#00#, 16#00#, 16#00#, 16#00#, -- Time
+ 16#00#, -- XFlags
+ 16#03# -- OS code
+ );
+ -- The simplest gzip header is not for informational, but just for
+ -- gzip format compatibility.
+ -- Note that some code below is using assumption
+ -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make
+ -- Simple_GZip_Header'Last <= Footer_Array'Last.
+ Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
+ := (0 => OK,
+ 1 => STREAM_END,
+ 2 => NEED_DICT,
+ -1 => ERRNO,
+ -2 => STREAM_ERROR,
+ -3 => DATA_ERROR,
+ -4 => MEM_ERROR,
+ -5 => BUF_ERROR,
+ -6 => VERSION_ERROR);
+ Flate : constant array (Boolean) of Flate_Type
+ := (True => (Step => Thin.Deflate'Access,
+ Done => Thin.DeflateEnd'Access),
+ False => (Step => Thin.Inflate'Access,
+ Done => Thin.InflateEnd'Access));
+ Flush_Finish : constant array (Boolean) of Flush_Mode
+ := (True => Finish, False => No_Flush);
+ procedure Raise_Error (Stream : in Z_Stream);
+ pragma Inline (Raise_Error);
+ procedure Raise_Error (Message : in String);
+ procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
+ (Z_Stream, Z_Stream_Access);
+ function To_Thin_Access is new Ada.Unchecked_Conversion
+ (Z_Stream_Access, Thin.Z_Streamp);
+ procedure Translate_GZip
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode);
+ -- Separate translate routine for make gzip header.
+ procedure Translate_Auto
+ -- translate routine without additional headers.
+ -- Check_Error --
+ procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
+ if Code /= Thin.Z_OK then
+ Raise_Error
+ (Return_Code_Enum'Image (Return_Code (Code))
+ & ": " & Last_Error_Message (Stream));
+ end Check_Error;
+ procedure Close
+ Ignore_Error : in Boolean := False)
+ Code : Thin.Int;
+ if not Ignore_Error and then not Is_Open (Filter) then
+ raise Status_Error;
+ Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
+ if Ignore_Error or else Code = Thin.Z_OK then
+ Free (Filter.Strm);
+ Error_Message : constant String
+ := Last_Error_Message (Filter.Strm.all);
+ Ada.Exceptions.Raise_Exception
+ (ZLib_Error'Identity,
+ Return_Code_Enum'Image (Return_Code (Code))
+ & ": " & Error_Message);
+ -- CRC32 --
+ function CRC32
+ (CRC : in Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array)
+ return Unsigned_32
+ use Thin;
+ return Unsigned_32 (crc32 (ULong (CRC),
+ Data'Address,
+ Data'Length));
+ end CRC32;
+ procedure CRC32
+ (CRC : in out Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array) is
+ CRC := CRC32 (CRC, Data);
+ procedure Deflate_Init
+ Method : in Compression_Method := Deflated;
+ Window_Bits : in Window_Bits_Type := Default_Window_Bits;
+ Memory_Level : in Memory_Level_Type := Default_Memory_Level;
+ Header : in Header_Type := Default)
+ Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+ if Is_Open (Filter) then
+ -- We allow ZLib to make header only in case of default header type.
+ -- Otherwise we would either do header by ourselfs, or do not do
+ -- header at all.
+ if Header = None or else Header = GZip then
+ Win_Bits := -Win_Bits;
+ -- For the GZip CRC calculation and make headers.
+ if Header = GZip then
+ Filter.CRC := 0;
+ Filter.Offset := Simple_GZip_Header'First;
+ Filter.Offset := Simple_GZip_Header'Last + 1;
+ Filter.Strm := new Z_Stream;
+ Filter.Compression := True;
+ Filter.Stream_End := False;
+ Filter.Header := Header;
+ if Thin.Deflate_Init
+ (To_Thin_Access (Filter.Strm),
+ Level => Thin.Int (Level),
+ method => Thin.Int (Method),
+ windowBits => Win_Bits,
+ memLevel => Thin.Int (Memory_Level),
+ strategy => Thin.Int (Strategy)) /= Thin.Z_OK
+ Raise_Error (Filter.Strm.all);
+ Flush : in Flush_Mode)
+ No_Data : Stream_Element_Array := (1 .. 0 => 0);
+ Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
+ -----------------------
+ -- Generic_Translate --
+ procedure Generic_Translate
+ (Filter : in out ZLib.Filter_Type;
+ In_Buffer_Size : in Integer := Default_Buffer_Size;
+ Out_Buffer_Size : in Integer := Default_Buffer_Size)
+ In_Buffer : Stream_Element_Array
+ (1 .. Stream_Element_Offset (In_Buffer_Size));
+ Out_Buffer : Stream_Element_Array
+ (1 .. Stream_Element_Offset (Out_Buffer_Size));
+ In_Last : Stream_Element_Offset;
+ In_First : Stream_Element_Offset;
+ Out_Last : Stream_Element_Offset;
+ Data_In (In_Buffer, Last);
+ In_First := In_Buffer'First;
+ In_Data => In_Buffer (In_First .. Last),
+ In_Last => In_Last,
+ Out_Data => Out_Buffer,
+ Out_Last => Out_Last,
+ Flush => Flush_Finish (Last < In_Buffer'First));
+ if Out_Buffer'First <= Out_Last then
+ Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
+ exit Main when Stream_End (Filter);
+ -- The end of in buffer.
+ exit when In_Last = Last;
+ In_First := In_Last + 1;
+ end Generic_Translate;
+ procedure Inflate_Init
+ procedure Check_Version;
+ -- Check the latest header types compatibility.
+ procedure Check_Version is
+ if Version <= "1.1.4" then
+ ("Inflate header type " & Header_Type'Image (Header)
+ & " incompatible with ZLib version " & Version);
+ end Check_Version;
+ case Header is
+ when None =>
+ Check_Version;
+ -- Inflate data without headers determined
+ -- by negative Win_Bits.
+ when GZip =>
+ -- Inflate gzip data defined by flag 16.
+ Win_Bits := Win_Bits + 16;
+ when Auto =>
+ -- Inflate with automatic detection
+ -- of gzip or native header defined by flag 32.
+ Win_Bits := Win_Bits + 32;
+ when Default => null;
+ end case;
+ Filter.Compression := False;
+ if Thin.Inflate_Init
+ (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
+ function Is_Open (Filter : in Filter_Type) return Boolean is
+ return Filter.Strm /= null;
+ -- Raise_Error --
+ procedure Raise_Error (Message : in String) is
+ Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
+ end Raise_Error;
+ procedure Raise_Error (Stream : in Z_Stream) is
+ Raise_Error (Last_Error_Message (Stream));
+ Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode := No_Flush)
+ Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
+ V_Flush : Flush_Mode := Flush;
+ pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
+ pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
+ if Rest_Last = Buffer'First - 1 then
+ V_Flush := Finish;
+ elsif Rest_First > Rest_Last then
+ Read (Buffer, Rest_Last);
+ Rest_First := Buffer'First;
+ if Rest_Last < Buffer'First then
+ In_Data => Buffer (Rest_First .. Rest_Last),
+ Out_Data => Item (Item_First .. Item'Last),
+ Out_Last => Last,
+ Flush => V_Flush);
+ Rest_First := In_Last + 1;
+ exit when Stream_End (Filter)
+ or else Last = Item'Last
+ or else (Last >= Item'First and then Allow_Read_Some);
+ Item_First := Last + 1;
+ ----------------
+ -- Stream_End --
+ function Stream_End (Filter : in Filter_Type) return Boolean is
+ if Filter.Header = GZip and Filter.Compression then
+ return Filter.Stream_End
+ and then Filter.Offset = Footer_Array'Last + 1;
+ return Filter.Stream_End;
+ end Stream_End;
+ function Total_In (Filter : in Filter_Type) return Count is
+ return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
+ function Total_Out (Filter : in Filter_Type) return Count is
+ return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
+ -- Translate --
+ procedure Translate
+ Flush : in Flush_Mode) is
+ if Filter.Header = GZip and then Filter.Compression then
+ Translate_GZip
+ In_Data => In_Data,
+ Out_Data => Out_Data,
+ Flush => Flush);
+ Translate_Auto
+ end Translate;
+ -- Translate_Auto --
+ if not Is_Open (Filter) then
+ if Out_Data'Length = 0 and then In_Data'Length = 0 then
+ Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
+ Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length);
+ Code := Flate (Filter.Compression).Step
+ Thin.Int (Flush));
+ if Code = Thin.Z_STREAM_END then
+ Filter.Stream_End := True;
+ Check_Error (Filter.Strm.all, Code);
+ In_Last := In_Data'Last
+ - Stream_Element_Offset (Avail_In (Filter.Strm.all));
+ Out_Last := Out_Data'Last
+ - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
+ end Translate_Auto;
+ -- Translate_GZip --
+ Out_First : Stream_Element_Offset;
+ procedure Add_Data (Data : in Stream_Element_Array);
+ -- Add data to stream from the Filter.Offset till necessary,
+ -- used for add gzip headr/footer.
+ procedure Put_32
+ (Item : in out Stream_Element_Array;
+ Data : in Unsigned_32);
+ pragma Inline (Put_32);
+ -- Add_Data --
+ procedure Add_Data (Data : in Stream_Element_Array) is
+ Data_First : Stream_Element_Offset renames Filter.Offset;
+ Data_Last : Stream_Element_Offset;
+ Data_Len : Stream_Element_Offset; -- -1
+ Out_Len : Stream_Element_Offset; -- -1
+ Out_First := Out_Last + 1;
+ if Data_First > Data'Last then
+ return;
+ Data_Len := Data'Last - Data_First;
+ Out_Len := Out_Data'Last - Out_First;
+ if Data_Len <= Out_Len then
+ Out_Last := Out_First + Data_Len;
+ Data_Last := Data'Last;
+ Out_Last := Out_Data'Last;
+ Data_Last := Data_First + Out_Len;
+ Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
+ Data_First := Data_Last + 1;
+ end Add_Data;
+ -- Put_32 --
+ Data : in Unsigned_32)
+ D : Unsigned_32 := Data;
+ for J in Item'First .. Item'First + 3 loop
+ Item (J) := Stream_Element (D and 16#FF#);
+ D := Shift_Right (D, 8);
+ end Put_32;
+ Out_Last := Out_Data'First - 1;
+ if not Filter.Stream_End then
+ Add_Data (Simple_GZip_Header);
+ Out_Data => Out_Data (Out_First .. Out_Data'Last),
+ CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
+ if Filter.Stream_End and then Out_Last <= Out_Data'Last then
+ -- This detection method would work only when
+ -- Simple_GZip_Header'Last > Footer_Array'Last
+ if Filter.Offset = Simple_GZip_Header'Last + 1 then
+ Filter.Offset := Footer_Array'First;
+ Footer : Footer_Array;
+ Put_32 (Footer, Filter.CRC);
+ Put_32 (Footer (Footer'First + 4 .. Footer'Last),
+ Unsigned_32 (Total_In (Filter)));
+ Add_Data (Footer);
+ end Translate_GZip;
+ -- Version --
+ function Version return String is
+ return Interfaces.C.Strings.Value (Thin.zlibVersion);
+ end Version;
+ Item : in Ada.Streams.Stream_Element_Array;
+ In_First : Stream_Element_Offset := Item'First;
+ if Item'Length = 0 and Flush = No_Flush then
+ In_Data => Item (In_First .. Item'Last),
+ Out_Data => Buffer,
+ if Out_Last >= Buffer'First then
+ Write (Buffer (1 .. Out_Last));
+ exit when In_Last = Item'Last or Stream_End (Filter);
+end ZLib;
@@ -0,0 +1,328 @@
+------------------------------------------------------------------------------
+-- This 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. --
+-- This 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 this library; if not, write to the Free Software Foundation, --
+-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
+-- As a special exception, if other files instantiate generics from this --
+-- unit, or you link this unit with other files to produce an executable, --
+-- this unit does not by itself cause the resulting executable to be --
+-- covered by the GNU General Public License. This exception does not --
+-- however invalidate any other reasons why the executable file might be --
+-- covered by the GNU Public License. --
+-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
+with Interfaces;
+package ZLib is
+ ZLib_Error : exception;
+ Status_Error : exception;
+ type Compression_Level is new Integer range -1 .. 9;
+ type Flush_Mode is private;
+ type Compression_Method is private;
+ type Window_Bits_Type is new Integer range 8 .. 15;
+ type Memory_Level_Type is new Integer range 1 .. 9;
+ type Unsigned_32 is new Interfaces.Unsigned_32;
+ type Strategy_Type is private;
+ type Header_Type is (None, Auto, Default, GZip);
+ -- Header type usage have a some limitation for inflate.
+ -- See comment for Inflate_Init.
+ subtype Count is Ada.Streams.Stream_Element_Count;
+ Default_Memory_Level : constant Memory_Level_Type := 8;
+ Default_Window_Bits : constant Window_Bits_Type := 15;
+ ----------------------------------
+ -- Compression method constants --
+ Deflated : constant Compression_Method;
+ -- Only one method allowed in this ZLib version
+ ---------------------------------
+ -- Compression level constants --
+ No_Compression : constant Compression_Level := 0;
+ Best_Speed : constant Compression_Level := 1;
+ Best_Compression : constant Compression_Level := 9;
+ Default_Compression : constant Compression_Level := -1;
+ --------------------------
+ -- Flush mode constants --
+ No_Flush : constant Flush_Mode;
+ -- Regular way for compression, no flush
+ Partial_Flush : constant Flush_Mode;
+ -- Will be removed, use Z_SYNC_FLUSH instead
+ Sync_Flush : constant Flush_Mode;
+ -- All pending output is flushed to the output buffer and the output
+ -- is aligned on a byte boundary, so that the decompressor can get all
+ -- input data available so far. (In particular avail_in is zero after the
+ -- call if enough output space has been provided before the call.)
+ -- Flushing may degrade compression for some compression algorithms and so
+ -- it should be used only when necessary.
+ Block_Flush : constant Flush_Mode;
+ -- Z_BLOCK requests that inflate() stop
+ -- if and when it get to the next deflate block boundary. When decoding the
+ -- zlib or gzip format, this will cause inflate() to return immediately
+ -- after the header and before the first block. When doing a raw inflate,
+ -- inflate() will go ahead and process the first block, and will return
+ -- when it gets to the end of that block, or when it runs out of data.
+ Full_Flush : constant Flush_Mode;
+ -- All output is flushed as with SYNC_FLUSH, and the compression state
+ -- is reset so that decompression can restart from this point if previous
+ -- compressed data has been damaged or if random access is desired. Using
+ -- Full_Flush too often can seriously degrade the compression.
+ Finish : constant Flush_Mode;
+ -- Just for tell the compressor that input data is complete.
+ -- Compression strategy constants --
+ -- RLE stategy could be used only in version 1.2.0 and later.
+ Filtered : constant Strategy_Type;
+ Huffman_Only : constant Strategy_Type;
+ RLE : constant Strategy_Type;
+ Default_Strategy : constant Strategy_Type;
+ Default_Buffer_Size : constant := 4096;
+ type Filter_Type is tagged limited private;
+ -- The filter is for compression and for decompression.
+ -- The usage of the type is depend of its initialization.
+ function Version return String;
+ pragma Inline (Version);
+ -- Return string representation of the ZLib version.
+ Header : in Header_Type := Default);
+ -- Compressor initialization.
+ -- When Header parameter is Auto or Default, then default zlib header
+ -- would be provided for compressed data.
+ -- When Header is GZip, then gzip header would be set instead of
+ -- default header.
+ -- When Header is None, no header would be set for compressed data.
+ -- Decompressor initialization.
+ -- Default header type mean that ZLib default header is expecting in the
+ -- input compressed stream.
+ -- Header type None mean that no header is expecting in the input stream.
+ -- GZip header type mean that GZip header is expecting in the
+ -- Auto header type mean that header type (GZip or Native) would be
+ -- detected automatically in the input stream.
+ -- Note that header types parameter values None, GZip and Auto are
+ -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
+ -- Deflate_Init is supporting all header types.
+ function Is_Open (Filter : in Filter_Type) return Boolean;
+ pragma Inline (Is_Open);
+ -- Is the filter opened for compression or decompression.
+ Ignore_Error : in Boolean := False);
+ -- Closing the compression or decompressor.
+ -- If stream is closing before the complete and Ignore_Error is False,
+ -- The exception would be raised.
+ generic
+ with procedure Data_In
+ with procedure Data_Out
+ (Item : in Ada.Streams.Stream_Element_Array);
+ Out_Buffer_Size : in Integer := Default_Buffer_Size);
+ -- Compress/decompress data fetch from Data_In routine and pass the result
+ -- to the Data_Out routine. User should provide Data_In and Data_Out
+ -- for compression/decompression data flow.
+ -- Compression or decompression depend on Filter initialization.
+ function Total_In (Filter : in Filter_Type) return Count;
+ -- Returns total number of input bytes read so far
+ function Total_Out (Filter : in Filter_Type) return Count;
+ -- Returns total number of bytes output so far
+ return Unsigned_32;
+ pragma Inline (CRC32);
+ -- Compute CRC32, it could be necessary for make gzip format
+ Data : in Ada.Streams.Stream_Element_Array);
+ -------------------------------------------------
+ -- Below is more complex low level routines. --
+ -- Compress/decompress the In_Data buffer and place the result into
+ -- Out_Data. In_Last is the index of last element from In_Data accepted by
+ -- the Filter. Out_Last is the last element of the received data from
+ -- Filter. To tell the filter that incoming data are complete put the
+ -- Flush parameter to Finish.
+ function Stream_End (Filter : in Filter_Type) return Boolean;
+ pragma Inline (Stream_End);
+ -- Return the true when the stream is complete.
+ pragma Inline (Flush);
+ -- Flushing the data from the compressor.
+ with procedure Write
+ -- User should provide this routine for accept
+ -- compressed/decompressed data.
+ Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ -- Buffer size for Write user routine.
+ Flush : in Flush_Mode := No_Flush);
+ -- Compress/Decompress data from Item to the generic parameter procedure
+ -- Write. Output buffer size could be set in Buffer_Size generic parameter.
+ with procedure Read
+ -- User should provide data for compression/decompression
+ -- thru this routine.
+ Buffer : in out Ada.Streams.Stream_Element_Array;
+ -- Buffer for keep remaining data from the previous
+ -- back read.
+ Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
+ -- Rest_First have to be initialized to Buffer'Last + 1
+ -- Rest_Last have to be initialized to Buffer'Last
+ -- before usage.
+ Allow_Read_Some : in Boolean := False;
+ -- Is it allowed to return Last < Item'Last before end of data.
+ -- Compress/Decompress data from generic parameter procedure Read to the
+ -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
+ -- indicators. If Allow_Read_Some is True, Read routines could return
+ -- Last < Item'Last only at end of stream.
+ pragma Assert (Ada.Streams.Stream_Element'Size = 8);
+ pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
+ type Flush_Mode is new Integer range 0 .. 5;
+ type Compression_Method is new Integer range 8 .. 8;
+ type Strategy_Type is new Integer range 0 .. 3;
+ No_Flush : constant Flush_Mode := 0;
+ Partial_Flush : constant Flush_Mode := 1;
+ Sync_Flush : constant Flush_Mode := 2;
+ Full_Flush : constant Flush_Mode := 3;
+ Finish : constant Flush_Mode := 4;
+ Block_Flush : constant Flush_Mode := 5;
+ Filtered : constant Strategy_Type := 1;
+ Huffman_Only : constant Strategy_Type := 2;
+ RLE : constant Strategy_Type := 3;
+ Default_Strategy : constant Strategy_Type := 0;
+ Deflated : constant Compression_Method := 8;
+ type Z_Stream;
+ type Z_Stream_Access is access all Z_Stream;
+ type Filter_Type is tagged limited record
+ Strm : Z_Stream_Access;
+ Compression : Boolean;
+ Stream_End : Boolean;
+ Header : Header_Type;
+ CRC : Unsigned_32;
+ -- Offset for gzip header/footer output.
@@ -0,0 +1,20 @@
+project Zlib is
+ for Languages use ("Ada");
+ for Source_Dirs use (".");
+ for Object_Dir use ".";
+ for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
+ package Compiler is
+ for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
+ end Compiler;
+ package Linker is
+ for Default_Switches ("ada") use ("-lz");
+ end Linker;
+ package Builder is
+ for Default_Switches ("ada") use ("-s", "-gnatQ");
+ end Builder;
+end Zlib;
@@ -0,0 +1,8 @@
+blast: blast.c blast.h
+ cc -DTEST -o blast blast.c
+test: blast
+ blast < test.pk | cmp - test.txt
+ rm -f blast blast.o
@@ -0,0 +1,4 @@
+Read blast.h for purpose and usage.
+Mark Adler
[email protected]
@@ -0,0 +1,466 @@
+/* blast.c
+ * Copyright (C) 2003, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in blast.h
+ * version 1.3, 24 Aug 2013
+ *
+ * blast.c decompresses data compressed by the PKWare Compression Library.
+ * This function provides functionality similar to the explode() function of
+ * the PKWare library, hence the name "blast".
+ * This decompressor is based on the excellent format description provided by
+ * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
+ * example Ben provided in the post is incorrect. The distance 110001 should
+ * instead be 111000. When corrected, the example byte stream becomes:
+ * 00 04 82 24 25 8f 80 7f
+ * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
+/*
+ * Change history:
+ * 1.0 12 Feb 2003 - First version
+ * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
+ * 1.2 24 Oct 2012 - Add note about using binary mode in stdio
+ * - Fix comparisons of differently signed integers
+ * 1.3 24 Aug 2013 - Return unused input from blast()
+ * - Fix test code to correctly report unused input
+ * - Enable the provision of initial input to blast()
+#include <stddef.h> /* for NULL */
+#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
+#include "blast.h" /* prototype for blast() */
+#define local static /* for local function definitions */
+#define MAXBITS 13 /* maximum code length */
+#define MAXWIN 4096 /* maximum window size */
+/* input and output state */
+struct state {
+ /* input state */
+ blast_in infun; /* input function provided by user */
+ void *inhow; /* opaque information passed to infun() */
+ unsigned char *in; /* next input location */
+ unsigned left; /* available input at in */
+ int bitbuf; /* bit buffer */
+ int bitcnt; /* number of bits in bit buffer */
+ /* input limit error return state for bits() and decode() */
+ jmp_buf env;
+ /* output state */
+ blast_out outfun; /* output function provided by user */
+ void *outhow; /* opaque information passed to outfun() */
+ unsigned next; /* index of next write location in out[] */
+ int first; /* true to check distances (for first 4K) */
+ unsigned char out[MAXWIN]; /* output buffer and sliding window */
+};
+ * Return need bits from the input stream. This always leaves less than
+ * eight bits in the buffer. bits() works properly for need == 0.
+ * Format notes:
+ * - Bits are stored in bytes from the least significant bit to the most
+ * significant bit. Therefore bits are dropped from the bottom of the bit
+ * buffer, using shift right, and new bytes are appended to the top of the
+ * bit buffer, using shift left.
+local int bits(struct state *s, int need)
+ int val; /* bit accumulator */
+ /* load at least need bits into val */
+ val = s->bitbuf;
+ while (s->bitcnt < need) {
+ if (s->left == 0) {
+ s->left = s->infun(s->inhow, &(s->in));
+ if (s->left == 0) longjmp(s->env, 1); /* out of input */
+ val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
+ s->left--;
+ s->bitcnt += 8;
+ /* drop need bits and update buffer, always zero to seven bits left */
+ s->bitbuf = val >> need;
+ s->bitcnt -= need;
+ /* return need bits, zeroing the bits above that */
+ return val & ((1 << need) - 1);
+ * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[]. The decoding process can be
+ * seen in the function decode() below.
+struct huffman {
+ short *count; /* number of symbols of each length */
+ short *symbol; /* canonically ordered symbols */
+ * Decode a code from the stream s using huffman table h. Return the symbol or
+ * a negative value if there is an error. If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -9 is returned after reading MAXBITS bits.
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ * a simple integer ordering of codes of the same lengths. Hence below the
+ * bits are pulled from the compressed data one at a time and used to
+ * build the code value reversed from what is in the stream in order to
+ * permit simple integer comparisons for decoding.
+ * - The first code for the shortest length is all ones. Subsequent codes of
+ * the same length are simply integer decrements of the previous code. When
+ * moving up a length, a one bit is appended to the code. For a complete
+ * code, the last code of the longest length will be all zeros. To support
+ * this ordering, the bits pulled during decoding are inverted to apply the
+ * more "natural" ordering starting with all zeros and incrementing.
+local int decode(struct state *s, struct huffman *h)
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+ int bitbuf; /* bits from stream */
+ int left; /* bits left in next or left to process */
+ short *next; /* next number of codes */
+ bitbuf = s->bitbuf;
+ left = s->bitcnt;
+ code = first = index = 0;
+ len = 1;
+ next = h->count + 1;
+ while (1) {
+ while (left--) {
+ code |= (bitbuf & 1) ^ 1; /* invert code */
+ bitbuf >>= 1;
+ count = *next++;
+ if (code < first + count) { /* if length len, return symbol */
+ s->bitbuf = bitbuf;
+ s->bitcnt = (s->bitcnt - len) & 7;
+ return h->symbol[index + (code - first)];
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ len++;
+ left = (MAXBITS+1) - len;
+ if (left == 0) break;
+ bitbuf = *(s->in)++;
+ if (left > 8) left = 8;
+ return -9; /* ran out of codes */
+ * Given a list of repeated code lengths rep[0..n-1], where each byte is a
+ * count (high four bits + 1) and a code length (low four bits), generate the
+ * list of code lengths. This compaction reduces the size of the object code.
+ * Then given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes. Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length. The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set. The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative. If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol. If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+local int construct(struct huffman *h, const unsigned char *rep, int n)
+ int symbol; /* current symbol when stepping through length[] */
+ int len; /* current length when stepping through h->count[] */
+ int left; /* number of possible codes left of current length */
+ short offs[MAXBITS+1]; /* offsets in symbol table for each length */
+ short length[256]; /* code lengths */
+ /* convert compact repeat counts into symbol bit length list */
+ symbol = 0;
+ len = *rep++;
+ left = (len >> 4) + 1;
+ len &= 15;
+ length[symbol++] = len;
+ } while (--left);
+ n = symbol;
+ /* count number of codes of each length */
+ for (len = 0; len <= MAXBITS; len++)
+ h->count[len] = 0;
+ for (symbol = 0; symbol < n; symbol++)
+ (h->count[length[symbol]])++; /* assumes lengths are within bounds */
+ if (h->count[0] == n) /* no codes! */
+ return 0; /* complete, but decode() will fail */
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1; /* one possible code of zero length */
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1; /* one more bit, double codes left */
+ left -= h->count[len]; /* deduct count from possible codes */
+ if (left < 0) return left; /* over-subscribed--return negative */
+ } /* left > 0 means incomplete */
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + h->count[len];
+ /*
+ * put symbols in table sorted by length, by symbol order within each
+ * length
+ if (length[symbol] != 0)
+ h->symbol[offs[length[symbol]]++] = symbol;
+ /* return zero for complete set, positive for incomplete set */
+ return left;
+ * Decode PKWare Compression Library stream.
+ * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
+ * byte is 4, 5, or 6 for the number of extra bits in the distance code.
+ * This is the base-2 logarithm of the dictionary size minus six.
+ * - Compressed data is a combination of literals and length/distance pairs
+ * terminated by an end code. Literals are either Huffman coded or
+ * uncoded bytes. A length/distance pair is a coded length followed by a
+ * coded distance to represent a string that occurs earlier in the
+ * uncompressed data that occurs again at the current location.
+ * - A bit preceding a literal or length/distance pair indicates which comes
+ * next, 0 for literals, 1 for length/distance.
+ * - If literals are uncoded, then the next eight bits are the literal, in the
+ * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly,
+ * no bit reversal is needed for either the length extra bits or the distance
+ * extra bits.
+ * - Literal bytes are simply written to the output. A length/distance pair is
+ * an instruction to copy previously uncompressed bytes to the output. The
+ * copy is from distance bytes back in the output stream, copying for length
+ * bytes.
+ * - Distances pointing before the beginning of the output data are not
+ * permitted.
+ * - Overlapped copies, where the length is greater than the distance, are
+ * allowed and common. For example, a distance of one and a length of 518
+ * simply copies the last byte 518 times. A distance of four and a length of
+ * twelve copies the last four bytes three times. A simple forward copy
+ * ignoring whether the length is greater than the distance or not implements
+ * this correctly.
+local int decomp(struct state *s)
+ int lit; /* true if literals are coded */
+ int dict; /* log2(dictionary size) - 6 */
+ int symbol; /* decoded symbol, extra bits for distance */
+ int len; /* length for copy */
+ unsigned dist; /* distance for copy */
+ int copy; /* copy counter */
+ unsigned char *from, *to; /* copy pointers */
+ static int virgin = 1; /* build tables once */
+ static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
+ static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
+ static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
+ static struct huffman litcode = {litcnt, litsym}; /* length code */
+ static struct huffman lencode = {lencnt, lensym}; /* length code */
+ static struct huffman distcode = {distcnt, distsym};/* distance code */
+ /* bit lengths of literal codes */
+ static const unsigned char litlen[] = {
+ 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
+ 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
+ 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
+ 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
+ 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
+ 44, 173};
+ /* bit lengths of length codes 0..15 */
+ static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
+ /* bit lengths of distance codes 0..63 */
+ static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
+ static const short base[16] = { /* base for length codes */
+ 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
+ static const char extra[16] = { /* extra bits for length codes */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+ /* set up decoding tables (once--might not be thread-safe) */
+ if (virgin) {
+ construct(&litcode, litlen, sizeof(litlen));
+ construct(&lencode, lenlen, sizeof(lenlen));
+ construct(&distcode, distlen, sizeof(distlen));
+ virgin = 0;
+ /* read header */
+ lit = bits(s, 8);
+ if (lit > 1) return -1;
+ dict = bits(s, 8);
+ if (dict < 4 || dict > 6) return -2;
+ /* decode literals and length/distance pairs */
+ if (bits(s, 1)) {
+ /* get length */
+ symbol = decode(s, &lencode);
+ len = base[symbol] + bits(s, extra[symbol]);
+ if (len == 519) break; /* end code */
+ /* get distance */
+ symbol = len == 2 ? 2 : dict;
+ dist = decode(s, &distcode) << symbol;
+ dist += bits(s, symbol);
+ dist++;
+ if (s->first && dist > s->next)
+ return -3; /* distance too far back */
+ /* copy length bytes from distance bytes back */
+ to = s->out + s->next;
+ from = to - dist;
+ copy = MAXWIN;
+ if (s->next < dist) {
+ from += copy;
+ copy = dist;
+ copy -= s->next;
+ if (copy > len) copy = len;
+ len -= copy;
+ s->next += copy;
+ *to++ = *from++;
+ } while (--copy);
+ if (s->next == MAXWIN) {
+ if (s->outfun(s->outhow, s->out, s->next)) return 1;
+ s->next = 0;
+ s->first = 0;
+ } while (len != 0);
+ else {
+ /* get literal and write it */
+ symbol = lit ? decode(s, &litcode) : bits(s, 8);
+ s->out[s->next++] = symbol;
+ } while (1);
+/* See comments in blast.h */
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
+ unsigned *left, unsigned char **in)
+ struct state s; /* input/output state */
+ int err; /* return value */
+ /* initialize input state */
+ s.infun = infun;
+ s.inhow = inhow;
+ if (left != NULL && *left) {
+ s.left = *left;
+ s.in = *in;
+ s.left = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+ /* initialize output state */
+ s.outfun = outfun;
+ s.outhow = outhow;
+ s.next = 0;
+ s.first = 1;
+ /* return if bits() or decode() tries to read past available input */
+ if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
+ err = 2; /* then skip decomp(), return error */
+ err = decomp(&s); /* decompress */
+ /* return unused input */
+ if (left != NULL)
+ *left = s.left;
+ if (in != NULL)
+ *in = s.left ? s.in : NULL;
+ /* write any leftover output and update the error code if needed */
+ if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
+ err = 1;
+ return err;
+#ifdef TEST
+/* Example of how to use blast() */
+#define CHUNK 16384
+local unsigned inf(void *how, unsigned char **buf)
+ static unsigned char hold[CHUNK];
+ *buf = hold;
+ return fread(hold, 1, CHUNK, (FILE *)how);
+local int outf(void *how, unsigned char *buf, unsigned len)
+ return fwrite(buf, 1, len, (FILE *)how) != len;
+/* Decompress a PKWare Compression Library stream from stdin to stdout */
+int main(void)
+ int ret;
+ unsigned left;
+ /* decompress to stdout */
+ left = 0;
+ ret = blast(inf, stdin, outf, stdout, &left, NULL);
+ if (ret != 0)
+ fprintf(stderr, "blast error: %d\n", ret);
+ /* count any leftover bytes */
+ while (getchar() != EOF)
+ left++;
+ if (left)
+ fprintf(stderr, "blast warning: %u unused bytes of input\n", left);
+ /* return blast() error code */
+ return ret;
@@ -0,0 +1,83 @@
+/* blast.h -- interface for blast.c
+ Copyright (C) 2003, 2012, 2013 Mark Adler
+ version 1.3, 24 Aug 2013
+ warranty. In no event will the author be held liable for any damages
+ Mark Adler [email protected]
+ * blast() decompresses the PKWare Data Compression Library (DCL) compressed
+ * format. It provides the same functionality as the explode() function in
+ * that library. (Note: PKWare overused the "implode" verb, and the format
+ * used by their library implode() function is completely different and
+ * incompatible with the implode compression method supported by PKZIP.)
+ * The binary mode for stdio functions should be used to assure that the
+ * compressed data is not corrupted when read or written. For example:
+ * fopen(..., "rb") and fopen(..., "wb").
+typedef unsigned (*blast_in)(void *how, unsigned char **buf);
+typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
+/* Definitions for input/output functions passed to blast(). See below for
+ * what the provided functions need to do.
+ unsigned *left, unsigned char **in);
+/* Decompress input to output using the provided infun() and outfun() calls.
+ * On success, the return value of blast() is zero. If there is an error in
+ * the source data, i.e. it is not in the proper format, then a negative value
+ * is returned. If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.
+ * The input function is invoked: len = infun(how, &buf), where buf is set by
+ * infun() to point to the input buffer, and infun() returns the number of
+ * available bytes there. If infun() returns zero, then blast() returns with
+ * an input error. (blast() only asks for input if it needs it.) inhow is for
+ * use by the application to pass an input descriptor to infun(), if desired.
+ * If left and in are not NULL and *left is not zero when blast() is called,
+ * then the *left bytes at *in are consumed for input before infun() is used.
+ * The output function is invoked: err = outfun(how, buf, len), where the bytes
+ * to be written are buf[0..len-1]. If err is not zero, then blast() returns
+ * with an output error. outfun() is always called with len <= 4096. outhow
+ * is for use by the application to pass an output descriptor to outfun(), if
+ * desired.
+ * If there is any unused input, *left is set to the number of bytes that were
+ * read and *in points to them. Otherwise *left is set to zero and *in is set
+ * to NULL. If left or in are NULL, then they are not set.
+ * The return codes are:
+ * 2: ran out of input before completing decompression
+ * 1: output error before completing decompression
+ * 0: successful decompression
+ * -1: literal flag not zero or one
+ * -2: dictionary size not in 4..6
+ * -3: distance is too far back
+ * At the bottom of blast.c is an example program that uses blast() that can be
+ * compiled to produce a command-line decompression filter by defining TEST.
@@ -0,0 +1 @@
+AIAIAIAIAIAIA
@@ -0,0 +1,557 @@
+{*******************************************************}
+{ }
+{ Borland Delphi Supplemental Components }
+{ ZLIB Data Compression Interface Unit }
+{ Copyright (c) 1997,99 Borland Corporation }
+{ Updated for zlib 1.2.x by Cosmin Truta <[email protected]> }
+unit ZLib;
+interface
+uses SysUtils, Classes;
+type
+ TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+ TFree = procedure (AppData, Block: Pointer); cdecl;
+ // Internal structure. Ignore.
+ TZStreamRec = packed record
+ next_in: PChar; // next input byte
+ avail_in: Integer; // number of bytes available at next_in
+ total_in: Longint; // total nb of input bytes read so far
+ next_out: PChar; // next output byte should be put here
+ avail_out: Integer; // remaining free space at next_out
+ total_out: Longint; // total nb of bytes output so far
+ msg: PChar; // last error message, NULL if no error
+ internal: Pointer; // not visible by applications
+ zalloc: TAlloc; // used to allocate the internal state
+ zfree: TFree; // used to free the internal state
+ AppData: Pointer; // private data object passed to zalloc and zfree
+ data_type: Integer; // best guess about the data type: ascii or binary
+ adler: Longint; // adler32 value of the uncompressed data
+ reserved: Longint; // reserved for future use
+ // Abstract ancestor class
+ TCustomZlibStream = class(TStream)
+ private
+ FStrm: TStream;
+ FStrmPos: Integer;
+ FOnProgress: TNotifyEvent;
+ FZRec: TZStreamRec;
+ FBuffer: array [Word] of Char;
+ protected
+ procedure Progress(Sender: TObject); dynamic;
+ property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
+ constructor Create(Strm: TStream);
+{ TCompressionStream compresses data on the fly as data is written to it, and
+ stores the compressed data to another stream.
+ TCompressionStream is write-only and strictly sequential. Reading from the
+ stream will raise an exception. Using Seek to move the stream pointer
+ will raise an exception.
+ Output data is cached internally, written to the output stream only when
+ the internal output buffer is full. All pending output data is flushed
+ when the stream is destroyed.
+ The Position property returns the number of uncompressed bytes of
+ data that have been written to the stream so far.
+ CompressionRate returns the on-the-fly percentage by which the original
+ data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
+ If raw data size = 100 and compressed data size = 25, the CompressionRate
+ is 75%
+ The OnProgress event is called each time the output buffer is filled and
+ written to the output stream. This is useful for updating a progress
+ indicator when you are writing a large chunk of data to the compression
+ stream in a single call.}
+ TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+ TCompressionStream = class(TCustomZlibStream)
+ function GetCompressionRate: Single;
+ public
+ constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
+ destructor Destroy; override;
+ function Read(var Buffer; Count: Longint): Longint; override;
+ function Write(const Buffer; Count: Longint): Longint; override;
+ function Seek(Offset: Longint; Origin: Word): Longint; override;
+ property CompressionRate: Single read GetCompressionRate;
+ property OnProgress;
+{ TDecompressionStream decompresses data on the fly as data is read from it.
+ Compressed data comes from a separate source stream. TDecompressionStream
+ is read-only and unidirectional; you can seek forward in the stream, but not
+ backwards. The special case of setting the stream position to zero is
+ allowed. Seeking forward decompresses data until the requested position in
+ the uncompressed data has been reached. Seeking backwards, seeking relative
+ to the end of the stream, requesting the size of the stream, and writing to
+ the stream will raise an exception.
+ The Position property returns the number of bytes of uncompressed data that
+ have been read from the stream so far.
+ The OnProgress event is called each time the internal input buffer of
+ compressed data is exhausted and the next block is read from the input stream.
+ This is useful for updating a progress indicator when you are reading a
+ large chunk of data from the decompression stream in a single call.}
+ TDecompressionStream = class(TCustomZlibStream)
+ constructor Create(Source: TStream);
+{ CompressBuf compresses data, buffer to buffer, in one call.
+ In: InBuf = ptr to compressed data
+ InBytes = number of bytes in InBuf
+ Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+ OutBytes = number of bytes in OutBuf }
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+ out OutBuf: Pointer; out OutBytes: Integer);
+{ DecompressBuf decompresses data, buffer to buffer, in one call.
+ OutEstimate = zero, or est. size of the decompressed data
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.
+ Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
+ BufSize = number of bytes in OutBuf }
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+ const OutBuf: Pointer; BufSize: Integer);
+const
+ zlib_version = '1.2.13';
+ EZlibError = class(Exception);
+ ECompressionError = class(EZlibError);
+ EDecompressionError = class(EZlibError);
+implementation
+uses ZLibConst;
+ Z_NO_FLUSH = 0;
+ Z_PARTIAL_FLUSH = 1;
+ Z_SYNC_FLUSH = 2;
+ Z_FULL_FLUSH = 3;
+ Z_FINISH = 4;
+ Z_OK = 0;
+ Z_STREAM_END = 1;
+ Z_NEED_DICT = 2;
+ Z_ERRNO = (-1);
+ Z_STREAM_ERROR = (-2);
+ Z_DATA_ERROR = (-3);
+ Z_MEM_ERROR = (-4);
+ Z_BUF_ERROR = (-5);
+ Z_VERSION_ERROR = (-6);
+ Z_NO_COMPRESSION = 0;
+ Z_BEST_SPEED = 1;
+ Z_BEST_COMPRESSION = 9;
+ Z_DEFAULT_COMPRESSION = (-1);
+ Z_FILTERED = 1;
+ Z_HUFFMAN_ONLY = 2;
+ Z_RLE = 3;
+ Z_DEFAULT_STRATEGY = 0;
+ Z_BINARY = 0;
+ Z_ASCII = 1;
+ Z_UNKNOWN = 2;
+ Z_DEFLATED = 8;
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+procedure adler32; external;
+procedure compressBound; external;
+procedure crc32; external;
+procedure deflateInit2_; external;
+procedure deflateParams; external;
+function _malloc(Size: Integer): Pointer; cdecl;
+ Result := AllocMem(Size);
+end;
+procedure _free(Block: Pointer); cdecl;
+ FreeMem(Block);
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+ FillChar(P^, count, B);
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+ Move(source^, dest^, count);
+// deflate compresses data
+function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
+ recsize: Integer): Integer; external;
+function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function deflateEnd(var strm: TZStreamRec): Integer; external;
+// inflate decompresses data
+function inflateInit_(var strm: TZStreamRec; version: PChar;
+function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function inflateEnd(var strm: TZStreamRec): Integer; external;
+function inflateReset(var strm: TZStreamRec): Integer; external;
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+// GetMem(Result, Items*Size);
+ Result := AllocMem(Items * Size);
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+{function zlibCheck(code: Integer): Integer;
+ Result := code;
+ if code < 0 then
+ raise EZlibError.Create('error'); //!!
+end;}
+function CCheck(code: Integer): Integer;
+ raise ECompressionError.Create('error'); //!!
+function DCheck(code: Integer): Integer;
+ raise EDecompressionError.Create('error'); //!!
+var
+ strm: TZStreamRec;
+ P: Pointer;
+ FillChar(strm, sizeof(strm), 0);
+ strm.zalloc := zlibAllocMem;
+ strm.zfree := zlibFreeMem;
+ OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+ GetMem(OutBuf, OutBytes);
+ try
+ strm.next_in := InBuf;
+ strm.avail_in := InBytes;
+ strm.next_out := OutBuf;
+ strm.avail_out := OutBytes;
+ CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
+ while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
+ P := OutBuf;
+ Inc(OutBytes, 256);
+ ReallocMem(OutBuf, OutBytes);
+ strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+ strm.avail_out := 256;
+ finally
+ CCheck(deflateEnd(strm));
+ ReallocMem(OutBuf, strm.total_out);
+ OutBytes := strm.total_out;
+ except
+ FreeMem(OutBuf);
+ raise
+ BufInc: Integer;
+ BufInc := (InBytes + 255) and not 255;
+ if OutEstimate = 0 then
+ OutBytes := BufInc
+ OutBytes := OutEstimate;
+ DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+ while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
+ Inc(OutBytes, BufInc);
+ strm.avail_out := BufInc;
+ DCheck(inflateEnd(strm));
+ strm.avail_out := BufSize;
+ if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
+ raise EZlibError.CreateRes(@sTargetBufferTooSmall);
+// TCustomZlibStream
+constructor TCustomZLibStream.Create(Strm: TStream);
+ inherited Create;
+ FStrm := Strm;
+ FStrmPos := Strm.Position;
+ FZRec.zalloc := zlibAllocMem;
+ FZRec.zfree := zlibFreeMem;
+procedure TCustomZLibStream.Progress(Sender: TObject);
+ if Assigned(FOnProgress) then FOnProgress(Sender);
+// TCompressionStream
+constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
+ Dest: TStream);
+ Levels: array [TCompressionLevel] of ShortInt =
+ (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
+ inherited Create(Dest);
+ FZRec.next_out := FBuffer;
+ FZRec.avail_out := sizeof(FBuffer);
+ CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
+destructor TCompressionStream.Destroy;
+ FZRec.next_in := nil;
+ FZRec.avail_in := 0;
+ if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+ while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
+ and (FZRec.avail_out = 0) do
+ FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+ if FZRec.avail_out < sizeof(FBuffer) then
+ FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
+ deflateEnd(FZRec);
+ inherited Destroy;
+function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
+ raise ECompressionError.CreateRes(@sInvalidStreamOp);
+function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
+ FZRec.next_in := @Buffer;
+ FZRec.avail_in := Count;
+ while (FZRec.avail_in > 0) do
+ CCheck(deflate(FZRec, 0));
+ if FZRec.avail_out = 0 then
+ FStrmPos := FStrm.Position;
+ Progress(Self);
+ Result := Count;
+function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+ if (Offset = 0) and (Origin = soFromCurrent) then
+ Result := FZRec.total_in
+function TCompressionStream.GetCompressionRate: Single;
+ if FZRec.total_in = 0 then
+ Result := 0
+ Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
+// TDecompressionStream
+constructor TDecompressionStream.Create(Source: TStream);
+ inherited Create(Source);
+ FZRec.next_in := FBuffer;
+ DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
+destructor TDecompressionStream.Destroy;
+ FStrm.Seek(-FZRec.avail_in, 1);
+ inflateEnd(FZRec);
+function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
+ FZRec.next_out := @Buffer;
+ FZRec.avail_out := Count;
+ while (FZRec.avail_out > 0) do
+ if FZRec.avail_in = 0 then
+ FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
+ Result := Count - FZRec.avail_out;
+ Exit;
+ CCheck(inflate(FZRec, 0));
+function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
+ raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+ I: Integer;
+ Buf: array [0..4095] of Char;
+ if (Offset = 0) and (Origin = soFromBeginning) then
+ DCheck(inflateReset(FZRec));
+ FStrm.Position := 0;
+ FStrmPos := 0;
+ end
+ else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
+ ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
+ if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
+ if Offset > 0 then
+ for I := 1 to Offset div sizeof(Buf) do
+ ReadBuffer(Buf, sizeof(Buf));
+ ReadBuffer(Buf, Offset mod sizeof(Buf));
+ Result := FZRec.total_out;
+end.
@@ -0,0 +1,11 @@
+unit ZLibConst;
+resourcestring
+ sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
+ sInvalidStreamOp = 'Invalid stream operation';
@@ -0,0 +1,76 @@
+Overview
+========
+This directory contains an update to the ZLib interface unit,
+distributed by Borland as a Delphi supplemental component.
+The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
+and is based on zlib version 1.0.4. There are a series of bugs
+and security problems associated with that old zlib version, and
+we recommend the users to update their ZLib unit.
+Summary of modifications
+========================
+- Improved makefile, adapted to zlib version 1.2.1.
+- Some field types from TZStreamRec are changed from Integer to
+ Longint, for consistency with the zlib.h header, and for 64-bit
+ readiness.
+- The zlib_version constant is updated.
+- The new Z_RLE strategy has its corresponding symbolic constant.
+- The allocation and deallocation functions and function types
+ (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
+ and _malloc and _free are added as C RTL stubs. As a result,
+ the original C sources of zlib can be compiled out of the box,
+ and linked to the ZLib unit.
+Suggestions for improvements
+============================
+Currently, the ZLib unit provides only a limited wrapper around
+the zlib library, and much of the original zlib functionality is
+missing. Handling compressed file formats like ZIP/GZIP or PNG
+cannot be implemented without having this functionality.
+Applications that handle these formats are either using their own,
+duplicated code, or not using the ZLib unit at all.
+Here are a few suggestions:
+- Checksum class wrappers around adler32() and crc32(), similar
+ to the Java classes that implement the java.util.zip.Checksum
+ interface.
+- The ability to read and write raw deflate streams, without the
+ zlib stream header and trailer. Raw deflate streams are used
+ in the ZIP file format.
+- The ability to read and write gzip streams, used in the GZIP
+ file format, and normally produced by the gzip program.
+- The ability to select a different compression strategy, useful
+ to PNG and MNG image compression, and to multimedia compression
+ in general. Besides the compression level
+ which, in fact, could have used the 'z' prefix and avoided
+ TColor-like symbols
+ TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
+ there could be a compression strategy
+ TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
+- ZIP and GZIP stream handling via TStreams.
+Cosmin Truta <[email protected]>
@@ -0,0 +1,99 @@
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+# ------------ Borland C++ ------------
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+# variables
+ZLIB_LIB = zlib.lib
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+adler32.obj: adler32.c zlib.h zconf.h
+compress.obj: compress.c zlib.h zconf.h
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+uncompr.obj: uncompr.c zlib.h zconf.h
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+example.obj: test/example.c zlib.h zconf.h
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+# testing
+test: example.exe minigzip.exe
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+# cleanup
+ -del *.obj
+ -del *.exe
+ -del *.lib
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<project name="DotZLib" default="build" basedir="./DotZLib">
+ <description>A .Net wrapper library around ZLib1.dll</description>
+ <property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
+ <property name="build.root" value="bin" />
+ <property name="debug" value="true" />
+ <property name="nunit" value="true" />
+ <property name="build.folder" value="${build.root}/debug/" if="${debug}" />
+ <property name="build.folder" value="${build.root}/release/" unless="${debug}" />
+ <target name="clean" description="Remove all generated files">
+ <delete dir="${build.root}" failonerror="false" />
+ </target>
+ <target name="build" description="compiles the source code">
+ <mkdir dir="${build.folder}" />
+ <csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
+ <references basedir="${nunit.location}">
+ <includes if="${nunit}" name="nunit.framework.dll" />
+ </references>
+ <sources>
+ <includes name="*.cs" />
+ <excludes name="UnitTests.cs" unless="${nunit}" />
+ </sources>
+ <arg value="/d:nunit" if="${nunit}" />
+ </csc>
+</project>
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ GlobalSection(ExtensibilityAddIns) = postSolution
+EndGlobal
@@ -0,0 +1,58 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DotZLib")]
+[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Henrik Ravn")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+// Version information for an assembly consists of the following four values:
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+// Use the attributes below to control which key is used for signing.
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
@@ -0,0 +1,202 @@
+// © Copyright Henrik Ravn 2004
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+namespace DotZLib
+ #region ChecksumGeneratorBase
+ /// <summary>
+ /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
+ /// </summary>
+ /// <example></example>
+ public abstract class ChecksumGeneratorBase : ChecksumGenerator
+ /// The value of the current checksum
+ protected uint _current;
+ /// Initializes a new instance of the checksum generator base - the current checksum is
+ /// set to zero
+ public ChecksumGeneratorBase()
+ _current = 0;
+ /// Initializes a new instance of the checksum generator basewith a specified value
+ /// <param name="initialValue">The value to set the current checksum to</param>
+ public ChecksumGeneratorBase(uint initialValue)
+ _current = initialValue;
+ /// Resets the current checksum to zero
+ public void Reset() { _current = 0; }
+ /// Gets the current checksum value
+ public uint Value { get { return _current; } }
+ /// Updates the current checksum with part of an array of bytes
+ /// <param name="data">The data to update the checksum with</param>
+ /// <param name="offset">Where in <c>data</c> to start updating</param>
+ /// <param name="count">The number of bytes from <c>data</c> to use</param>
+ /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+ /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+ /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
+ /// This is therefore the only method a derived class has to implement</remarks>
+ public abstract void Update(byte[] data, int offset, int count);
+ /// Updates the current checksum with an array of bytes.
+ public void Update(byte[] data)
+ Update(data, 0, data.Length);
+ /// Updates the current checksum with the data from a string
+ /// <param name="data">The string to update the checksum with</param>
+ /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
+ public void Update(string data)
+ Update(Encoding.UTF8.GetBytes(data));
+ /// Updates the current checksum with the data from a string, using a specific encoding
+ /// <param name="encoding">The encoding to use</param>
+ public void Update(string data, Encoding encoding)
+ Update(encoding.GetBytes(data));
+ #endregion
+ #region CRC32
+ /// Implements a CRC32 checksum generator
+ public sealed class CRC32Checksum : ChecksumGeneratorBase
+ #region DLL imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern uint crc32(uint crc, int data, uint length);
+ /// Initializes a new instance of the CRC32 checksum generator
+ public CRC32Checksum() : base() {}
+ /// Initializes a new instance of the CRC32 checksum generator with a specified value
+ public CRC32Checksum(uint initialValue) : base(initialValue) {}
+ public override void Update(byte[] data, int offset, int count)
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > data.Length) throw new ArgumentException();
+ GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
+ _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+ hData.Free();
+ #region Adler
+ /// Implements a checksum generator that computes the Adler checksum on data
+ public sealed class AdlerChecksum : ChecksumGeneratorBase
+ private static extern uint adler32(uint adler, int data, uint length);
+ /// Initializes a new instance of the Adler checksum generator
+ public AdlerChecksum() : base() {}
+ /// Initializes a new instance of the Adler checksum generator with a specified value
+ public AdlerChecksum(uint initialValue) : base(initialValue) {}
+ _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+using System.Diagnostics;
+ /// This class implements a circular buffer
+ internal class CircularBuffer
+ #region Private data
+ private int _capacity;
+ private int _head;
+ private int _tail;
+ private int _size;
+ private byte[] _buffer;
+ public CircularBuffer(int capacity)
+ Debug.Assert( capacity > 0 );
+ _buffer = new byte[capacity];
+ _capacity = capacity;
+ _head = 0;
+ _tail = 0;
+ _size = 0;
+ public int Size { get { return _size; } }
+ public int Put(byte[] source, int offset, int count)
+ Debug.Assert( count > 0 );
+ int trueCount = Math.Min(count, _capacity - Size);
+ for (int i = 0; i < trueCount; ++i)
+ _buffer[(_tail+i) % _capacity] = source[offset+i];
+ _tail += trueCount;
+ _tail %= _capacity;
+ _size += trueCount;
+ return trueCount;
+ public bool Put(byte b)
+ if (Size == _capacity) // no room
+ return false;
+ _buffer[_tail++] = b;
+ ++_size;
+ return true;
+ public int Get(byte[] destination, int offset, int count)
+ int trueCount = Math.Min(count,Size);
+ destination[offset + i] = _buffer[(_head+i) % _capacity];
+ _head += trueCount;
+ _head %= _capacity;
+ _size -= trueCount;
+ public int Get()
+ if (Size == 0)
+ return -1;
+ int result = (int)_buffer[_head++ % _capacity];
+ --_size;
+ return result;
@@ -0,0 +1,198 @@
+ /// Implements the common functionality needed for all <see cref="Codec"/>s
+ public abstract class CodecBase : Codec, IDisposable
+ #region Data members
+ /// Instance of the internal zlib buffer structure that is
+ /// passed to all functions in the zlib dll
+ internal ZStream _ztream = new ZStream();
+ /// True if the object instance has been disposed, false otherwise
+ protected bool _isDisposed = false;
+ /// The size of the internal buffers
+ protected const int kBufferSize = 16384;
+ private byte[] _outBuffer = new byte[kBufferSize];
+ private byte[] _inBuffer = new byte[kBufferSize];
+ private GCHandle _hInput;
+ private GCHandle _hOutput;
+ private uint _checksum = 0;
+ /// Initializes a new instance of the <c>CodeBase</c> class.
+ public CodecBase()
+ _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
+ _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
+ catch (Exception)
+ CleanUp(false);
+ throw;
+ #region Codec Members
+ /// Occurs when more processed data are available.
+ public event DataAvailableHandler DataAvailable;
+ /// Fires the <see cref="DataAvailable"/> event
+ protected void OnDataAvailable()
+ if (_ztream.total_out > 0)
+ if (DataAvailable != null)
+ DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
+ resetOutput();
+ /// Adds more data to the codec to be processed.
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ public void Add(byte[] data)
+ Add(data,0,data.Length);
+ /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+ /// <param name="count">The number of bytes to add</param>
+ /// <remarks>This must be implemented by a derived class</remarks>
+ public abstract void Add(byte[] data, int offset, int count);
+ /// Finishes up any pending data that needs to be processed and handled.
+ public abstract void Finish();
+ /// Gets the checksum of the data that has been added so far
+ public uint Checksum { get { return _checksum; } }
+ #region Destructor & IDisposable stuff
+ /// Destroys this instance
+ ~CodecBase()
+ /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
+ public void Dispose()
+ CleanUp(true);
+ /// Performs any codec specific cleanup
+ protected abstract void CleanUp();
+ // performs the release of the handles and calls the dereived CleanUp()
+ private void CleanUp(bool isDisposing)
+ if (!_isDisposed)
+ CleanUp();
+ if (_hInput.IsAllocated)
+ _hInput.Free();
+ if (_hOutput.IsAllocated)
+ _hOutput.Free();
+ _isDisposed = true;
+ #region Helper methods
+ /// Copies a number of bytes to the internal codec buffer - ready for proccesing
+ /// <param name="data">The byte array that contains the data to copy</param>
+ /// <param name="startIndex">The index of the first byte to copy</param>
+ /// <param name="count">The number of bytes to copy from <c>data</c></param>
+ protected void copyInput(byte[] data, int startIndex, int count)
+ Array.Copy(data, startIndex, _inBuffer,0, count);
+ _ztream.next_in = _hInput.AddrOfPinnedObject();
+ _ztream.total_in = 0;
+ _ztream.avail_in = (uint)count;
+ /// Resets the internal output buffers to a known state - ready for processing
+ protected void resetOutput()
+ _ztream.total_out = 0;
+ _ztream.avail_out = kBufferSize;
+ _ztream.next_out = _hOutput.AddrOfPinnedObject();
+ /// Updates the running checksum property
+ /// <param name="newSum">The new checksum value</param>
+ protected void setChecksum(uint newSum)
+ _checksum = newSum;
+ /// Implements a data compressor, using the deflate algorithm in the ZLib dll
+ public sealed class Deflater : CodecBase
+ #region Dll imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+ private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
+ private static extern int deflate(ref ZStream sz, int flush);
+ private static extern int deflateReset(ref ZStream sz);
+ private static extern int deflateEnd(ref ZStream sz);
+ /// Constructs an new instance of the <c>Deflater</c>
+ /// <param name="level">The compression level to use for this <c>Deflater</c></param>
+ public Deflater(CompressLevel level) : base()
+ int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
+ if (retval != 0)
+ throw new ZLibException(retval, "Could not initialize deflater");
+ public override void Add(byte[] data, int offset, int count)
+ if (data == null) throw new ArgumentNullException();
+ int total = count;
+ int inputIndex = offset;
+ int err = 0;
+ while (err >= 0 && inputIndex < total)
+ copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
+ while (err >= 0 && _ztream.avail_in > 0)
+ err = deflate(ref _ztream, (int)FlushTypes.None);
+ if (err == 0)
+ while (_ztream.avail_out == 0)
+ OnDataAvailable();
+ inputIndex += (int)_ztream.total_in;
+ setChecksum( _ztream.adler );
+ public override void Finish()
+ do
+ err = deflate(ref _ztream, (int)FlushTypes.Finish);
+ while (err == 0);
+ deflateReset(ref _ztream);
+ /// Closes the internal zlib deflate stream
+ protected override void CleanUp() { deflateEnd(ref _ztream); }
@@ -0,0 +1,288 @@
+using System.IO;
+ #region Internal types
+ /// Defines constants for the various flush types used with zlib
+ internal enum FlushTypes
+ None, Partial, Sync, Full, Finish, Block
+ #region ZStream structure
+ // internal mapping of the zlib zstream structure for marshalling
+ [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
+ internal struct ZStream
+ public IntPtr next_in;
+ public uint avail_in;
+ public uint total_in;
+ public IntPtr next_out;
+ public uint avail_out;
+ public uint total_out;
+ [MarshalAs(UnmanagedType.LPStr)]
+ string msg;
+ uint state;
+ uint zalloc;
+ uint zfree;
+ uint opaque;
+ int data_type;
+ public uint adler;
+ uint reserved;
+ #region Public enums
+ /// Defines constants for the available compression levels in zlib
+ public enum CompressLevel : int
+ /// The default compression level with a reasonable compromise between compression and speed
+ Default = -1,
+ /// No compression at all. The data are passed straight through.
+ None = 0,
+ /// The maximum compression rate available.
+ Best = 9,
+ /// The fastest available compression level.
+ Fastest = 1
+ #region Exception classes
+ /// The exception that is thrown when an error occurs on the zlib dll
+ public class ZLibException : ApplicationException
+ /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
+ /// error message and error code
+ /// <param name="errorCode">The zlib error code that caused the exception</param>
+ /// <param name="msg">A message that (hopefully) describes the error</param>
+ public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
+ /// error code
+ public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
+ #region Interfaces
+ /// Declares methods and properties that enables a running checksum to be calculated
+ public interface ChecksumGenerator
+ /// Gets the current value of the checksum
+ uint Value { get; }
+ /// Clears the current checksum to 0
+ void Reset();
+ /// Updates the current checksum with an array of bytes
+ void Update(byte[] data);
+ /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
+ void Update(byte[] data, int offset, int count);
+ void Update(string data);
+ void Update(string data, Encoding encoding);
+ /// Represents the method that will be called from a codec when new data
+ /// are available.
+ /// <paramref name="data">The byte array containing the processed data</paramref>
+ /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
+ /// <paramref name="count">The number of processed bytes available</paramref>
+ /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
+ /// You cannot assume that startIndex will be zero.
+ /// </remarks>
+ public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
+ /// Declares methods and events for implementing compressors/decompressors
+ public interface Codec
+ event DataAvailableHandler DataAvailable;
+ void Add(byte[] data);
+ void Add(byte[] data, int offset, int count);
+ void Finish();
+ uint Checksum { get; }
+ #region Classes
+ /// Encapsulates general information about the ZLib library
+ public class Info
+ private static extern uint zlibCompileFlags();
+ private static extern string zlibVersion();
+ #region Private stuff
+ private uint _flags;
+ // helper function that unpacks a bitsize mask
+ private static int bitSize(uint bits)
+ switch (bits)
+ case 0: return 16;
+ case 1: return 32;
+ case 2: return 64;
+ /// Constructs an instance of the <c>Info</c> class.
+ public Info()
+ _flags = zlibCompileFlags();
+ /// True if the library is compiled with debug info
+ public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
+ /// True if the library is compiled with assembly optimizations
+ public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
+ /// Gets the size of the unsigned int that was compiled into Zlib
+ public int SizeOfUInt { get { return bitSize(_flags & 3); } }
+ /// Gets the size of the unsigned long that was compiled into Zlib
+ public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
+ /// Gets the size of the pointers that were compiled into Zlib
+ public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
+ /// Gets the size of the z_off_t type that was compiled into Zlib
+ public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
+ /// Gets the version of ZLib as a string, e.g. "1.2.1"
+ public static string Version { get { return zlibVersion(); } }
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "DotZLib"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Library"
+ PreBuildEvent = ""
+ PostBuildEvent = ""
+ RootNamespace = "DotZLib"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = "docs\DotZLib.xml"
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = "1591"
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ Name = "Release"
+ DefineConstants = "TRACE"
+ DebugSymbols = "false"
+ NoWarn = ""
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ Name = "nunit.framework"
+ AssemblyName = "nunit.framework"
+ HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
+ AssemblyFolderKey = "hklm\dn\nunit.framework"
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ RelPath = "ChecksumImpl.cs"
+ RelPath = "CircularBuffer.cs"
+ RelPath = "CodecBase.cs"
+ RelPath = "Deflater.cs"
+ RelPath = "DotZLib.cs"
+ RelPath = "GZipStream.cs"
+ RelPath = "Inflater.cs"
+ RelPath = "UnitTests.cs"
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
@@ -0,0 +1,301 @@
+ /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
+ public class GZipStream : Stream, IDisposable
+ #region Dll Imports
+ private static extern IntPtr gzopen(string name, string mode);
+ private static extern int gzclose(IntPtr gzFile);
+ private static extern int gzwrite(IntPtr gzFile, int data, int length);
+ private static extern int gzread(IntPtr gzFile, int data, int length);
+ private static extern int gzgetc(IntPtr gzFile);
+ private static extern int gzputc(IntPtr gzFile, int c);
+ private IntPtr _gzFile;
+ private bool _isDisposed = false;
+ private bool _isWriting;
+ #region Constructors
+ /// Creates a new file as a writeable GZipStream
+ /// <param name="fileName">The name of the compressed file to create</param>
+ /// <param name="level">The compression level to use when adding data</param>
+ /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
+ public GZipStream(string fileName, CompressLevel level)
+ _isWriting = true;
+ _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
+ if (_gzFile == IntPtr.Zero)
+ throw new ZLibException(-1, "Could not open " + fileName);
+ /// Opens an existing file as a readable GZipStream
+ /// <param name="fileName">The name of the file to open</param>
+ public GZipStream(string fileName)
+ _isWriting = false;
+ _gzFile = gzopen(fileName, "rb");
+ #region Access properties
+ /// Returns true of this stream can be read from, false otherwise
+ public override bool CanRead
+ get
+ return !_isWriting;
+ /// Returns false.
+ public override bool CanSeek
+ /// Returns true if this tsream is writeable, false otherwise
+ public override bool CanWrite
+ return _isWriting;
+ #region Destructor & IDispose stuff
+ ~GZipStream()
+ cleanUp(false);
+ /// Closes the external file handle
+ cleanUp(true);
+ // Does the actual closing of the file handle.
+ private void cleanUp(bool isDisposing)
+ gzclose(_gzFile);
+ #region Basic reading and writing
+ /// Attempts to read a number of bytes from the stream.
+ /// <param name="buffer">The destination data buffer</param>
+ /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
+ /// <param name="count">The number of bytes requested</param>
+ /// <returns>The number of bytes read</returns>
+ /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
+ /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
+ /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is > buffer.Length</exception>
+ /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
+ /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+ public override int Read(byte[] buffer, int offset, int count)
+ if (!CanRead) throw new NotSupportedException();
+ if (buffer == null) throw new ArgumentNullException();
+ if ((offset+count) > buffer.Length) throw new ArgumentException();
+ if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+ GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+ int result;
+ result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+ if (result < 0)
+ throw new IOException();
+ h.Free();
+ /// Attempts to read a single byte from the stream.
+ /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
+ public override int ReadByte()
+ return gzgetc(_gzFile);
+ /// Writes a number of bytes to the stream
+ /// <param name="buffer"></param>
+ /// <param name="offset"></param>
+ /// <param name="count"></param>
+ /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
+ public override void Write(byte[] buffer, int offset, int count)
+ if (!CanWrite) throw new NotSupportedException();
+ int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+ /// Writes a single byte to the stream
+ /// <param name="value">The byte to add to the stream.</param>
+ public override void WriteByte(byte value)
+ int result = gzputc(_gzFile, (int)value);
+ #region Position & length stuff
+ /// Not supported.
+ /// <param name="value"></param>
+ /// <exception cref="NotSupportedException">Always thrown</exception>
+ public override void SetLength(long value)
+ throw new NotSupportedException();
+ /// Not suppported.
+ /// <param name="origin"></param>
+ /// <returns></returns>
+ public override long Seek(long offset, SeekOrigin origin)
+ /// Flushes the <c>GZipStream</c>.
+ /// <remarks>In this implementation, this method does nothing. This is because excessive
+ /// flushing may degrade the achievable compression rates.</remarks>
+ public override void Flush()
+ // left empty on purpose
+ /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
+ /// <remarks>In this implementation this property is not supported</remarks>
+ public override long Position
+ set
+ /// Gets the size of the stream. Not suppported.
+ public override long Length
@@ -0,0 +1,105 @@
+ /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
+ public class Inflater : CodecBase
+ private static extern int inflateInit_(ref ZStream sz, string vs, int size);
+ private static extern int inflate(ref ZStream sz, int flush);
+ private static extern int inflateReset(ref ZStream sz);
+ private static extern int inflateEnd(ref ZStream sz);
+ /// Constructs an new instance of the <c>Inflater</c>
+ public Inflater() : base()
+ int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
+ throw new ZLibException(retval, "Could not initialize inflater");
+ err = inflate(ref _ztream, (int)FlushTypes.None);
+ err = inflate(ref _ztream, (int)FlushTypes.Finish);
+ inflateReset(ref _ztream);
+ /// Closes the internal zlib inflate stream
+ protected override void CleanUp() { inflateEnd(ref _ztream); }
@@ -0,0 +1,274 @@
+using System.Collections;
+// uncomment the define below to include unit tests
+//#define nunit
+#if nunit
+using NUnit.Framework;
+// Unit tests for the DotZLib class library
+// ----------------------------------------
+// Use this with NUnit 2 from http://www.nunit.org
+namespace DotZLibTests
+ using DotZLib;
+ // helper methods
+ internal class Utils
+ public static bool byteArrEqual( byte[] lhs, byte[] rhs )
+ if (lhs.Length != rhs.Length)
+ for (int i = lhs.Length-1; i >= 0; --i)
+ if (lhs[i] != rhs[i])
+ [TestFixture]
+ public class CircBufferTests
+ #region Circular buffer tests
+ [Test]
+ public void SinglePutGet()
+ CircularBuffer buf = new CircularBuffer(10);
+ Assert.AreEqual( 0, buf.Size );
+ Assert.AreEqual( -1, buf.Get() );
+ Assert.IsTrue(buf.Put( 1 ));
+ Assert.AreEqual( 1, buf.Size );
+ Assert.AreEqual( 1, buf.Get() );
+ public void BlockPutGet()
+ byte[] arr = {1,2,3,4,5,6,7,8,9,10};
+ Assert.AreEqual( 10, buf.Put(arr,0,10) );
+ Assert.AreEqual( 10, buf.Size );
+ Assert.IsFalse( buf.Put(11) );
+ Assert.IsTrue( buf.Put(11) );
+ byte[] arr2 = (byte[])arr.Clone();
+ Assert.AreEqual( 9, buf.Get(arr2,1,9) );
+ Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
+ public class ChecksumTests
+ #region CRC32 Tests
+ public void CRC32_Null()
+ CRC32Checksum crc32 = new CRC32Checksum();
+ Assert.AreEqual( 0, crc32.Value );
+ crc32 = new CRC32Checksum(1);
+ Assert.AreEqual( 1, crc32.Value );
+ crc32 = new CRC32Checksum(556);
+ Assert.AreEqual( 556, crc32.Value );
+ public void CRC32_Data()
+ byte[] data = { 1,2,3,4,5,6,7 };
+ crc32.Update(data);
+ Assert.AreEqual( 0x70e46888, crc32.Value );
+ crc32 = new CRC32Checksum();
+ crc32.Update("penguin");
+ Assert.AreEqual( 0x0e5c1a120, crc32.Value );
+ Assert.AreEqual(0x43b6aa94, crc32.Value);
+ #region Adler tests
+ public void Adler_Null()
+ AdlerChecksum adler = new AdlerChecksum();
+ Assert.AreEqual(0, adler.Value);
+ adler = new AdlerChecksum(1);
+ Assert.AreEqual( 1, adler.Value );
+ adler = new AdlerChecksum(556);
+ Assert.AreEqual( 556, adler.Value );
+ public void Adler_Data()
+ AdlerChecksum adler = new AdlerChecksum(1);
+ adler.Update(data);
+ Assert.AreEqual( 0x5b001d, adler.Value );
+ adler = new AdlerChecksum();
+ adler.Update("penguin");
+ Assert.AreEqual(0x0bcf02f6, adler.Value );
+ Assert.AreEqual(0x0bd602f7, adler.Value);
+ public class InfoTests
+ #region Info tests
+ public void Info_Version()
+ Info info = new Info();
+ Assert.AreEqual("1.2.13", Info.Version);
+ Assert.AreEqual(32, info.SizeOfUInt);
+ Assert.AreEqual(32, info.SizeOfULong);
+ Assert.AreEqual(32, info.SizeOfPointer);
+ Assert.AreEqual(32, info.SizeOfOffset);
+ public class DeflateInflateTests
+ #region Deflate tests
+ public void Deflate_Init()
+ using (Deflater def = new Deflater(CompressLevel.Default))
+ private ArrayList compressedData = new ArrayList();
+ private uint adler1;
+ private ArrayList uncompressedData = new ArrayList();
+ private uint adler2;
+ public void CDataAvail(byte[] data, int startIndex, int count)
+ for (int i = 0; i < count; ++i)
+ compressedData.Add(data[i+startIndex]);
+ public void Deflate_Compress()
+ compressedData.Clear();
+ byte[] testData = new byte[35000];
+ for (int i = 0; i < testData.Length; ++i)
+ testData[i] = 5;
+ using (Deflater def = new Deflater((CompressLevel)5))
+ def.DataAvailable += new DataAvailableHandler(CDataAvail);
+ def.Add(testData);
+ def.Finish();
+ adler1 = def.Checksum;
+ #region Inflate tests
+ public void Inflate_Init()
+ using (Inflater inf = new Inflater())
+ private void DDataAvail(byte[] data, int startIndex, int count)
+ uncompressedData.Add(data[i+startIndex]);
+ public void Inflate_Expand()
+ uncompressedData.Clear();
+ inf.DataAvailable += new DataAvailableHandler(DDataAvail);
+ inf.Add((byte[])compressedData.ToArray(typeof(byte)));
+ inf.Finish();
+ adler2 = inf.Checksum;
+ Assert.AreEqual( adler1, adler2 );
+ public class GZipStreamTests
+ #region GZipStream test
+ public void GZipStream_WriteRead()
+ using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
+ BinaryWriter writer = new BinaryWriter(gzOut);
+ writer.Write("hi there");
+ writer.Write(Math.PI);
+ writer.Write(42);
+ using (GZipStream gzIn = new GZipStream("gzstream.gz"))
+ BinaryReader reader = new BinaryReader(gzIn);
+ string s = reader.ReadString();
+ Assert.AreEqual("hi there",s);
+ double d = reader.ReadDouble();
+ Assert.AreEqual(Math.PI, d);
+ int i = reader.ReadInt32();
+ Assert.AreEqual(42,i);
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+This directory contains a .Net wrapper class library for the ZLib1.dll
+The wrapper includes support for inflating/deflating memory buffers,
+.Net streaming wrappers for the gz streams part of zlib, and wrappers
+for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
+Directory structure:
+--------------------
+LICENSE_1_0.txt - License file.
+readme.txt - This file.
+DotZLib.chm - Class library documentation
+DotZLib.build - NAnt build file
+DotZLib.sln - Microsoft Visual Studio 2003 solution file
+DotZLib\*.cs - Source files for the class library
+Unit tests:
+-----------
+The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
+To include unit tests in the build, define nunit before building.
+Build instructions:
+-------------------
+1. Using Visual Studio.Net 2003:
+ Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
+ will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
+ you are building the release or debug version of the library. Check
+ DotZLib/UnitTests.cs for instructions on how to include unit tests in the
+ build.
+2. Using NAnt:
+ Open a command prompt with access to the build environment and run nant
+ in the same directory as the DotZLib.build file.
+ You can define 2 properties on the nant command-line to control the build:
+ debug={true|false} to toggle between release/debug builds (default=true).
+ nunit={true|false} to include or esclude unit tests (default=true).
+ Also the target clean will remove binaries.
+ Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
+ or ./DotZLib/bin/debug, depending on whether you are building the release
+ or debug version of the library.
+ Examples:
+ nant -D:debug=false -D:nunit=false
+ will build a release mode version of the library without unit tests.
+ nant
+ will build a debug version of the library with unit tests
+ nant clean
+ will remove all previously built files.
+---------------------------------
+Copyright (c) Henrik Ravn 2004
+Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -0,0 +1,574 @@
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); // current match
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
+; (AMD64 on Athlon 64, Opteron, Phenom
+; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+; This software is provided 'as-is', without any express or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not be
+; misrepresented as being the original software
+; 3. This notice may not be removed or altered from any source distribution.
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+; to compile this file for zLib, I use option:
+; gcc -c -arch x86_64 gvmat64.S
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; // current match /
+; with XCode for Mac, I had strange error with some jump on intel syntax
+; this is why BEFORE_JMP and AFTER_JMP are used
+#define BEFORE_JMP .att_syntax
+#define AFTER_JMP .intel_syntax noprefix
+#ifndef NO_UNDERLINE
+# define match_init _match_init
+# define longest_match _longest_match
+.intel_syntax noprefix
+.globl match_init, longest_match
+.text
+longest_match:
+#define LocalVarsSize 96
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+#define chainlenwmask (rsp + 8 - LocalVarsSize)
+#define nicematch (rsp + 16 - LocalVarsSize)
+#define save_rdi (rsp + 24 - LocalVarsSize)
+#define save_rsi (rsp + 32 - LocalVarsSize)
+#define save_rbx (rsp + 40 - LocalVarsSize)
+#define save_rbp (rsp + 48 - LocalVarsSize)
+#define save_r12 (rsp + 56 - LocalVarsSize)
+#define save_r13 (rsp + 64 - LocalVarsSize)
+#define save_r14 (rsp + 72 - LocalVarsSize)
+#define save_r15 (rsp + 80 - LocalVarsSize)
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+#define MAX_MATCH 258
+#define MIN_MATCH 3
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+/* you can check the structure offset by running
+#include "deflate.h"
+void print_depl()
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+#define dsWSize 68
+#define dsWMask 76
+#define dsWindow 80
+#define dsPrev 96
+#define dsMatchLen 144
+#define dsPrevMatch 148
+#define dsStrStart 156
+#define dsMatchStart 160
+#define dsLookahead 164
+#define dsPrevLen 168
+#define dsMaxChainLen 172
+#define dsGoodMatch 188
+#define dsNiceMatch 192
+#define window_size [ rcx + dsWSize]
+#define WMask [ rcx + dsWMask]
+#define window_ad [ rcx + dsWindow]
+#define prev_ad [ rcx + dsPrev]
+#define strstart [ rcx + dsStrStart]
+#define match_start [ rcx + dsMatchStart]
+#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip
+#define prev_length [ rcx + dsPrevLen]
+#define max_chain_length [ rcx + dsMaxChainLen]
+#define good_match [ rcx + dsGoodMatch]
+#define nice_match [ rcx + dsNiceMatch]
+; windows:
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+; gcc on macosx-linux:
+; see http://www.x86-64.org/documentation/abi-0.99.pdf
+; param 1 in rdi, param 2 in rsi
+; rbx, rsp, rbp, r12 to r15 must be preserved
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+; mac: param 1 in rdi, param 2 rsi
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+ mov rcx,rdi
+ mov r8d,esi
+ mov [save_r12],r12
+ mov [save_r13],r13
+ mov [save_r14],r14
+ mov [save_r15],r15
+//;;; uInt wmask = s->w_mask;
+//;;; unsigned chain_length = s->max_chain_length;
+//;;; if (s->prev_length >= s->good_match) {
+//;;; chain_length >>= 2;
+//;;; }
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+//;;; chainlen is decremented once beforehand so that the function can
+//;;; use the sign flag instead of the zero flag for the exit test.
+//;;; It is then shifted into the high word, to make room for the wmask
+//;;; value, which it will always accompany.
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+//;;; on zlib only
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+//;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+//;;; Determine how many bytes the scan ptr is off from being
+//;;; dword-aligned.
+ mov r9,r13
+ neg r13
+ and r13,3
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+//;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+ xor edi,edi
+ sub ebp, eax
+ mov r11d, prev_length
+ cmovng ebp,edi
+//;;; int best_len = s->prev_length;
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.
+ lea rsi,[r10+r11]
+//;;; register ush scan_start = *(ushf*)scan;
+//;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+//;;; Posf *prev = s->prev;
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+ mov rdi, prev_ad
+//;;; Jump into the main loop.
+ mov edx, [chainlenwmask]
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+LookupLoop1:
+ and r8d, edx
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+LoopEntry1:
+LookupLoop2:
+LoopEntry2:
+LookupLoop4:
+LoopEntry4:
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+.balign 16
+LookupLoop:
+LoopEntry:
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+//;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+ lea rsi,[r8+r10]
+ mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+ add rdx,8+8+8
+ jnz LoopCmps
+ jmp LenMaximum
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+ test eax, 0x0000FFFF
+ jnz LenLower
+ test eax,0xffffffff
+ jnz LenLower32
+ add rdx,4
+ shr rax,32
+ or ax,ax
+LenLower32:
+ shr eax,16
+ add rdx,2
+LenLower:
+ sub al, 1
+ adc rdx, 0
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+//;;; then automatically accept it as the best possible match and leave.
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ jge LenMaximum
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+ cmp eax, r11d
+ jg LongerMatch
+ jmp LookupLoop
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ jge LeaveNow
+ lea rsi,[r10+rax]
+ movzx ebx, word ptr [r9 + rax - 1]
+//;;; Accept the current string, with the maximum possible length.
+LenMaximum:
+ mov r11d,MAX_MATCH
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+//;;; return s->lookahead;
+LeaveNow:
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+//;;; Restore the stack and return from whence we came.
+// mov rsi,[save_rsi]
+// mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+ mov r14,[save_r14]
+ mov r15,[save_r15]
+ ret 0
+//; please don't remove this string !
+//; Your can freely use gvmat64 in any free or commercial app
+//; but it is far better don't remove the string in the binary!
+ // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+match_init:
+See infback9.h for what this is and how to use it.
@@ -0,0 +1,615 @@
+/* infback9.c -- inflate deflate64 data using a call-back interface
+ * Copyright (C) 1995-2008 Mark Adler
+#include "infback9.h"
+#include "inftree9.h"
+#include "inflate9.h"
+#define WSIZE 65536UL
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+ window is a user-supplied window and output buffer that is 64K bytes.
+int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
+z_stream FAR *strm;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+ struct inflate_state FAR *state;
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ state->window = window;
+ return Z_OK;
+ Build and output length and distance decoding tables for fixed code
+ decoding.
+#ifdef MAKEFIXED
+void makefixed9(void)
+ unsigned sym, bits, low, size;
+ code *next, *lenfix, *distfix;
+ struct inflate_state state;
+ code fixed[544];
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state.lens[sym++] = 8;
+ while (sym < 256) state.lens[sym++] = 9;
+ while (sym < 280) state.lens[sym++] = 7;
+ while (sym < 288) state.lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
+ /* distance table */
+ while (sym < 32) state.lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
+ /* write tables */
+ puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
+ puts(" * Generated automatically by makefixed9().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
+ lenfix[low].val);
+ if (++low == size) break;
+ putchar(',');
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ if ((low % 5) == 0) printf("\n ");
+ printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
+ distfix[low].val);
+#endif /* MAKEFIXED */
+/* Macros for inflateBack(): */
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ hold = 0; \
+ bits = 0; \
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+/* Return the low n bits of the bit accumulator (n <= 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ if (left == 0) { \
+ put = window; \
+ left = WSIZE; \
+ wrap = 1; \
+ if (out(out_desc, put, (unsigned)left)) { \
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have; /* available input */
+ unsigned long left; /* available output */
+ inflate_mode mode; /* current inflate mode */
+ int lastblock; /* true if processing last block */
+ int wrap; /* true if the window has wrapped */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned extra; /* extra bits needed */
+ unsigned long length; /* literal or length of data to copy */
+ unsigned long offset; /* distance back to copy string from */
+ unsigned long copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+#include "inffix9.h"
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ state = (struct inflate_state FAR *)strm->state;
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ mode = TYPE;
+ lastblock = 0;
+ wrap = 0;
+ window = state->window;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = window;
+ left = WSIZE;
+ lencode = Z_NULL;
+ distcode = Z_NULL;
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (lastblock) {
+ BYTEBITS();
+ mode = DONE;
+ break;
+ NEEDBITS(3);
+ lastblock = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ lastblock ? " (last)" : ""));
+ mode = STORED;
+ case 1: /* fixed block */
+ lencode = lenfix;
+ lenbits = 9;
+ distcode = distfix;
+ distbits = 5;
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ mode = LEN; /* decode codes */
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ mode = TABLE;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ mode = BAD;
+ DROPBITS(2);
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %lu\n",
+ length));
+ INITBITS();
+ /* copy stored block from input to output */
+ while (length != 0) {
+ copy = length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ length -= copy;
+ Tracev((stderr, "inflate: stored end\n"));
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+ if (state->nlen > 286) {
+ strm->msg = (char *)"too many length symbols";
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ lencode = (code const FAR *)(state->next);
+ lenbits = 7;
+ ret = inflate_table9(CODES, state->lens, 19, &(state->next),
+ &(lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ /* get length and distance code code lengths */
+ while (state->have < state->nlen + state->ndist) {
+ here = lencode[BITS(lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ if (here.val < 16) {
+ NEEDBITS(here.bits);
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ len = 0;
+ copy = 3 + BITS(3);
+ NEEDBITS(here.bits + 7);
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ if (state->have + copy > state->nlen + state->ndist) {
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ /* handle error breaks in while */
+ if (mode == BAD) break;
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftree9.h
+ concerning the ENOUGH constants, which depend on those values */
+ ret = inflate_table9(LENS, state->lens, state->nlen,
+ &(state->next), &(lenbits), state->work);
+ strm->msg = (char *)"invalid literal/lengths set";
+ distcode = (code const FAR *)(state->next);
+ distbits = 6;
+ ret = inflate_table9(DISTS, state->lens + state->nlen,
+ state->ndist, &(state->next), &(distbits),
+ state->work);
+ strm->msg = (char *)"invalid distances set";
+ Tracev((stderr, "inflate: codes ok\n"));
+ mode = LEN;
+ case LEN:
+ /* get a literal, length, or end-of-block code */
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ here = lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ DROPBITS(last.bits);
+ length = (unsigned)here.val;
+ /* process literal */
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ *put++ = (unsigned char)(length);
+ left--;
+ /* process end of block */
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ /* invalid code */
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ /* length code -- get extra bits, if any */
+ extra = (unsigned)(here.op) & 31;
+ if (extra != 0) {
+ NEEDBITS(extra);
+ length += BITS(extra);
+ DROPBITS(extra);
+ Tracevv((stderr, "inflate: length %lu\n", length));
+ /* get distance code */
+ here = distcode[BITS(distbits)];
+ if ((here.op & 0xf0) == 0) {
+ here = distcode[last.val +
+ strm->msg = (char *)"invalid distance code";
+ offset = (unsigned)here.val;
+ /* get distance extra bits, if any */
+ extra = (unsigned)(here.op) & 15;
+ offset += BITS(extra);
+ if (offset > WSIZE - (wrap ? 0: left)) {
+ strm->msg = (char *)"invalid distance too far back";
+ Tracevv((stderr, "inflate: distance %lu\n", offset));
+ /* copy match from window to output */
+ copy = WSIZE - offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ from = put - offset;
+ copy = left;
+ if (copy > length) copy = length;
+ *put++ = *from++;
+ } while (length != 0);
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < WSIZE) {
+ if (out(out_desc, window, (unsigned)(WSIZE - left)))
+ ret = Z_BUF_ERROR;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+int ZEXPORT inflateBack9End(strm)
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
@@ -0,0 +1,37 @@
+/* infback9.h -- header for using inflateBack9 functions
+ * Copyright (C) 2003 Mark Adler
+ * This header file and associated patches provide a decoder for PKWare's
+ * undocumented deflate64 compression method (method 9). Use with infback9.c,
+ * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported.
+ * This should be compiled with zlib, since it uses zutil.h and zutil.o.
+ * This code has not yet been tested on 16-bit architectures. See the
+ * comments in zlib.h for inflateBack() usage. These functions are used
+ * identically, except that there is no windowBits parameter, and a 64K
+ * window must be provided. Also if int's are 16 bits, then a zero for
+ * the third parameter of the "out" function actually means 65536UL.
+ * zlib.h must be included before this header file.
+#ifdef __cplusplus
+extern "C" {
+ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define inflateBack9Init(strm, window) \
+ inflateBack9Init_((strm), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
@@ -0,0 +1,107 @@
+ /* inffix9.h -- table for decoding deflate64 fixed codes
+ * Generated automatically by makefixed9().
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
+ {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
+ {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
+ {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
+ {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
+ {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
+ {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
+ {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
+ {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
+ {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
+ {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
+ {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
+ {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
+ {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
+ {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
+ {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
+ {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
+ {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
+ {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
+ {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
+ {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
+ {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
+ {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
+ {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
+ {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
+ {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
+ {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
+ {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
+ {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
+ {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
+ {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
+ {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
+ {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
+ {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
+ {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
+ {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
+ {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
+ {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
+ {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
+ {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
+ {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
+ {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
+ {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
+ {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
+ {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
+ {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
+ {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
+ {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
+ {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
+ {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
+ {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
+ {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
+ {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
+ {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
+ {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
+ {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
+ {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
+ {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
+ {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
+ {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
+ {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
+ {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
+ {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
+ {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
+ {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
+ {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
+ {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
+ {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
+ {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
+ {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
+ {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
+ {0,8,79},{0,9,255}
+ };
+ static const code distfix[32] = {
+ {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
+ {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
+ {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
+ {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
+ {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
+ {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
+ {134,5,193},{142,5,49153}
@@ -0,0 +1,47 @@
+/* inflate9.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ STORED, /* i: waiting for stored size (length and complement) */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LEN, /* i: waiting for length/lit code */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD /* got a data error -- remain here until reset */
+} inflate_mode;
+ State transitions between above modes -
+ (most modes can go to the BAD mode -- not shown for clarity)
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or DONE
+ STORED -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LEN or TYPE
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ /* sliding window */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
@@ -0,0 +1,324 @@
+/* inftree9.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2022 Mark Adler
+#define MAXBITS 15
+const char inflate9_copyright[] =
+ " inflate9 1.2.13 Copyright 1995-2022 Mark Adler ";
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+int inflate_table9(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
+ 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
+ 131, 163, 195, 227, 3, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
+ 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
+ 133, 133, 133, 133, 144, 194, 65};
+ static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
+ 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
+ 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
+ static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
+ 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
+ 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
+ 139, 139, 140, 140, 141, 141, 142, 142};
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) return -1; /* no codes! */
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+ left = 1;
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+ offs[len + 1] = offs[len] + count[len];
+ /* sort symbols by length, by symbol order within each length */
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftree9.h
+ for more information.
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+ /* check available table space */
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS))
+ return 1;
+ /* process all codes and make table entries */
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ huff = 0;
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+ /* increment past last table */
+ next += 1U << curr;
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ /* check for enough space */
+ used += 1U << curr;
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ curr = root;
+ this.bits = (unsigned char)len;
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+ /* set return parameters */
+ *table += used;
+ *bits = root;
@@ -0,0 +1,61 @@
+/* inftree9.h -- header to use inftree9.c
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 100eeeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1446, which is the sum of 852 for literal/length codes and 594 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 32 6 15" for distance codes returns 594.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in infback9.c. If the root table size is changed,
+ then these maximum sizes would be need to be recalculated and updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 594
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+/* Type of code to build for inflate_table9() */
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
@@ -0,0 +1,24 @@
+#include "zfstream.h"
+int main() {
+ // Construct a stream object with this filebuffer. Anything sent
+ // to this stream will go to standard out.
+ gzofstream os( 1, ios::out );
+ // This text is getting compressed and sent to stdout.
+ // To prove this, run 'test | zcat'.
+ os << "Hello, Mommy" << endl;
+ os << setcompressionlevel( Z_NO_COMPRESSION );
+ os << "hello, hello, hi, ho!" << endl;
+ setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
+ << "I'm compressing again" << endl;
+ os.close();
@@ -0,0 +1,329 @@
+gzfilebuf::gzfilebuf() :
+ file(NULL),
+ mode(0),
+ own_file_descriptor(0)
+gzfilebuf::~gzfilebuf() {
+ sync();
+ if ( own_file_descriptor )
+ close();
+gzfilebuf *gzfilebuf::open( const char *name,
+ int io_mode ) {
+ if ( is_open() )
+ return NULL;
+ char char_mode[10];
+ char *p = char_mode;
+ if ( io_mode & ios::in ) {
+ mode = ios::in;
+ *p++ = 'r';
+ } else if ( io_mode & ios::app ) {
+ mode = ios::app;
+ *p++ = 'a';
+ } else {
+ mode = ios::out;
+ *p++ = 'w';
+ if ( io_mode & ios::binary ) {
+ mode |= ios::binary;
+ *p++ = 'b';
+ // Hard code the compression level
+ if ( io_mode & (ios::out|ios::app )) {
+ *p++ = '9';
+ // Put the end-of-string indicator
+ *p = '\0';
+ if ( (file = gzopen(name, char_mode)) == NULL )
+ own_file_descriptor = 1;
+ return this;
+gzfilebuf *gzfilebuf::attach( int file_descriptor,
+ if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
+ own_file_descriptor = 0;
+gzfilebuf *gzfilebuf::close() {
+ if ( is_open() ) {
+ gzclose( file );
+ file = NULL;
+int gzfilebuf::setcompressionlevel( int comp_level ) {
+ return gzsetparams(file, comp_level, -2);
+int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
+ return gzsetparams(file, -2, comp_strategy);
+streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
+ return streampos(EOF);
+int gzfilebuf::underflow() {
+ // If the file hasn't been opened for reading, error.
+ if ( !is_open() || !(mode & ios::in) )
+ return EOF;
+ // if a buffer doesn't exists, allocate one.
+ if ( !base() ) {
+ if ( (allocate()) == EOF )
+ setp(0,0);
+ if ( in_avail() )
+ return (unsigned char) *gptr();
+ if ( out_waiting() ) {
+ if ( flushbuf() == EOF )
+ // Attempt to fill the buffer.
+ int result = fillbuf();
+ if ( result == EOF ) {
+ // disable get area
+ setg(0,0,0);
+int gzfilebuf::overflow( int c ) {
+ if ( !is_open() || !(mode & ios::out) )
+ if ( allocate() == EOF )
+ if (in_avail()) {
+ if (out_waiting()) {
+ if (flushbuf() == EOF)
+ int bl = blen();
+ setp( base(), base() + bl);
+ if ( c != EOF ) {
+ *pptr() = c;
+ pbump(1);
+int gzfilebuf::sync() {
+ if ( !is_open() )
+ if ( out_waiting() )
+ return flushbuf();
+int gzfilebuf::flushbuf() {
+ char *q;
+ q = pbase();
+ n = pptr() - q;
+ if ( gzwrite( file, q, n) < n )
+int gzfilebuf::fillbuf() {
+ int required;
+ char *p;
+ p = base();
+ required = blen();
+ int t = gzread( file, p, required );
+ if ( t <= 0) return EOF;
+ setg( base(), base(), base()+t);
+ return t;
+gzfilestream_common::gzfilestream_common() :
+ ios( gzfilestream_common::rdbuf() )
+gzfilestream_common::~gzfilestream_common()
+void gzfilestream_common::attach( int fd, int io_mode ) {
+ if ( !buffer.attach( fd, io_mode) )
+ clear( ios::failbit | ios::badbit );
+ clear();
+void gzfilestream_common::open( const char *name, int io_mode ) {
+ if ( !buffer.open( name, io_mode ) )
+void gzfilestream_common::close() {
+ if ( !buffer.close() )
+gzfilebuf *gzfilestream_common::rdbuf()
+ return &buffer;
+gzifstream::gzifstream() :
+ clear( ios::badbit );
+gzifstream::gzifstream( const char *name, int io_mode ) :
+ gzfilestream_common::open( name, io_mode );
+gzifstream::gzifstream( int fd, int io_mode ) :
+ gzfilestream_common::attach( fd, io_mode );
+gzifstream::~gzifstream() { }
+gzofstream::gzofstream() :
+gzofstream::gzofstream( const char *name, int io_mode ) :
+gzofstream::gzofstream( int fd, int io_mode ) :
+gzofstream::~gzofstream() { }
@@ -0,0 +1,128 @@
+#ifndef zfstream_h
+#define zfstream_h
+#include <fstream.h>
+class gzfilebuf : public streambuf {
+public:
+ gzfilebuf( );
+ virtual ~gzfilebuf();
+ gzfilebuf *open( const char *name, int io_mode );
+ gzfilebuf *attach( int file_descriptor, int io_mode );
+ gzfilebuf *close();
+ int setcompressionlevel( int comp_level );
+ int setcompressionstrategy( int comp_strategy );
+ inline int is_open() const { return (file !=NULL); }
+ virtual streampos seekoff( streamoff, ios::seek_dir, int );
+ virtual int sync();
+protected:
+ virtual int underflow();
+ virtual int overflow( int = EOF );
+private:
+ gzFile file;
+ short mode;
+ short own_file_descriptor;
+ int flushbuf();
+ int fillbuf();
+class gzfilestream_common : virtual public ios {
+ friend class gzifstream;
+ friend class gzofstream;
+ friend gzofstream &setcompressionlevel( gzofstream &, int );
+ friend gzofstream &setcompressionstrategy( gzofstream &, int );
+ virtual ~gzfilestream_common();
+ void attach( int fd, int io_mode );
+ void open( const char *name, int io_mode );
+ void close();
+ gzfilestream_common();
+ gzfilebuf *rdbuf();
+ gzfilebuf buffer;
+class gzifstream : public gzfilestream_common, public istream {
+ gzifstream();
+ gzifstream( const char *name, int io_mode = ios::in );
+ gzifstream( int fd, int io_mode = ios::in );
+ virtual ~gzifstream();
+class gzofstream : public gzfilestream_common, public ostream {
+ gzofstream();
+ gzofstream( const char *name, int io_mode = ios::out );
+ gzofstream( int fd, int io_mode = ios::out );
+ virtual ~gzofstream();
+template<class T> class gzomanip {
+ friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
+ gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
+ gzofstream &(*func)(gzofstream &, T);
+ T val;
+template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
+ return (*m.func)(s, m.val);
+inline gzofstream &setcompressionlevel( gzofstream &s, int l )
+ (s.rdbuf())->setcompressionlevel(l);
+ return s;
+inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
+ (s.rdbuf())->setcompressionstrategy(l);
+inline gzomanip<int> setcompressionlevel(int l)
+ return gzomanip<int>(&setcompressionlevel,l);
+inline gzomanip<int> setcompressionstrategy(int l)
+ return gzomanip<int>(&setcompressionstrategy,l);
@@ -0,0 +1,307 @@
+ * Copyright (c) 1997
+ * Christian Michelsen Research AS
+ * Advanced Computing
+ * Fantoftvegen 38, 5036 BERGEN, Norway
+ * http://www.cmr.no
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Christian Michelsen Research AS makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+#ifndef ZSTREAM__H
+#define ZSTREAM__H
+ * zstream.h - C++ interface to the 'zlib' general purpose compression library
+ * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
+#include <strstream.h>
+#if defined(_WIN32)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+# define SET_BINARY_MODE(file)
+class zstringlen {
+ zstringlen(class izstream&);
+ zstringlen(class ozstream&, const char*);
+ size_t value() const { return val.word; }
+ struct Val { unsigned char byte; size_t word; } val;
+// ----------------------------- izstream -----------------------------
+class izstream
+ public:
+ izstream() : m_fp(0) {}
+ izstream(FILE* fp) : m_fp(0) { open(fp); }
+ izstream(const char* name) : m_fp(0) { open(name); }
+ ~izstream() { close(); }
+ /* Opens a gzip (.gz) file for reading.
+ * open() can be used to read a file which is not in gzip format;
+ * in this case read() will directly read from the file without
+ * decompression. errno can be checked to distinguish two error
+ * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
+ void open(const char* name) {
+ if (m_fp) close();
+ m_fp = ::gzopen(name, "rb");
+ void open(FILE* fp) {
+ SET_BINARY_MODE(fp);
+ m_fp = ::gzdopen(fileno(fp), "rb");
+ /* Flushes all pending input if necessary, closes the compressed file
+ * and deallocates all the (de)compression state. The return value is
+ * the zlib error number (see function error() below).
+ int close() {
+ int r = ::gzclose(m_fp);
+ m_fp = 0; return r;
+ /* Binary read the given number of bytes from the compressed file.
+ int read(void* buf, size_t len) {
+ return ::gzread(m_fp, buf, len);
+ /* Returns the error message for the last error which occurred on the
+ * given compressed file. errnum is set to zlib error number. If an
+ * error occurred in the file system and not in the compression library,
+ * errnum is set to Z_ERRNO and the application may consult errno
+ * to get the exact error code.
+ const char* error(int* errnum) {
+ return ::gzerror(m_fp, errnum);
+ gzFile fp() { return m_fp; }
+ private:
+ gzFile m_fp;
+ * Binary read the given (array of) object(s) from the compressed file.
+ * If the input file was not in gzip format, read() copies the objects number
+ * of bytes into the buffer.
+ * returns the number of uncompressed bytes actually read
+ * (0 for end of file, -1 for error).
+template <class T, class Items>
+inline int read(izstream& zs, T* x, Items items) {
+ return ::gzread(zs.fp(), x, items*sizeof(T));
+ * Binary input with the '>' operator.
+template <class T>
+inline izstream& operator>(izstream& zs, T& x) {
+ ::gzread(zs.fp(), &x, sizeof(T));
+ return zs;
+inline zstringlen::zstringlen(izstream& zs) {
+ zs > val.byte;
+ if (val.byte == 255) zs > val.word;
+ else val.word = val.byte;
+ * Read length of string + the string with the '>' operator.
+inline izstream& operator>(izstream& zs, char* x) {
+ zstringlen len(zs);
+ ::gzread(zs.fp(), x, len.value());
+ x[len.value()] = '\0';
+inline char* read_string(izstream& zs) {
+ char* x = new char[len.value()+1];
+ return x;
+// ----------------------------- ozstream -----------------------------
+class ozstream
+ ozstream() : m_fp(0), m_os(0) {
+ ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
+ : m_fp(0), m_os(0) {
+ open(fp, level);
+ ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
+ open(name, level);
+ ~ozstream() {
+ /* Opens a gzip (.gz) file for writing.
+ * The compression level parameter should be in 0..9
+ * errno can be checked to distinguish two error cases
+ * (if errno is zero, the zlib error is Z_MEM_ERROR).
+ void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
+ char mode[4] = "wb\0";
+ if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+ m_fp = ::gzopen(name, mode);
+ /* open from a FILE pointer.
+ void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
+ m_fp = ::gzdopen(fileno(fp), mode);
+ /* Flushes all pending output if necessary, closes the compressed file
+ if (m_os) {
+ ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+ delete[] m_os->str(); delete m_os; m_os = 0;
+ int r = ::gzclose(m_fp); m_fp = 0; return r;
+ /* Binary write the given number of bytes into the compressed file.
+ int write(const void* buf, size_t len) {
+ return ::gzwrite(m_fp, (voidp) buf, len);
+ /* Flushes all pending output into the compressed file. The parameter
+ * _flush is as in the deflate() function. The return value is the zlib
+ * error number (see function gzerror below). flush() returns Z_OK if
+ * the flush_ parameter is Z_FINISH and all output could be flushed.
+ * flush() should be called only when strictly necessary because it can
+ * degrade compression.
+ int flush(int _flush) {
+ os_flush();
+ return ::gzflush(m_fp, _flush);
+ ostream& os() {
+ if (m_os == 0) m_os = new ostrstream;
+ return *m_os;
+ void os_flush() {
+ if (m_os && m_os->pcount()>0) {
+ ostrstream* oss = new ostrstream;
+ oss->fill(m_os->fill());
+ oss->flags(m_os->flags());
+ oss->precision(m_os->precision());
+ oss->width(m_os->width());
+ delete[] m_os->str(); delete m_os; m_os = oss;
+ ostrstream* m_os;
+ * Binary write the given (array of) object(s) into the compressed file.
+ * returns the number of uncompressed bytes actually written
+ * (0 in case of error).
+inline int write(ozstream& zs, const T* x, Items items) {
+ return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
+ * Binary output with the '<' operator.
+inline ozstream& operator<(ozstream& zs, const T& x) {
+ ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
+inline zstringlen::zstringlen(ozstream& zs, const char* x) {
+ val.byte = 255; val.word = ::strlen(x);
+ if (val.word < 255) zs < (val.byte = val.word);
+ else zs < val;
+ * Write length of string + the string with the '<' operator.
+inline ozstream& operator<(ozstream& zs, const char* x) {
+ zstringlen len(zs, x);
+ ::gzwrite(zs.fp(), (voidp) x, len.value());
+#ifdef _MSC_VER
+inline ozstream& operator<(ozstream& zs, char* const& x) {
+ return zs < (const char*) x;
+ * Ascii write with the << operator;
+inline ostream& operator<<(ozstream& zs, const T& x) {
+ zs.os_flush();
+ return zs.os() << x;
@@ -0,0 +1,25 @@
+#include "zstream.h"
+#include <math.h>
+#include <iomanip.h>
+void main() {
+ char h[256] = "Hello";
+ char* g = "Goodbye";
+ ozstream out("temp.gz");
+ out < "This works well" < h < g;
+ out.close();
+ izstream in("temp.gz"); // read it back
+ char *x = read_string(in), *y = new char[256], z[256];
+ in > y > z;
+ in.close();
+ cout << x << endl << y << endl << z << endl;
+ out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
+ out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
+ out << z << endl << y << endl << x << endl;
+ out << 1.1234567890123456789 << endl;
+ delete[] x; delete[] y;
@@ -0,0 +1,35 @@
+These classes provide a C++ stream interface to the zlib library. It allows you
+to do things like:
+ gzofstream outf("blah.gz");
+ outf << "These go into the gzip file " << 123 << endl;
+It does this by deriving a specialized stream buffer for gzipped files, which is
+the way Stroustrup would have done it. :->
+The gzifstream and gzofstream classes were originally written by Kevin Ruland
+and made available in the zlib contrib/iostream directory. The older version still
+compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
+this version.
+The new classes are as standard-compliant as possible, closely following the
+approach of the standard library's fstream classes. It compiles under gcc versions
+3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
+library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
+from the previous one in the following respects:
+- added showmanyc
+- added setbuf, with support for unbuffered output via setbuf(0,0)
+- a few bug fixes of stream behavior
+- gzipped output file opened with default compression level instead of maximum level
+- setcompressionlevel()/strategy() members replaced by single setcompression()
+The code is provided "as is", with the permission to use, copy, modify, distribute
+and sell it for any purpose without fee.
+Ludwig Schwardt
+<[email protected]>
+DSP Lab
+Electrical & Electronic Engineering Department
+University of Stellenbosch
+South Africa
@@ -0,0 +1,17 @@
+Possible upgrades to gzfilebuf:
+- The ability to do putback (e.g. putbackfail)
+- The ability to seek (zlib supports this, but could be slow/tricky)
+- Simultaneous read/write access (does it make sense?)
+- Support for ios_base::ate open mode
+- Locale support?
+- Check public interface to see which calls give problems
+ (due to dependence on library internals)
+- Override operator<<(ostream&, gzfilebuf*) to allow direct copying
+ of stream buffer to stream ( i.e. os << is.rdbuf(); )
@@ -0,0 +1,50 @@
+ * Test program for gzifstream and gzofstream
+ * by Ludwig Schwardt <[email protected]>
+ * original version by Kevin Ruland <[email protected]>
+#include <iostream> // for cout
+ gzofstream outf;
+ gzifstream inf;
+ char buf[80];
+ outf.open("test1.txt.gz");
+ outf << "The quick brown fox sidestepped the lazy canine\n"
+ << 1.3 << "\nPlan " << 9 << std::endl;
+ outf.close();
+ std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
+ << "The quick brown fox sidestepped the lazy canine\n"
+ std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
+ inf.open("test1.txt.gz");
+ while (inf.getline(buf,80,'\n')) {
+ std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+ inf.close();
+ outf.rdbuf()->pubsetbuf(0,0);
+ outf.open("test2.txt.gz");
+ outf << setcompression(Z_NO_COMPRESSION)
+ std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
+ std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
+ inf.rdbuf()->pubsetbuf(0,0);
+ inf.open("test2.txt.gz");
@@ -0,0 +1,479 @@
+ * A C++ I/O streams interface to the zlib gz* functions
+ * This version is standard-compliant and compatible with gcc 3.x.
+#include <cstring> // for strcpy, strcat, strlen (mode strings)
+#include <cstdio> // for BUFSIZ
+// Internal buffer sizes (default and "unbuffered" versions)
+#define BIGBUFSIZE BUFSIZ
+#define SMALLBUFSIZE 1
+/*****************************************************************************/
+// Default constructor
+gzfilebuf::gzfilebuf()
+: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
+ buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
+ // No buffers to start with
+ this->disable_buffer();
+// Destructor
+gzfilebuf::~gzfilebuf()
+ // Sync output buffer and close only if responsible for file
+ // (i.e. attached streams should be left open at this stage)
+ this->sync();
+ if (own_fd)
+ this->close();
+ // Make sure internal buffer is deallocated
+// Set compression level and strategy
+int
+gzfilebuf::setcompression(int comp_level,
+ int comp_strategy)
+ return gzsetparams(file, comp_level, comp_strategy);
+// Open gzipped file
+gzfilebuf*
+gzfilebuf::open(const char *name,
+ std::ios_base::openmode mode)
+ // Fail if file already open
+ if (this->is_open())
+ // Don't support simultaneous read/write access (yet)
+ if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+ // Build mode string for gzopen and check it [27.8.1.3.2]
+ char char_mode[6] = "\0\0\0\0\0";
+ if (!this->open_mode(mode, char_mode))
+ // Attempt to open file
+ if ((file = gzopen(name, char_mode)) == NULL)
+ // On success, allocate internal buffer and set flags
+ this->enable_buffer();
+ io_mode = mode;
+ own_fd = true;
+// Attach to gzipped file
+gzfilebuf::attach(int fd,
+ // Build mode string for gzdopen and check it [27.8.1.3.2]
+ // Attempt to attach to file
+ if ((file = gzdopen(fd, char_mode)) == NULL)
+ own_fd = false;
+// Close gzipped file
+gzfilebuf::close()
+ // Fail immediately if no file is open
+ if (!this->is_open())
+ // Assume success
+ gzfilebuf* retval = this;
+ // Attempt to sync and close gzipped file
+ if (this->sync() == -1)
+ retval = NULL;
+ if (gzclose(file) < 0)
+ // File is now gone anyway (postcondition [27.8.1.3.8])
+ // Destroy internal buffer if it exists
+ return retval;
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+// Convert int open mode to mode string
+bool
+gzfilebuf::open_mode(std::ios_base::openmode mode,
+ char* c_mode) const
+ bool testb = mode & std::ios_base::binary;
+ bool testi = mode & std::ios_base::in;
+ bool testo = mode & std::ios_base::out;
+ bool testt = mode & std::ios_base::trunc;
+ bool testa = mode & std::ios_base::app;
+ // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+ // Original zfstream hardcoded the compression level to maximum here...
+ // Double the time for less than 1% size improvement seems
+ // excessive though - keeping it at the default level
+ // To change back, just append "9" to the next three mode strings
+ if (!testi && testo && !testt && !testa)
+ strcpy(c_mode, "w");
+ if (!testi && testo && !testt && testa)
+ strcpy(c_mode, "a");
+ if (!testi && testo && testt && !testa)
+ if (testi && !testo && !testt && !testa)
+ strcpy(c_mode, "r");
+ // No read/write mode yet
+// if (testi && testo && !testt && !testa)
+// strcpy(c_mode, "r+");
+// if (testi && testo && testt && !testa)
+// strcpy(c_mode, "w+");
+ // Mode string should be empty for invalid combination of flags
+ if (strlen(c_mode) == 0)
+ if (testb)
+ strcat(c_mode, "b");
+// Determine number of characters in internal get buffer
+std::streamsize
+gzfilebuf::showmanyc()
+ // Calls to underflow will fail if file not opened for reading
+ if (!this->is_open() || !(io_mode & std::ios_base::in))
+ // Make sure get area is in use
+ if (this->gptr() && (this->gptr() < this->egptr()))
+ return std::streamsize(this->egptr() - this->gptr());
+// Fill get area from gzipped file
+gzfilebuf::int_type
+gzfilebuf::underflow()
+ // If something is left in the get area by chance, return it
+ // (this shouldn't normally happen, as underflow is only supposed
+ // to be called when gptr >= egptr, but it serves as error check)
+ return traits_type::to_int_type(*(this->gptr()));
+ // If the file hasn't been opened for reading, produce error
+ return traits_type::eof();
+ // Attempt to fill internal buffer from gzipped file
+ // (buffer must be guaranteed to exist...)
+ int bytes_read = gzread(file, buffer, buffer_size);
+ // Indicates error or EOF
+ if (bytes_read <= 0)
+ // Reset get area
+ this->setg(buffer, buffer, buffer);
+ // Make all bytes read from file available as get area
+ this->setg(buffer, buffer, buffer + bytes_read);
+ // Return next character in get area
+// Write put area to gzipped file
+gzfilebuf::overflow(int_type c)
+ // Determine whether put area is in use
+ if (this->pbase())
+ // Double-check pointer range
+ if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+ // Add extra character to buffer if not EOF
+ if (!traits_type::eq_int_type(c, traits_type::eof()))
+ *(this->pptr()) = traits_type::to_char_type(c);
+ this->pbump(1);
+ // Number of characters to write to file
+ int bytes_to_write = this->pptr() - this->pbase();
+ // Overflow doesn't fail if nothing is to be written
+ if (bytes_to_write > 0)
+ // If the file hasn't been opened for writing, produce error
+ if (!this->is_open() || !(io_mode & std::ios_base::out))
+ // If gzipped file won't accept all bytes written to it, fail
+ if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+ // Reset next pointer to point to pbase on success
+ this->pbump(-bytes_to_write);
+ // Write extra character to file if not EOF
+ else if (!traits_type::eq_int_type(c, traits_type::eof()))
+ // Impromptu char buffer (allows "unbuffered" output)
+ char_type last_char = traits_type::to_char_type(c);
+ // If gzipped file won't accept this character, fail
+ if (gzwrite(file, &last_char, 1) != 1)
+ // If you got here, you have succeeded (even if c was EOF)
+ // The return value should therefore be non-EOF
+ if (traits_type::eq_int_type(c, traits_type::eof()))
+ return traits_type::not_eof(c);
+ return c;
+// Assign new buffer
+std::streambuf*
+gzfilebuf::setbuf(char_type* p,
+ std::streamsize n)
+ // First make sure stuff is sync'ed, for safety
+ // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+ // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+ // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+ // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+ if (!p || !n)
+ // Replace existing buffer (if any) with small internal buffer
+ buffer = NULL;
+ buffer_size = 0;
+ own_buffer = true;
+ // Replace existing buffer (if any) with external buffer
+ buffer = p;
+ buffer_size = n;
+ own_buffer = false;
+// Write put area to gzipped file (i.e. ensures that put area is empty)
+gzfilebuf::sync()
+ return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+// Allocate internal buffer
+void
+gzfilebuf::enable_buffer()
+ // If internal buffer required, allocate one
+ if (own_buffer && !buffer)
+ // Check for buffered vs. "unbuffered"
+ if (buffer_size > 0)
+ // Allocate internal buffer
+ buffer = new char_type[buffer_size];
+ // Get area starts empty and will be expanded by underflow as need arises
+ // Setup entire internal buffer as put area.
+ // The one-past-end pointer actually points to the last element of the buffer,
+ // so that overflow(c) can safely add the extra character c to the sequence.
+ // These pointers remain in place for the duration of the buffer
+ this->setp(buffer, buffer + buffer_size - 1);
+ // Even in "unbuffered" case, (small?) get buffer is still required
+ buffer_size = SMALLBUFSIZE;
+ // "Unbuffered" means no put buffer
+ this->setp(0, 0);
+ // If buffer already allocated, reset buffer pointers just to make sure no
+ // stale chars are lying around
+// Destroy internal buffer
+gzfilebuf::disable_buffer()
+ // If internal buffer exists, deallocate it
+ if (own_buffer && buffer)
+ // Preserve unbuffered status by zeroing size
+ if (!this->pbase())
+ delete[] buffer;
+ this->setg(0, 0, 0);
+ // Reset buffer pointers to initial state if external buffer exists
+ if (buffer)
+// Default constructor initializes stream buffer
+gzifstream::gzifstream()
+: std::istream(NULL), sb()
+{ this->init(&sb); }
+// Initialize stream buffer and open file
+gzifstream::gzifstream(const char* name,
+ this->init(&sb);
+ this->open(name, mode);
+// Initialize stream buffer and attach to file
+gzifstream::gzifstream(int fd,
+ this->attach(fd, mode);
+// Open file and go into fail() state if unsuccessful
+gzifstream::open(const char* name,
+ if (!sb.open(name, mode | std::ios_base::in))
+ this->setstate(std::ios_base::failbit);
+ this->clear();
+// Attach to file and go into fail() state if unsuccessful
+gzifstream::attach(int fd,
+ if (!sb.attach(fd, mode | std::ios_base::in))
+// Close file
+gzifstream::close()
+ if (!sb.close())
+gzofstream::gzofstream()
+: std::ostream(NULL), sb()
+gzofstream::gzofstream(const char* name,
+gzofstream::gzofstream(int fd,
+gzofstream::open(const char* name,
+ if (!sb.open(name, mode | std::ios_base::out))
+gzofstream::attach(int fd,
+ if (!sb.attach(fd, mode | std::ios_base::out))
+gzofstream::close()
+#ifndef ZFSTREAM_H
+#define ZFSTREAM_H
+#include <istream> // not iostream, since we don't need cin/cout
+#include <ostream>
+/**
+ * @brief Gzipped file stream buffer class.
+ * This class implements basic_filebuf for gzipped files. It doesn't yet support
+ * seeking (allowed by zlib but slow/limited), putback and read/write access
+ * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+ * file streambuf.
+class gzfilebuf : public std::streambuf
+ // Default constructor.
+ gzfilebuf();
+ // Destructor.
+ virtual
+ ~gzfilebuf();
+ /**
+ * @brief Set compression level and strategy on the fly.
+ * @param comp_level Compression level (see zlib.h for allowed values)
+ * @param comp_strategy Compression strategy (see zlib.h for allowed values)
+ * @return Z_OK on success, Z_STREAM_ERROR otherwise.
+ * Unfortunately, these parameters cannot be modified separately, as the
+ * previous zfstream version assumed. Since the strategy is seldom changed,
+ * it can default and setcompression(level) then becomes like the old
+ * setcompressionlevel(level).
+ int
+ setcompression(int comp_level,
+ int comp_strategy = Z_DEFAULT_STRATEGY);
+ * @brief Check if file is open.
+ * @return True if file is open.
+ bool
+ is_open() const { return (file != NULL); }
+ * @brief Open gzipped file.
+ * @param name File name.
+ * @param mode Open mode flags.
+ * @return @c this on success, NULL on failure.
+ gzfilebuf*
+ open(const char* name,
+ std::ios_base::openmode mode);
+ * @brief Attach to already open gzipped file.
+ * @param fd File descriptor.
+ attach(int fd,
+ * @brief Close gzipped file.
+ * @brief Convert ios open mode int to mode string used by zlib.
+ * @return True if valid mode flag combination.
+ open_mode(std::ios_base::openmode mode,
+ char* c_mode) const;
+ * @brief Number of characters available in stream buffer.
+ * @return Number of characters.
+ * This indicates number of characters in get area of stream buffer.
+ * These characters can be read without accessing the gzipped file.
+ virtual std::streamsize
+ showmanyc();
+ * @brief Fill get area from gzipped file.
+ * @return First character in get area on success, EOF on error.
+ * This actually reads characters from gzipped file to stream
+ * buffer. Always buffered.
+ virtual int_type
+ underflow();
+ * @brief Write put area to gzipped file.
+ * @param c Extra character to add to buffer contents.
+ * @return Non-EOF on success, EOF on error.
+ * This actually writes characters in stream buffer to
+ * gzipped file. With unbuffered output this is done one
+ * character at a time.
+ overflow(int_type c = traits_type::eof());
+ * @brief Installs external stream buffer.
+ * @param p Pointer to char buffer.
+ * @param n Size of external buffer.
+ * Call setbuf(0,0) to enable unbuffered output.
+ virtual std::streambuf*
+ setbuf(char_type* p,
+ std::streamsize n);
+ * @brief Flush stream buffer to file.
+ * @return 0 on success, -1 on error.
+ * This calls underflow(EOF) to do the job.
+ virtual int
+// Some future enhancements
+// virtual int_type uflow();
+// virtual int_type pbackfail(int_type c = traits_type::eof());
+// virtual pos_type
+// seekoff(off_type off,
+// std::ios_base::seekdir way,
+// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+// seekpos(pos_type sp,
+ * @brief Allocate internal buffer.
+ * This function is safe to call multiple times. It will ensure
+ * that a proper internal buffer exists if it is required. If the
+ * buffer already exists or is external, the buffer pointers will be
+ * reset to their original state.
+ void
+ enable_buffer();
+ * @brief Destroy internal buffer.
+ * that the internal buffer is deallocated if it exists. In any
+ * case, it will also reset the buffer pointers.
+ disable_buffer();
+ * Underlying file pointer.
+ * Mode in which file was opened.
+ std::ios_base::openmode io_mode;
+ * @brief True if this object owns file descriptor.
+ * This makes the class responsible for closing the file
+ * upon destruction.
+ bool own_fd;
+ * @brief Stream buffer.
+ * For simplicity this remains allocated on the free store for the
+ * entire life span of the gzfilebuf object, unless replaced by setbuf.
+ char_type* buffer;
+ * @brief Stream buffer size.
+ * Defaults to system default buffer size (typically 8192 bytes).
+ * Modified by setbuf.
+ std::streamsize buffer_size;
+ * @brief True if this object owns stream buffer.
+ * This makes the class responsible for deleting the buffer
+ bool own_buffer;
+ * @brief Gzipped file input stream class.
+ * This class implements ifstream for gzipped files. Seeking and putback
+ * is not supported yet.
+class gzifstream : public std::istream
+ // Default constructor
+ * @brief Construct stream on gzipped file to be opened.
+ * @param mode Open mode flags (forced to contain ios::in).
+ explicit
+ gzifstream(const char* name,
+ std::ios_base::openmode mode = std::ios_base::in);
+ * @brief Construct stream on already open gzipped file.
+ gzifstream(int fd,
+ * Obtain underlying stream buffer.
+ rdbuf() const
+ { return const_cast<gzfilebuf*>(&sb); }
+ is_open() { return sb.is_open(); }
+ * Stream will be in state good() if file opens successfully;
+ * otherwise in state fail(). This differs from the behavior of
+ * ifstream, which never sets the state to good() and therefore
+ * won't allow you to reuse the stream for a second file unless
+ * you manually clear() the state. The choice is a matter of
+ * convenience.
+ * Stream will be in state good() if attach succeeded; otherwise
+ * in state fail().
+ * Stream will be in state fail() if close failed.
+ * Underlying stream buffer.
+ gzfilebuf sb;
+ * @brief Gzipped file output stream class.
+ * This class implements ofstream for gzipped files. Seeking and putback
+class gzofstream : public std::ostream
+ * @param mode Open mode flags (forced to contain ios::out).
+ gzofstream(const char* name,
+ std::ios_base::openmode mode = std::ios_base::out);
+ gzofstream(int fd,
+ * ofstream, which never sets the state to good() and therefore
+ * @brief Gzipped file output stream manipulator class.
+ * This class defines a two-argument manipulator for gzofstream. It is used
+ * as base for the setcompression(int,int) manipulator.
+template<typename T1, typename T2>
+ class gzomanip2
+ // Allows insertor to peek at internals
+ template <typename Ta, typename Tb>
+ friend gzofstream&
+ operator<<(gzofstream&,
+ const gzomanip2<Ta,Tb>&);
+ // Constructor
+ gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+ T1 v1,
+ T2 v2);
+ // Underlying manipulator function
+ gzofstream&
+ (*func)(gzofstream&, T1, T2);
+ // Arguments for manipulator function
+ T1 val1;
+ T2 val2;
+// Manipulator function thunks through to stream buffer
+inline gzofstream&
+setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+ (gzs.rdbuf())->setcompression(l, s);
+ return gzs;
+// Manipulator constructor stores arguments
+ inline
+ gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+ T2 v2)
+ : func(f), val1(v1), val2(v2)
+ { }
+// Insertor applies underlying manipulator function to stream
+ inline gzofstream&
+ operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+ { return (*m.func)(s, m.val1, m.val2); }
+// Insert this onto stream to simplify setting of compression level
+inline gzomanip2<int,int>
+setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+{ return gzomanip2<int,int>(&setcompression, l, s); }
+#endif // ZFSTREAM_H
@@ -0,0 +1,29 @@
+CFLAGS := $(CFLAGS) -O -I../..
+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
+ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
+.c.o:
+all: miniunz minizip
+miniunz: $(UNZ_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
+minizip: $(ZIP_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
+test: miniunz minizip
+ @rm -f test.*
+ @echo hello hello hello > test.txt
+ ./minizip test test.txt
+ ./miniunz -l test.zip
+ @mv test.txt test.old
+ ./miniunz test.zip
+ @cmp test.txt test.old
+ /bin/rm -f *.o *~ minizip miniunz test.*
@@ -0,0 +1,45 @@
+lib_LTLIBRARIES = libminizip.la
+if COND_DEMOS
+bin_PROGRAMS = miniunzip minizip
+endif
+zlib_top_srcdir = $(top_srcdir)/../..
+zlib_top_builddir = $(top_builddir)/../..
+AM_CPPFLAGS = -I$(zlib_top_srcdir)
+AM_LDFLAGS = -L$(zlib_top_builddir)
+if WIN32
+iowin32_src = iowin32.c
+iowin32_h = iowin32.h
+libminizip_la_SOURCES = \
+ ioapi.c \
+ mztools.c \
+ unzip.c \
+ zip.c \
+ ${iowin32_src}
+libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz
+minizip_includedir = $(includedir)/minizip
+minizip_include_HEADERS = \
+ crypt.h \
+ ioapi.h \
+ mztools.h \
+ unzip.h \
+ zip.h \
+ ${iowin32_h}
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = minizip.pc
+EXTRA_PROGRAMS = miniunzip minizip
+miniunzip_SOURCES = miniunz.c
+miniunzip_LDADD = libminizip.la
+minizip_SOURCES = minizip.c
+minizip_LDADD = libminizip.la -lz
@@ -0,0 +1,6 @@
+MiniZip 1.1 was derrived from MiniZip at version 1.01f
+Change in 1.0 (Okt 2009)
+ - **TODO - Add history**
@@ -0,0 +1,74 @@
+MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
+Introduction
+---------------------
+MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
+When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
+All possible work was done for compatibility.
+Background
+When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64
+support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
+That was used as a starting point. And after that ZIP64 support was added to zip.c
+some refactoring and code cleanup was also done.
+Changed from MiniZip 1.0 to MiniZip 1.1
+---------------------------------------
+* Added ZIP64 support for unzip ( by Even Rouault )
+* Added ZIP64 support for zip ( by Mathias Svensson )
+* Reverted some changed that Even Rouault did.
+* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
+* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
+* Added BZIP Compress method for zip
+* Did some refactoring and code cleanup
+Credits
+ Gilles Vollant - Original MiniZip author
+ Even Rouault - ZIP64 unzip Support
+ Daniel Borca - BZip Compression method support in unzip
+ Mathias Svensson - ZIP64 zip support
+ Mathias Svensson - BZip Compression method support in zip
+ Resources
+ ZipLayout http://result42.com/projects/ZipFileLayout
+ Command line tool for Windows that shows the layout and information of the headers in a zip archive.
+ Used when debugging and validating the creation of zip files using MiniZip64
+ ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+ Zip File specification
+Notes.
+ * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
+License
+----------------------------------------------------------
+ Condition of use and distribution are the same than zlib :
@@ -0,0 +1,32 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+AC_INIT([minizip], [1.2.13], [bugzilla.redhat.com])
+AC_CONFIG_SRCDIR([minizip.c])
+AM_INIT_AUTOMAKE([foreign])
+LT_INIT
+AC_MSG_CHECKING([whether to build example programs])
+AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs]))
+AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes])
+if test "$enable_demos" = yes
+then
+ AC_MSG_RESULT([yes])
+ AC_MSG_RESULT([no])
+case "${host}" in
+ *-mingw* | mingw*)
+ WIN32="yes"
+AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
+AC_SUBST([HAVE_UNISTD_H], [0])
+AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])
+AC_CONFIG_FILES([Makefile minizip.pc])
+AC_OUTPUT
@@ -0,0 +1,132 @@
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+ Version 1.01e, February 12th, 2005
+ Copyright (C) 1998-2005 Gilles Vollant
+ This code is a modified version of crypting code in Infozip distribution
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+ If you don't need crypting in your application, just define symbols
+ NOCRYPT and NOUNCRYPT.
+ This code support the "Traditional PKWARE Encryption".
+ The new AES encryption added on Zip format by Winzip (see the page
+ http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+ Encryption is not supported.
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ * unpredictable manner on 16-bit systems; not a problem
+ * with any known compiler so far, though */
+ (void)pcrc_32_tab;
+ temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+ * Update the encryption keys with the next byte of plain text
+static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
+ (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+ (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+ (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+ register int keyshift = (int)((*(pkeys+1)) >> 24);
+ (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
+ *(pkeys+0) = 305419896L;
+ *(pkeys+1) = 591751049L;
+ *(pkeys+2) = 878082192L;
+ while (*passwd != '\0') {
+ update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+ passwd++;
+#define zdecode(pkeys,pcrc_32_tab,c) \
+ (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+ (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#define RAND_HEAD_LEN 12
+ /* "last resort" source for second part of crypt seed pattern */
+# ifndef ZCR_SEED2
+# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
+# endif
+static unsigned crypthead(const char* passwd, /* password string */
+ unsigned char* buf, /* where to write header */
+ int bufSize,
+ unsigned long* pkeys,
+ const z_crc_t* pcrc_32_tab,
+ unsigned long crcForCrypting)
+ unsigned n; /* index in random header */
+ int t; /* temporary */
+ int c; /* random byte */
+ unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+ static unsigned calls = 0; /* ensure different random header each time */
+ if (bufSize<RAND_HEAD_LEN)
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ * output of rand() to get less predictability, since rand() is
+ * often poorly implemented.
+ if (++calls == 1)
+ srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+ init_keys(passwd, pkeys, pcrc_32_tab);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ c = (rand() >> 7) & 0xff;
+ header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+ /* Encrypt random header (last two bytes is high word of crc) */
+ buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);