mirror of
https://github.com/etlegacy/etlegacy-libs.git
synced 2024-12-04 01:51:39 +00:00
libs: updated to zlib 1.2.13
This commit is contained in:
parent
2b4822bcf9
commit
984873cb30
55 changed files with 12391 additions and 1886 deletions
|
@ -3,10 +3,7 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
|
|||
|
||||
project(zlib C)
|
||||
|
||||
set(VERSION "1.2.11")
|
||||
|
||||
option(ASM686 "Enable building i686 assembly implementation")
|
||||
option(AMD64 "Enable building amd64 assembly implementation")
|
||||
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")
|
||||
|
@ -129,39 +126,6 @@ if(NOT MINGW)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(ASM686)
|
||||
set(ZLIB_ASMS contrib/asm686/match.S)
|
||||
elseif (AMD64)
|
||||
set(ZLIB_ASMS contrib/amd64/amd64-match.S)
|
||||
endif ()
|
||||
|
||||
if(ZLIB_ASMS)
|
||||
add_definitions(-DASMV)
|
||||
set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(ASM686)
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
set(ZLIB_ASMS
|
||||
contrib/masmx86/inffas32.asm
|
||||
contrib/masmx86/match686.asm
|
||||
)
|
||||
elseif (AMD64)
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
set(ZLIB_ASMS
|
||||
contrib/masmx64/gvmat64.asm
|
||||
contrib/masmx64/inffasx64.asm
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ZLIB_ASMS)
|
||||
add_definitions(-DASMV -DASMINF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 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.]+)\".*"
|
||||
|
@ -183,8 +147,8 @@ if(MINGW)
|
|||
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
|
||||
endif(MINGW)
|
||||
|
||||
add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
||||
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
|
||||
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)
|
||||
|
||||
|
|
185
zlib/ChangeLog
185
zlib/ChangeLog
|
@ -1,6 +1,81 @@
|
|||
|
||||
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
|
||||
|
@ -96,7 +171,7 @@ Changes in 1.2.7.1 (24 Mar 2013)
|
|||
- 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
|
||||
- Suport i686 and amd64 assembler builds in CMakeLists.txt
|
||||
- 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
|
||||
|
@ -296,14 +371,14 @@ Changes in 1.2.5.1 (10 Sep 2011)
|
|||
- 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 indeterminancy
|
||||
- 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 assmebler code [Londer]
|
||||
- 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]
|
||||
|
||||
|
@ -511,7 +586,7 @@ Changes in 1.2.3.5 (8 Jan 2010)
|
|||
- 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 .
|
||||
- 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
|
||||
|
@ -685,7 +760,7 @@ Changes in 1.2.2.4 (11 July 2005)
|
|||
- 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.
|
||||
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]
|
||||
|
@ -721,7 +796,7 @@ Changes in 1.2.2.2 (30 December 2004)
|
|||
- 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.
|
||||
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
|
||||
|
@ -792,7 +867,7 @@ Changes in 1.2.1.1 (9 January 2004)
|
|||
- 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.
|
||||
- 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
|
||||
|
@ -970,7 +1045,7 @@ Changes in 1.2.0.1 (17 March 2003)
|
|||
- 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
|
||||
- Enchance comments in zlib.h on what happens if gzprintf() tries to
|
||||
- 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
|
||||
|
@ -1036,14 +1111,14 @@ Changes in 1.2.0 (9 March 2003)
|
|||
- 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.
|
||||
- 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.
|
||||
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).
|
||||
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
|
||||
|
@ -1117,7 +1192,7 @@ Changes in 1.1.1 (27 Feb 98)
|
|||
- 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.
|
||||
matches in deflate_slow
|
||||
- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
|
||||
|
||||
Changes in 1.1.0 (24 Feb 98)
|
||||
|
@ -1148,7 +1223,7 @@ Changes in 1.0.9 (17 Feb 1998)
|
|||
- 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)
|
||||
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)
|
||||
|
@ -1162,7 +1237,7 @@ Changes in 1.0.8 (27 Jan 1998)
|
|||
- 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".
|
||||
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
|
||||
|
@ -1201,12 +1276,12 @@ 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.
|
||||
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.
|
||||
- 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)
|
||||
|
@ -1218,7 +1293,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
- added Makefile.nt (thanks to Stephen Williams)
|
||||
- added the unsupported "contrib" directory:
|
||||
contrib/asm386/ by Gilles Vollant <info@winimage.com>
|
||||
386 asm code replacing longest_match().
|
||||
386 asm code replacing longest_match()
|
||||
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
|
||||
A C++ I/O streams interface to the zlib gz* functions
|
||||
contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
|
||||
|
@ -1226,7 +1301,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
|
||||
A very simple tar.gz file extractor using zlib
|
||||
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
|
||||
How to use compress(), uncompress() and the gz* functions from VB.
|
||||
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)
|
||||
|
||||
|
@ -1235,8 +1310,8 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
- 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.
|
||||
- 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
|
||||
|
@ -1249,7 +1324,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
- 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).
|
||||
- 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)
|
||||
|
@ -1259,7 +1334,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
|||
- 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.
|
||||
- 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
|
||||
|
@ -1280,7 +1355,7 @@ Changes in 1.0.5 (3 Jan 98)
|
|||
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.
|
||||
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)
|
||||
|
@ -1310,7 +1385,7 @@ 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.
|
||||
- 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),
|
||||
|
@ -1331,7 +1406,7 @@ 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.
|
||||
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
|
||||
|
@ -1373,30 +1448,30 @@ Changes in 0.99 (27 Jan 96)
|
|||
- 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.
|
||||
- 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).
|
||||
- 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.
|
||||
- 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?).
|
||||
(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).
|
||||
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).
|
||||
(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).
|
||||
typedefs and because voidnp was not near in large model)
|
||||
|
||||
Changes in 0.94 (13 Aug 95)
|
||||
- support MSDOS medium model
|
||||
|
@ -1405,12 +1480,12 @@ Changes in 0.94 (13 Aug 95)
|
|||
- 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.
|
||||
- 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.
|
||||
- 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
|
||||
|
@ -1429,7 +1504,7 @@ Changes in 0.92 (3 May 95)
|
|||
- no memcpy on Pyramid
|
||||
- suppressed inftest.c
|
||||
- optimized fill_window, put longest_match inline for gcc
|
||||
- optimized inflate on stored blocks.
|
||||
- optimized inflate on stored blocks
|
||||
- untabify all sources to simplify patches
|
||||
|
||||
Changes in 0.91 (2 May 95)
|
||||
|
@ -1447,7 +1522,7 @@ Changes in 0.9 (1 May 95)
|
|||
- 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.
|
||||
- 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++
|
||||
|
@ -1456,7 +1531,7 @@ Changes in 0.9 (1 May 95)
|
|||
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.
|
||||
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
|
||||
|
@ -1466,50 +1541,50 @@ Changes in 0.8 (29 April 95)
|
|||
|
||||
Changes in 0.71 (14 April 95)
|
||||
- Fixed more MSDOS compilation problems :( There is still a bug with
|
||||
TurboC large model.
|
||||
TurboC large model
|
||||
|
||||
Changes in 0.7 (14 April 95)
|
||||
- Added full inflate support.
|
||||
- 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.
|
||||
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.
|
||||
- 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.
|
||||
- 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).
|
||||
- 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.
|
||||
not yet Z_FULL_FLUSH
|
||||
- support decompression but only in a single step (forced Z_FINISH)
|
||||
- added opaque object for zalloc and zfree.
|
||||
- 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.
|
||||
- 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.
|
||||
- avoid "zip" everywhere, use zlib instead of ziplib
|
||||
- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
|
||||
if compression method == 8.
|
||||
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 the method parameter for deflateInit2
|
||||
- added inflateInit2
|
||||
- simplied considerably deflateInit and inflateInit by not supporting
|
||||
- simplified considerably deflateInit and inflateInit by not supporting
|
||||
user-provided history buffer. This is supported only in deflateInit2
|
||||
and inflateInit2.
|
||||
and inflateInit2
|
||||
|
||||
Changes in 0.3:
|
||||
- prefix all macro names with Z_
|
||||
- use Z_FINISH instead of deflateEnd to finish compression.
|
||||
- use Z_FINISH instead of deflateEnd to finish compression
|
||||
- added Z_HUFFMAN_ONLY
|
||||
- added gzerror()
|
||||
|
|
22
zlib/LICENSE
Normal file
22
zlib/LICENSE
Normal file
|
@ -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
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
|
@ -7,10 +7,6 @@
|
|||
# Normally configure builds both a static and a shared library.
|
||||
# If you want to build just a static library, use: ./configure --static
|
||||
|
||||
# To use the asm code, type:
|
||||
# cp contrib/asm?86/match.S ./match.S
|
||||
# make LOC=-DASMV OBJA=match.o
|
||||
|
||||
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
|
||||
# make install
|
||||
# To install in $HOME instead of /usr/local, use:
|
||||
|
@ -26,13 +22,13 @@ CFLAGS=-O
|
|||
|
||||
SFLAGS=-O
|
||||
LDFLAGS=
|
||||
TEST_LDFLAGS=-L. libz.a
|
||||
TEST_LDFLAGS=$(LDFLAGS) -L. libz.a
|
||||
LDSHARED=$(CC)
|
||||
CPP=$(CC) -E
|
||||
|
||||
STATICLIB=libz.a
|
||||
SHAREDLIB=libz.so
|
||||
SHAREDLIBV=libz.so.1.2.11
|
||||
SHAREDLIBV=libz.so.1.2.13
|
||||
SHAREDLIBM=libz.so.1
|
||||
LIBS=$(STATICLIB) $(SHAREDLIBV)
|
||||
|
||||
|
@ -87,12 +83,12 @@ test: all teststatic testshared
|
|||
|
||||
teststatic: static
|
||||
@TMPST=tmpst_$$; \
|
||||
if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
|
||||
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
|
||||
fi
|
||||
@rm -f tmpst_$$
|
||||
|
||||
testshared: shared
|
||||
@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
|
||||
|
@ -100,21 +96,21 @@ testshared: shared
|
|||
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 | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
|
||||
if echo hello world | ${QEMU_RUN} ./minigzipsh | ${QEMU_RUN} ./minigzipsh -d && ${QEMU_RUN} ./examplesh $$TMPSH; then \
|
||||
echo ' *** zlib shared test OK ***'; \
|
||||
else \
|
||||
echo ' *** zlib shared test FAILED ***'; false; \
|
||||
fi; \
|
||||
rm -f $$TMPSH
|
||||
fi
|
||||
@rm -f tmpsh_$$
|
||||
|
||||
test64: all64
|
||||
@TMP64=tmp64_$$; \
|
||||
if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
|
||||
if echo hello world | ${QEMU_RUN} ./minigzip64 | ${QEMU_RUN} ./minigzip64 -d && ${QEMU_RUN} ./example64 $$TMP64; then \
|
||||
echo ' *** zlib 64-bit test OK ***'; \
|
||||
else \
|
||||
echo ' *** zlib 64-bit test FAILED ***'; false; \
|
||||
fi; \
|
||||
rm -f $$TMP64
|
||||
fi
|
||||
@rm -f tmp64_$$
|
||||
|
||||
infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
|
||||
$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
|
||||
|
@ -124,7 +120,7 @@ infcover: infcover.o libz.a
|
|||
|
||||
cover: infcover
|
||||
rm -f *.gcda
|
||||
./infcover
|
||||
${QEMU_RUN} ./infcover
|
||||
gcov inf*.c
|
||||
|
||||
libz.a: $(OBJS)
|
||||
|
@ -292,10 +288,10 @@ minigzip$(EXE): minigzip.o $(STATICLIB)
|
|||
$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
|
||||
|
||||
examplesh$(EXE): example.o $(SHAREDLIBV)
|
||||
$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
|
||||
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) -L. $(SHAREDLIBV)
|
||||
|
||||
minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
|
||||
$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
|
||||
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) -L. $(SHAREDLIBV)
|
||||
|
||||
example64$(EXE): example64.o $(STATICLIB)
|
||||
$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
|
||||
|
@ -376,15 +372,13 @@ clean:
|
|||
rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
|
||||
|
||||
maintainer-clean: distclean
|
||||
distclean: clean zconf zconf.h.cmakein docs
|
||||
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
|
||||
@if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi
|
||||
@if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi
|
||||
|
||||
tags:
|
||||
etags $(SRCDIR)*.[ch]
|
||||
|
|
11
zlib/README
11
zlib/README
|
@ -1,6 +1,6 @@
|
|||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.11 is a general purpose data compression library. All the code is
|
||||
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
|
||||
|
@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> 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.11 are documented in the file ChangeLog.
|
||||
The changes made in version 1.2.13 are documented in the file ChangeLog.
|
||||
|
||||
Unsupported third party contributions are provided in directory contrib/ .
|
||||
|
||||
|
@ -84,7 +84,7 @@ Acknowledgments:
|
|||
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
(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
|
||||
|
@ -108,7 +108,10 @@ Copyright notice:
|
|||
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.
|
||||
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
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
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)
|
||||
int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
|
@ -65,7 +65,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
|||
|
||||
/* ===========================================================================
|
||||
*/
|
||||
int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT compress(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
|
@ -78,7 +78,7 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
|
|||
If the default memLevel or windowBits for deflateInit() is changed, then
|
||||
this function needs to be updated.
|
||||
*/
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong ZEXPORT compressBound(sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
|
|
143
zlib/configure
vendored
143
zlib/configure
vendored
|
@ -32,8 +32,11 @@ fi
|
|||
|
||||
# set command prefix for cross-compilation
|
||||
if [ -n "${CHOST}" ]; then
|
||||
uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
|
||||
uname=${CHOST}
|
||||
mname=${CHOST}
|
||||
CROSS_PREFIX="${CHOST}-"
|
||||
else
|
||||
mname=`(uname -a || echo unknown) 2>/dev/null`
|
||||
fi
|
||||
|
||||
# destination name for static library
|
||||
|
@ -87,6 +90,7 @@ build64=0
|
|||
gcc=0
|
||||
warn=0
|
||||
debug=0
|
||||
sanitize=0
|
||||
old_cc="$CC"
|
||||
old_cflags="$CFLAGS"
|
||||
OBJC='$(OBJZ) $(OBJG)'
|
||||
|
@ -137,6 +141,7 @@ case "$1" in
|
|||
-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
|
||||
|
@ -165,10 +170,17 @@ extern int getchar();
|
|||
int hello() {return getchar();}
|
||||
EOF
|
||||
|
||||
test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
|
||||
cc=${CC-${CROSS_PREFIX}gcc}
|
||||
cflags=${CFLAGS-"-O3"}
|
||||
# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
|
||||
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
|
||||
fi
|
||||
else
|
||||
cc=${CC}
|
||||
fi
|
||||
|
||||
case "$cc" in
|
||||
*gcc*) gcc=1 ;;
|
||||
*clang*) gcc=1 ;;
|
||||
|
@ -194,11 +206,14 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
|
|||
fi
|
||||
if test "$warn" -eq 1; then
|
||||
if test "$zconst" -eq 1; then
|
||||
CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
|
||||
CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -DZLIB_CONST"
|
||||
else
|
||||
CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
|
||||
CFLAGS="${CFLAGS} -Wall -Wextra"
|
||||
fi
|
||||
fi
|
||||
if test $sanitize -eq 1; then
|
||||
CFLAGS="${CFLAGS} -g -fsanitize=address"
|
||||
fi
|
||||
if test $debug -eq 1; then
|
||||
CFLAGS="${CFLAGS} -DZLIB_DEBUG"
|
||||
SFLAGS="${SFLAGS} -DZLIB_DEBUG"
|
||||
|
@ -207,47 +222,52 @@ if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
|
|||
uname=`(uname -s || echo unknown) 2>/dev/null`
|
||||
fi
|
||||
case "$uname" in
|
||||
Linux* | linux* | GNU | GNU/* | solaris*)
|
||||
Linux* | linux* | *-linux* | GNU | GNU/* | solaris*)
|
||||
case "$mname" in
|
||||
*sparc*)
|
||||
LDFLAGS="${LDFLAGS} -Wl,--no-warn-rwx-segments" ;;
|
||||
esac
|
||||
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* | OS/2*)
|
||||
CYGWIN* | Cygwin* | cygwin* | *-cygwin* | OS/2*)
|
||||
EXE='.exe' ;;
|
||||
MINGW* | mingw*)
|
||||
# temporary bypass
|
||||
MINGW* | mingw* | *-mingw*)
|
||||
rm -f $test.[co] $test $test$shared_ext
|
||||
echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
|
||||
leave 1
|
||||
echo "If this doesn't work for you, try win32/Makefile.gcc." | tee -a configure.log
|
||||
LDSHARED=${LDSHARED-"$cc -shared"}
|
||||
LDSHAREDLIBC=""
|
||||
EXE='.exe' ;;
|
||||
QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
|
||||
# (alain.bonnefoy@icbt.com)
|
||||
LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
|
||||
QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
|
||||
# (alain.bonnefoy@icbt.com)
|
||||
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 ;;
|
||||
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"
|
||||
else
|
||||
AR="/usr/bin/libtool"
|
||||
fi
|
||||
ARFLAGS="-o" ;;
|
||||
*) LDSHARED=${LDSHARED-"$cc -shared"} ;;
|
||||
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"
|
||||
else
|
||||
AR="/usr/bin/libtool"
|
||||
fi
|
||||
ARFLAGS="-o" ;;
|
||||
*)
|
||||
LDSHARED=${LDSHARED-"$cc -shared"} ;;
|
||||
esac
|
||||
else
|
||||
# find system name and corresponding cc options
|
||||
|
@ -367,8 +387,11 @@ else
|
|||
try()
|
||||
{
|
||||
show $*
|
||||
( $* ) >> configure.log 2>&1
|
||||
got=`( $* ) 2>&1`
|
||||
ret=$?
|
||||
if test "$got" != ""; then
|
||||
printf "%s\n" "$got" >> configure.log
|
||||
fi
|
||||
if test $ret -ne 0; then
|
||||
echo "(exit code "$ret")" >> configure.log
|
||||
fi
|
||||
|
@ -381,8 +404,11 @@ tryboth()
|
|||
show $*
|
||||
got=`( $* ) 2>&1`
|
||||
ret=$?
|
||||
printf %s "$got" >> configure.log
|
||||
if test "$got" != ""; then
|
||||
printf "%s\n" "$got" >> configure.log
|
||||
fi
|
||||
if test $ret -ne 0; then
|
||||
echo "(exit code "$ret")" >> configure.log
|
||||
return $ret
|
||||
fi
|
||||
test "$got" = ""
|
||||
|
@ -433,20 +459,6 @@ else
|
|||
TEST="all teststatic testshared"
|
||||
fi
|
||||
|
||||
# check for underscores in external names for use by assembler code
|
||||
CPP=${CPP-"$CC -E"}
|
||||
case $CFLAGS in
|
||||
*ASMV*)
|
||||
echo >> configure.log
|
||||
show "$NM $test.o | grep _hello"
|
||||
if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
|
||||
CPP="$CPP -DNO_UNDERLINE"
|
||||
echo Checking for underline in external names... No. | tee -a configure.log
|
||||
else
|
||||
echo Checking for underline in external names... Yes. | tee -a configure.log
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
echo >> configure.log
|
||||
|
||||
# check for size_t
|
||||
|
@ -457,17 +469,11 @@ size_t dummy = 0;
|
|||
EOF
|
||||
if try $CC -c $CFLAGS $test.c; then
|
||||
echo "Checking for size_t... Yes." | tee -a configure.log
|
||||
need_sizet=0
|
||||
else
|
||||
echo "Checking for size_t... No." | tee -a configure.log
|
||||
need_sizet=1
|
||||
fi
|
||||
|
||||
echo >> configure.log
|
||||
|
||||
# find the size_t integer type, if needed
|
||||
if test $need_sizet -eq 1; then
|
||||
cat > $test.c <<EOF
|
||||
# find a size_t integer type
|
||||
# check for long long
|
||||
cat > $test.c << EOF
|
||||
long long dummy = 0;
|
||||
EOF
|
||||
if try $CC -c $CFLAGS $test.c; then
|
||||
|
@ -495,17 +501,13 @@ EOF
|
|||
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}"
|
||||
else
|
||||
echo "Failed to find a pointer-size integer type." | tee -a configure.log
|
||||
leave 1
|
||||
echo "Checking for a pointer-size integer type... not found." | tee -a configure.log
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $need_sizet -eq 1; then
|
||||
CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
|
||||
SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
|
||||
fi
|
||||
|
||||
echo >> configure.log
|
||||
|
||||
# check for large file support, and if none, check for fseeko()
|
||||
|
@ -849,7 +851,6 @@ echo SHAREDLIBV = $SHAREDLIBV >> configure.log
|
|||
echo STATICLIB = $STATICLIB >> configure.log
|
||||
echo TEST = $TEST >> configure.log
|
||||
echo VER = $VER >> configure.log
|
||||
echo Z_U4 = $Z_U4 >> configure.log
|
||||
echo SRCDIR = $SRCDIR >> configure.log
|
||||
echo exec_prefix = $exec_prefix >> configure.log
|
||||
echo includedir = $includedir >> configure.log
|
||||
|
|
1303
zlib/crc32.c
1303
zlib/crc32.c
File diff suppressed because it is too large
Load diff
9877
zlib/crc32.h
9877
zlib/crc32.h
File diff suppressed because it is too large
Load diff
312
zlib/deflate.c
312
zlib/deflate.c
|
@ -1,5 +1,5 @@
|
|||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
* Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
#include "deflate.h"
|
||||
|
||||
const char deflate_copyright[] =
|
||||
" deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
|
||||
" deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and 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
|
||||
|
@ -87,13 +87,7 @@ local void lm_init OF((deflate_state *s));
|
|||
local void putShortMSB OF((deflate_state *s, uInt b));
|
||||
local void flush_pending OF((z_streamp strm));
|
||||
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
|
||||
#ifdef ASMV
|
||||
# pragma message("Assembler code may have bugs -- use at your own risk")
|
||||
void match_init OF((void)); /* asm code initialization */
|
||||
uInt longest_match OF((deflate_state *s, IPos cur_match));
|
||||
#else
|
||||
local uInt longest_match OF((deflate_state *s, IPos cur_match));
|
||||
#endif
|
||||
|
||||
#ifdef ZLIB_DEBUG
|
||||
local void check_match OF((deflate_state *s, IPos start, IPos match,
|
||||
|
@ -160,7 +154,7 @@ local const config configuration_table[10] = {
|
|||
* characters, so that a running hash key can be computed from the previous
|
||||
* key instead of complete recalculation each time.
|
||||
*/
|
||||
#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
|
||||
#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask)
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -190,8 +184,11 @@ local const config configuration_table[10] = {
|
|||
* prev[] will be initialized on the fly.
|
||||
*/
|
||||
#define CLEAR_HASH(s) \
|
||||
s->head[s->hash_size-1] = NIL; \
|
||||
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
|
||||
do { \
|
||||
s->head[s->hash_size - 1] = NIL; \
|
||||
zmemzero((Bytef *)s->head, \
|
||||
(unsigned)(s->hash_size - 1)*sizeof(*s->head)); \
|
||||
} while (0)
|
||||
|
||||
/* ===========================================================================
|
||||
* Slide the hash table when sliding the window down (could be avoided with 32
|
||||
|
@ -252,11 +249,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
int wrap = 1;
|
||||
static const char my_version[] = ZLIB_VERSION;
|
||||
|
||||
ushf *overlay;
|
||||
/* We overlay pending_buf and d_buf+l_buf. This works since the average
|
||||
* output size for (length,distance) codes is <= 24 bits.
|
||||
*/
|
||||
|
||||
if (version == Z_NULL || version[0] != my_version[0] ||
|
||||
stream_size != sizeof(z_stream)) {
|
||||
return Z_VERSION_ERROR;
|
||||
|
@ -287,6 +279,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
|
||||
if (windowBits < 0) { /* suppress zlib wrapper */
|
||||
wrap = 0;
|
||||
if (windowBits < -15)
|
||||
return Z_STREAM_ERROR;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
#ifdef GZIP
|
||||
|
@ -316,7 +310,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
s->hash_bits = (uInt)memLevel + 7;
|
||||
s->hash_size = 1 << s->hash_bits;
|
||||
s->hash_mask = s->hash_size - 1;
|
||||
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
|
||||
s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH);
|
||||
|
||||
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
|
||||
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
|
||||
|
@ -326,9 +320,47 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
|
||||
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
||||
|
||||
overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
||||
s->pending_buf = (uchf *) overlay;
|
||||
s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
|
||||
/* We overlay pending_buf and sym_buf. This works since the average size
|
||||
* for length/distance pairs over any compressed block is assured to be 31
|
||||
* bits or less.
|
||||
*
|
||||
* Analysis: The longest fixed codes are a length code of 8 bits plus 5
|
||||
* extra bits, for lengths 131 to 257. The longest fixed distance codes are
|
||||
* 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
|
||||
* possible fixed-codes length/distance pair is then 31 bits total.
|
||||
*
|
||||
* sym_buf starts one-fourth of the way into pending_buf. So there are
|
||||
* three bytes in sym_buf for every four bytes in pending_buf. Each symbol
|
||||
* in sym_buf is three bytes -- two for the distance and one for the
|
||||
* literal/length. As each symbol is consumed, the pointer to the next
|
||||
* sym_buf value to read moves forward three bytes. From that symbol, up to
|
||||
* 31 bits are written to pending_buf. The closest the written pending_buf
|
||||
* bits gets to the next sym_buf symbol to read is just before the last
|
||||
* code is written. At that time, 31*(n - 2) bits have been written, just
|
||||
* after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at
|
||||
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1
|
||||
* symbols are written.) The closest the writing gets to what is unread is
|
||||
* then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and
|
||||
* can range from 128 to 32768.
|
||||
*
|
||||
* Therefore, at a minimum, there are 142 bits of space between what is
|
||||
* written and what is read in the overlain buffers, so the symbols cannot
|
||||
* be overwritten by the compressed data. That space is actually 139 bits,
|
||||
* due to the three-bit fixed-code block header.
|
||||
*
|
||||
* That covers the case where either Z_FIXED is specified, forcing fixed
|
||||
* codes, or when the use of fixed codes is chosen, because that choice
|
||||
* results in a smaller compressed block than dynamic codes. That latter
|
||||
* condition then assures that the above analysis also covers all dynamic
|
||||
* blocks. A dynamic-code block will only be chosen to be emitted if it has
|
||||
* fewer bits than a fixed-code block would for the same set of symbols.
|
||||
* Therefore its average symbol length is assured to be less than 31. So
|
||||
* the compressed data for a dynamic block also cannot overwrite the
|
||||
* symbols from which it is being constructed.
|
||||
*/
|
||||
|
||||
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
|
||||
s->pending_buf_size = (ulg)s->lit_bufsize * 4;
|
||||
|
||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
|
@ -337,8 +369,12 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
|
||||
s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
|
||||
s->sym_buf = s->pending_buf + s->lit_bufsize;
|
||||
s->sym_end = (s->lit_bufsize - 1) * 3;
|
||||
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
|
||||
* on 16 bit machines and because stored blocks are restricted to
|
||||
* 64K-1 bytes.
|
||||
*/
|
||||
|
||||
s->level = level;
|
||||
s->strategy = strategy;
|
||||
|
@ -350,7 +386,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|||
/* =========================================================================
|
||||
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
|
||||
*/
|
||||
local int deflateStateCheck (strm)
|
||||
local int deflateStateCheck(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
|
@ -373,7 +409,7 @@ local int deflateStateCheck (strm)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||
int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
const Bytef *dictionary;
|
||||
uInt dictLength;
|
||||
|
@ -442,7 +478,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
|
||||
int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
Bytef *dictionary;
|
||||
uInt *dictLength;
|
||||
|
@ -464,7 +500,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateResetKeep (strm)
|
||||
int ZEXPORT deflateResetKeep(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
deflate_state *s;
|
||||
|
@ -488,13 +524,13 @@ int ZEXPORT deflateResetKeep (strm)
|
|||
#ifdef GZIP
|
||||
s->wrap == 2 ? GZIP_STATE :
|
||||
#endif
|
||||
s->wrap ? INIT_STATE : BUSY_STATE;
|
||||
INIT_STATE;
|
||||
strm->adler =
|
||||
#ifdef GZIP
|
||||
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
|
||||
#endif
|
||||
adler32(0L, Z_NULL, 0);
|
||||
s->last_flush = Z_NO_FLUSH;
|
||||
s->last_flush = -2;
|
||||
|
||||
_tr_init(s);
|
||||
|
||||
|
@ -502,7 +538,7 @@ int ZEXPORT deflateResetKeep (strm)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateReset (strm)
|
||||
int ZEXPORT deflateReset(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
int ret;
|
||||
|
@ -514,7 +550,7 @@ int ZEXPORT deflateReset (strm)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateSetHeader (strm, head)
|
||||
int ZEXPORT deflateSetHeader(strm, head)
|
||||
z_streamp strm;
|
||||
gz_headerp head;
|
||||
{
|
||||
|
@ -525,7 +561,7 @@ int ZEXPORT deflateSetHeader (strm, head)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePending (strm, pending, bits)
|
||||
int ZEXPORT deflatePending(strm, pending, bits)
|
||||
unsigned *pending;
|
||||
int *bits;
|
||||
z_streamp strm;
|
||||
|
@ -539,7 +575,7 @@ int ZEXPORT deflatePending (strm, pending, bits)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflatePrime (strm, bits, value)
|
||||
int ZEXPORT deflatePrime(strm, bits, value)
|
||||
z_streamp strm;
|
||||
int bits;
|
||||
int value;
|
||||
|
@ -549,7 +585,8 @@ int ZEXPORT deflatePrime (strm, bits, value)
|
|||
|
||||
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
s = strm->state;
|
||||
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
if (bits < 0 || bits > 16 ||
|
||||
s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
|
||||
return Z_BUF_ERROR;
|
||||
do {
|
||||
put = Buf_size - s->bi_valid;
|
||||
|
@ -587,12 +624,12 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
|||
func = configuration_table[s->level].func;
|
||||
|
||||
if ((strategy != s->strategy || func != configuration_table[level].func) &&
|
||||
s->high_water) {
|
||||
s->last_flush != -2) {
|
||||
/* Flush the last buffer: */
|
||||
int err = deflate(strm, Z_BLOCK);
|
||||
if (err == Z_STREAM_ERROR)
|
||||
return err;
|
||||
if (strm->avail_out == 0)
|
||||
if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
|
||||
return Z_BUF_ERROR;
|
||||
}
|
||||
if (s->level != level) {
|
||||
|
@ -633,36 +670,50 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
|
|||
}
|
||||
|
||||
/* =========================================================================
|
||||
* For the default windowBits of 15 and memLevel of 8, this function returns
|
||||
* a close to exact, as well as small, upper bound on the compressed size.
|
||||
* They are coded as constants here for a reason--if the #define's are
|
||||
* changed, then this function needs to be changed as well. The return
|
||||
* value for 15 and 8 only works for those exact settings.
|
||||
* For the default windowBits of 15 and memLevel of 8, this function returns a
|
||||
* close to exact, as well as small, upper bound on the compressed size. This
|
||||
* is an expansion of ~0.03%, plus a small constant.
|
||||
*
|
||||
* For any setting other than those defaults for windowBits and memLevel,
|
||||
* the value returned is a conservative worst case for the maximum expansion
|
||||
* resulting from using fixed blocks instead of stored blocks, which deflate
|
||||
* can emit on compressed data for some combinations of the parameters.
|
||||
* For any setting other than those defaults for windowBits and memLevel, one
|
||||
* of two worst case bounds is returned. This is at most an expansion of ~4% or
|
||||
* ~13%, plus a small constant.
|
||||
*
|
||||
* This function could be more sophisticated to provide closer upper bounds for
|
||||
* every combination of windowBits and memLevel. But even the conservative
|
||||
* upper bound of about 14% expansion does not seem onerous for output buffer
|
||||
* allocation.
|
||||
* Both the 0.03% and 4% derive from the overhead of stored blocks. The first
|
||||
* one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second
|
||||
* is for stored blocks of 127 bytes (the worst case memLevel == 1). The
|
||||
* expansion results from five bytes of header for each stored block.
|
||||
*
|
||||
* The larger expansion of 13% results from a window size less than or equal to
|
||||
* the symbols buffer size (windowBits <= memLevel + 7). In that case some of
|
||||
* the data being compressed may have slid out of the sliding window, impeding
|
||||
* a stored block from being emitted. Then the only choice is a fixed or
|
||||
* dynamic block, where a fixed block limits the maximum expansion to 9 bits
|
||||
* per 8-bit byte, plus 10 bits for every block. The smallest block size for
|
||||
* which this can occur is 255 (memLevel == 2).
|
||||
*
|
||||
* Shifts are used to approximate divisions, for speed.
|
||||
*/
|
||||
uLong ZEXPORT deflateBound(strm, sourceLen)
|
||||
z_streamp strm;
|
||||
uLong sourceLen;
|
||||
{
|
||||
deflate_state *s;
|
||||
uLong complen, wraplen;
|
||||
uLong fixedlen, storelen, wraplen;
|
||||
|
||||
/* conservative upper bound for compressed data */
|
||||
complen = sourceLen +
|
||||
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
|
||||
/* upper bound for fixed blocks with 9-bit literals and length 255
|
||||
(memLevel == 2, which is the lowest that may not use stored blocks) --
|
||||
~13% overhead plus a small constant */
|
||||
fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) +
|
||||
(sourceLen >> 9) + 4;
|
||||
|
||||
/* if can't get parameters, return conservative bound plus zlib wrapper */
|
||||
/* upper bound for stored blocks with length 127 (memLevel == 1) --
|
||||
~4% overhead plus a small constant */
|
||||
storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) +
|
||||
(sourceLen >> 11) + 7;
|
||||
|
||||
/* if can't get parameters, return larger bound plus a zlib wrapper */
|
||||
if (deflateStateCheck(strm))
|
||||
return complen + 6;
|
||||
return (fixedlen > storelen ? fixedlen : storelen) + 6;
|
||||
|
||||
/* compute wrapper length */
|
||||
s = strm->state;
|
||||
|
@ -699,11 +750,12 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
|
|||
wraplen = 6;
|
||||
}
|
||||
|
||||
/* if not default parameters, return conservative bound */
|
||||
/* if not default parameters, return one of the conservative bounds */
|
||||
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
|
||||
return complen + wraplen;
|
||||
return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen;
|
||||
|
||||
/* default settings: return tight bound for that case */
|
||||
/* default settings: return tight bound for that case -- ~0.03% overhead
|
||||
plus a small constant */
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13 - 6 + wraplen;
|
||||
}
|
||||
|
@ -713,7 +765,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
|
|||
* IN assertion: the stream state is correct and there is enough room in
|
||||
* pending_buf.
|
||||
*/
|
||||
local void putShortMSB (s, b)
|
||||
local void putShortMSB(s, b)
|
||||
deflate_state *s;
|
||||
uInt b;
|
||||
{
|
||||
|
@ -760,7 +812,7 @@ local void flush_pending(strm)
|
|||
} while (0)
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflate (strm, flush)
|
||||
int ZEXPORT deflate(strm, flush)
|
||||
z_streamp strm;
|
||||
int flush;
|
||||
{
|
||||
|
@ -811,9 +863,11 @@ int ZEXPORT deflate (strm, flush)
|
|||
}
|
||||
|
||||
/* Write the header */
|
||||
if (s->status == INIT_STATE && s->wrap == 0)
|
||||
s->status = BUSY_STATE;
|
||||
if (s->status == INIT_STATE) {
|
||||
/* zlib header */
|
||||
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
|
||||
uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8;
|
||||
uInt level_flags;
|
||||
|
||||
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
|
||||
|
@ -1073,7 +1127,7 @@ int ZEXPORT deflate (strm, flush)
|
|||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int ZEXPORT deflateEnd (strm)
|
||||
int ZEXPORT deflateEnd(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
int status;
|
||||
|
@ -1099,7 +1153,7 @@ int ZEXPORT deflateEnd (strm)
|
|||
* To simplify the source, this is not supported for 16-bit MSDOS (which
|
||||
* doesn't have enough memory anyway to duplicate compression states).
|
||||
*/
|
||||
int ZEXPORT deflateCopy (dest, source)
|
||||
int ZEXPORT deflateCopy(dest, source)
|
||||
z_streamp dest;
|
||||
z_streamp source;
|
||||
{
|
||||
|
@ -1108,7 +1162,6 @@ int ZEXPORT deflateCopy (dest, source)
|
|||
#else
|
||||
deflate_state *ds;
|
||||
deflate_state *ss;
|
||||
ushf *overlay;
|
||||
|
||||
|
||||
if (deflateStateCheck(source) || dest == Z_NULL) {
|
||||
|
@ -1128,8 +1181,7 @@ int ZEXPORT deflateCopy (dest, source)
|
|||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
|
||||
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
|
||||
overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
|
||||
ds->pending_buf = (uchf *) overlay;
|
||||
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
|
||||
|
||||
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
|
||||
ds->pending_buf == Z_NULL) {
|
||||
|
@ -1143,8 +1195,7 @@ int ZEXPORT deflateCopy (dest, source)
|
|||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||
|
||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||
ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
|
||||
ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
|
||||
ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
|
||||
|
||||
ds->l_desc.dyn_tree = ds->dyn_ltree;
|
||||
ds->d_desc.dyn_tree = ds->dyn_dtree;
|
||||
|
@ -1191,7 +1242,7 @@ local unsigned read_buf(strm, buf, size)
|
|||
/* ===========================================================================
|
||||
* Initialize the "longest match" routines for a new zlib stream
|
||||
*/
|
||||
local void lm_init (s)
|
||||
local void lm_init(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
s->window_size = (ulg)2L*s->w_size;
|
||||
|
@ -1212,11 +1263,6 @@ local void lm_init (s)
|
|||
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||
s->match_available = 0;
|
||||
s->ins_h = 0;
|
||||
#ifndef FASTEST
|
||||
#ifdef ASMV
|
||||
match_init(); /* initialize the asm code */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef FASTEST
|
||||
|
@ -1229,10 +1275,6 @@ local void lm_init (s)
|
|||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
* OUT assertion: the match length is not greater than s->lookahead.
|
||||
*/
|
||||
#ifndef ASMV
|
||||
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
|
||||
* match.S. The code will be functionally equivalent.
|
||||
*/
|
||||
local uInt longest_match(s, cur_match)
|
||||
deflate_state *s;
|
||||
IPos cur_match; /* current match */
|
||||
|
@ -1257,10 +1299,10 @@ local uInt longest_match(s, cur_match)
|
|||
*/
|
||||
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
|
||||
register ush scan_start = *(ushf*)scan;
|
||||
register ush scan_end = *(ushf*)(scan+best_len-1);
|
||||
register ush scan_end = *(ushf*)(scan + best_len - 1);
|
||||
#else
|
||||
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
||||
register Byte scan_end1 = scan[best_len-1];
|
||||
register Byte scan_end1 = scan[best_len - 1];
|
||||
register Byte scan_end = scan[best_len];
|
||||
#endif
|
||||
|
||||
|
@ -1278,7 +1320,8 @@ local uInt longest_match(s, cur_match)
|
|||
*/
|
||||
if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||||
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"need lookahead");
|
||||
|
||||
do {
|
||||
Assert(cur_match < s->strstart, "no future");
|
||||
|
@ -1296,43 +1339,44 @@ local uInt longest_match(s, cur_match)
|
|||
/* This code assumes sizeof(unsigned short) == 2. Do not use
|
||||
* UNALIGNED_OK if your compiler uses a different size.
|
||||
*/
|
||||
if (*(ushf*)(match+best_len-1) != scan_end ||
|
||||
if (*(ushf*)(match + best_len - 1) != scan_end ||
|
||||
*(ushf*)match != scan_start) continue;
|
||||
|
||||
/* It is not necessary to compare scan[2] and match[2] since they are
|
||||
* always equal when the other bytes match, given that the hash keys
|
||||
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
|
||||
* strstart+3, +5, ... up to strstart+257. We check for insufficient
|
||||
* strstart + 3, + 5, up to strstart + 257. We check for insufficient
|
||||
* lookahead only every 4th comparison; the 128th check will be made
|
||||
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
|
||||
* at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is
|
||||
* necessary to put more guard bytes at the end of the window, or
|
||||
* to check more often for insufficient lookahead.
|
||||
*/
|
||||
Assert(scan[2] == match[2], "scan[2]?");
|
||||
scan++, match++;
|
||||
do {
|
||||
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
||||
} while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
*(ushf*)(scan += 2) == *(ushf*)(match += 2) &&
|
||||
scan < strend);
|
||||
/* The funny "do {}" generates better code on most compilers */
|
||||
|
||||
/* Here, scan <= window+strstart+257 */
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
/* Here, scan <= window + strstart + 257 */
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1),
|
||||
"wild scan");
|
||||
if (*scan == *match) scan++;
|
||||
|
||||
len = (MAX_MATCH - 1) - (int)(strend-scan);
|
||||
len = (MAX_MATCH - 1) - (int)(strend - scan);
|
||||
scan = strend - (MAX_MATCH-1);
|
||||
|
||||
#else /* UNALIGNED_OK */
|
||||
|
||||
if (match[best_len] != scan_end ||
|
||||
match[best_len-1] != scan_end1 ||
|
||||
*match != *scan ||
|
||||
*++match != scan[1]) continue;
|
||||
if (match[best_len] != scan_end ||
|
||||
match[best_len - 1] != scan_end1 ||
|
||||
*match != *scan ||
|
||||
*++match != scan[1]) continue;
|
||||
|
||||
/* The check at best_len-1 can be removed because it will be made
|
||||
/* The check at best_len - 1 can be removed because it will be made
|
||||
* again later. (This heuristic is not always a win.)
|
||||
* It is not necessary to compare scan[2] and match[2] since they
|
||||
* are always equal when the other bytes match, given that
|
||||
|
@ -1342,7 +1386,7 @@ local uInt longest_match(s, cur_match)
|
|||
Assert(*scan == *match, "match[2]?");
|
||||
|
||||
/* We check for insufficient lookahead only every 8th comparison;
|
||||
* the 256th check will be made at strstart+258.
|
||||
* the 256th check will be made at strstart + 258.
|
||||
*/
|
||||
do {
|
||||
} while (*++scan == *++match && *++scan == *++match &&
|
||||
|
@ -1351,7 +1395,8 @@ local uInt longest_match(s, cur_match)
|
|||
*++scan == *++match && *++scan == *++match &&
|
||||
scan < strend);
|
||||
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1),
|
||||
"wild scan");
|
||||
|
||||
len = MAX_MATCH - (int)(strend - scan);
|
||||
scan = strend - MAX_MATCH;
|
||||
|
@ -1363,9 +1408,9 @@ local uInt longest_match(s, cur_match)
|
|||
best_len = len;
|
||||
if (len >= nice_match) break;
|
||||
#ifdef UNALIGNED_OK
|
||||
scan_end = *(ushf*)(scan+best_len-1);
|
||||
scan_end = *(ushf*)(scan + best_len - 1);
|
||||
#else
|
||||
scan_end1 = scan[best_len-1];
|
||||
scan_end1 = scan[best_len - 1];
|
||||
scan_end = scan[best_len];
|
||||
#endif
|
||||
}
|
||||
|
@ -1375,7 +1420,6 @@ local uInt longest_match(s, cur_match)
|
|||
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
|
||||
return s->lookahead;
|
||||
}
|
||||
#endif /* ASMV */
|
||||
|
||||
#else /* FASTEST */
|
||||
|
||||
|
@ -1396,7 +1440,8 @@ local uInt longest_match(s, cur_match)
|
|||
*/
|
||||
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||||
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"need lookahead");
|
||||
|
||||
Assert(cur_match < s->strstart, "no future");
|
||||
|
||||
|
@ -1406,7 +1451,7 @@ local uInt longest_match(s, cur_match)
|
|||
*/
|
||||
if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
|
||||
|
||||
/* The check at best_len-1 can be removed because it will be made
|
||||
/* The check at best_len - 1 can be removed because it will be made
|
||||
* again later. (This heuristic is not always a win.)
|
||||
* It is not necessary to compare scan[2] and match[2] since they
|
||||
* are always equal when the other bytes match, given that
|
||||
|
@ -1416,7 +1461,7 @@ local uInt longest_match(s, cur_match)
|
|||
Assert(*scan == *match, "match[2]?");
|
||||
|
||||
/* We check for insufficient lookahead only every 8th comparison;
|
||||
* the 256th check will be made at strstart+258.
|
||||
* the 256th check will be made at strstart + 258.
|
||||
*/
|
||||
do {
|
||||
} while (*++scan == *++match && *++scan == *++match &&
|
||||
|
@ -1425,7 +1470,7 @@ local uInt longest_match(s, cur_match)
|
|||
*++scan == *++match && *++scan == *++match &&
|
||||
scan < strend);
|
||||
|
||||
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan");
|
||||
|
||||
len = MAX_MATCH - (int)(strend - scan);
|
||||
|
||||
|
@ -1461,7 +1506,7 @@ local void check_match(s, start, match, length)
|
|||
z_error("invalid match");
|
||||
}
|
||||
if (z_verbose > 1) {
|
||||
fprintf(stderr,"\\[%d,%d]", start-match, length);
|
||||
fprintf(stderr,"\\[%d,%d]", start - match, length);
|
||||
do { putc(s->window[start++], stderr); } while (--length != 0);
|
||||
}
|
||||
}
|
||||
|
@ -1507,12 +1552,14 @@ local void fill_window(s)
|
|||
/* If the window is almost full and there is insufficient lookahead,
|
||||
* move the upper half to the lower one to make room in the upper half.
|
||||
*/
|
||||
if (s->strstart >= wsize+MAX_DIST(s)) {
|
||||
if (s->strstart >= wsize + MAX_DIST(s)) {
|
||||
|
||||
zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
|
||||
zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more);
|
||||
s->match_start -= wsize;
|
||||
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
|
||||
s->block_start -= (long) wsize;
|
||||
if (s->insert > s->strstart)
|
||||
s->insert = s->strstart;
|
||||
slide_hash(s);
|
||||
more += wsize;
|
||||
}
|
||||
|
@ -1638,7 +1685,7 @@ local void fill_window(s)
|
|||
*
|
||||
* deflate_stored() is written to minimize the number of times an input byte is
|
||||
* copied. It is most efficient with large input and output buffers, which
|
||||
* maximizes the opportunites to have a single copy from next_in to next_out.
|
||||
* maximizes the opportunities to have a single copy from next_in to next_out.
|
||||
*/
|
||||
local block_state deflate_stored(s, flush)
|
||||
deflate_state *s;
|
||||
|
@ -1742,6 +1789,7 @@ local block_state deflate_stored(s, flush)
|
|||
s->matches = 2; /* clear hash */
|
||||
zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
|
||||
s->strstart = s->w_size;
|
||||
s->insert = s->strstart;
|
||||
}
|
||||
else {
|
||||
if (s->window_size - s->strstart <= used) {
|
||||
|
@ -1750,12 +1798,14 @@ local block_state deflate_stored(s, flush)
|
|||
zmemcpy(s->window, s->window + s->w_size, s->strstart);
|
||||
if (s->matches < 2)
|
||||
s->matches++; /* add a pending slide_hash() */
|
||||
if (s->insert > s->strstart)
|
||||
s->insert = s->strstart;
|
||||
}
|
||||
zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
|
||||
s->strstart += used;
|
||||
s->insert += MIN(used, s->w_size - s->insert);
|
||||
}
|
||||
s->block_start = s->strstart;
|
||||
s->insert += MIN(used, s->w_size - s->insert);
|
||||
}
|
||||
if (s->high_water < s->strstart)
|
||||
s->high_water = s->strstart;
|
||||
|
@ -1770,7 +1820,7 @@ local block_state deflate_stored(s, flush)
|
|||
return block_done;
|
||||
|
||||
/* Fill the window with any remaining input. */
|
||||
have = s->window_size - s->strstart - 1;
|
||||
have = s->window_size - s->strstart;
|
||||
if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
|
||||
/* Slide the window down. */
|
||||
s->block_start -= s->w_size;
|
||||
|
@ -1779,12 +1829,15 @@ local block_state deflate_stored(s, flush)
|
|||
if (s->matches < 2)
|
||||
s->matches++; /* add a pending slide_hash() */
|
||||
have += s->w_size; /* more space now */
|
||||
if (s->insert > s->strstart)
|
||||
s->insert = s->strstart;
|
||||
}
|
||||
if (have > s->strm->avail_in)
|
||||
have = s->strm->avail_in;
|
||||
if (have) {
|
||||
read_buf(s->strm, s->window + s->strstart, have);
|
||||
s->strstart += have;
|
||||
s->insert += MIN(have, s->w_size - s->insert);
|
||||
}
|
||||
if (s->high_water < s->strstart)
|
||||
s->high_water = s->strstart;
|
||||
|
@ -1842,7 +1895,7 @@ local block_state deflate_fast(s, flush)
|
|||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
/* Insert the string window[strstart .. strstart + 2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
hash_head = NIL;
|
||||
|
@ -1890,7 +1943,7 @@ local block_state deflate_fast(s, flush)
|
|||
s->strstart += s->match_length;
|
||||
s->match_length = 0;
|
||||
s->ins_h = s->window[s->strstart];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]);
|
||||
#if MIN_MATCH != 3
|
||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||
#endif
|
||||
|
@ -1901,7 +1954,7 @@ local block_state deflate_fast(s, flush)
|
|||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
|
@ -1912,7 +1965,7 @@ local block_state deflate_fast(s, flush)
|
|||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
@ -1945,7 +1998,7 @@ local block_state deflate_slow(s, flush)
|
|||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
|
||||
/* Insert the string window[strstart .. strstart+2] in the
|
||||
/* Insert the string window[strstart .. strstart + 2] in the
|
||||
* dictionary, and set hash_head to the head of the hash chain:
|
||||
*/
|
||||
hash_head = NIL;
|
||||
|
@ -1987,17 +2040,17 @@ local block_state deflate_slow(s, flush)
|
|||
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
|
||||
/* Do not insert strings in hash table beyond this. */
|
||||
|
||||
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
|
||||
check_match(s, s->strstart - 1, s->prev_match, s->prev_length);
|
||||
|
||||
_tr_tally_dist(s, s->strstart -1 - s->prev_match,
|
||||
_tr_tally_dist(s, s->strstart - 1 - s->prev_match,
|
||||
s->prev_length - MIN_MATCH, bflush);
|
||||
|
||||
/* Insert in hash table all strings up to the end of the match.
|
||||
* strstart-1 and strstart are already inserted. If there is not
|
||||
* strstart - 1 and strstart are already inserted. If there is not
|
||||
* enough lookahead, the last two strings are not inserted in
|
||||
* the hash table.
|
||||
*/
|
||||
s->lookahead -= s->prev_length-1;
|
||||
s->lookahead -= s->prev_length - 1;
|
||||
s->prev_length -= 2;
|
||||
do {
|
||||
if (++s->strstart <= max_insert) {
|
||||
|
@ -2015,8 +2068,8 @@ local block_state deflate_slow(s, flush)
|
|||
* single literal. If there was a match but the current match
|
||||
* is longer, truncate the previous match to a single literal.
|
||||
*/
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
Tracevv((stderr,"%c", s->window[s->strstart - 1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart - 1], bflush);
|
||||
if (bflush) {
|
||||
FLUSH_BLOCK_ONLY(s, 0);
|
||||
}
|
||||
|
@ -2034,8 +2087,8 @@ local block_state deflate_slow(s, flush)
|
|||
}
|
||||
Assert (flush != Z_NO_FLUSH, "no flush?");
|
||||
if (s->match_available) {
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||
Tracevv((stderr,"%c", s->window[s->strstart - 1]));
|
||||
_tr_tally_lit(s, s->window[s->strstart - 1], bflush);
|
||||
s->match_available = 0;
|
||||
}
|
||||
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||
|
@ -2043,7 +2096,7 @@ local block_state deflate_slow(s, flush)
|
|||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
@ -2092,7 +2145,8 @@ local block_state deflate_rle(s, flush)
|
|||
if (s->match_length > s->lookahead)
|
||||
s->match_length = s->lookahead;
|
||||
}
|
||||
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||||
Assert(scan <= s->window + (uInt)(s->window_size - 1),
|
||||
"wild scan");
|
||||
}
|
||||
|
||||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||||
|
@ -2107,7 +2161,7 @@ local block_state deflate_rle(s, flush)
|
|||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
|
@ -2118,7 +2172,7 @@ local block_state deflate_rle(s, flush)
|
|||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
@ -2147,7 +2201,7 @@ local block_state deflate_huff(s, flush)
|
|||
/* Output a literal byte */
|
||||
s->match_length = 0;
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
_tr_tally_lit(s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
|
@ -2157,7 +2211,7 @@ local block_state deflate_huff(s, flush)
|
|||
FLUSH_BLOCK(s, 1);
|
||||
return finish_done;
|
||||
}
|
||||
if (s->last_lit)
|
||||
if (s->sym_next)
|
||||
FLUSH_BLOCK(s, 0);
|
||||
return block_done;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2016 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2018 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -217,7 +217,7 @@ typedef struct internal_state {
|
|||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
uchf *l_buf; /* buffer for literals or lengths */
|
||||
uchf *sym_buf; /* buffer for distances and literals/lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
|
@ -239,13 +239,8 @@ typedef struct internal_state {
|
|||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
uInt last_lit; /* running index in l_buf */
|
||||
|
||||
ushf *d_buf;
|
||||
/* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
* the same number of elements. To use different lengths, an extra flag
|
||||
* array would be necessary.
|
||||
*/
|
||||
uInt sym_next; /* running index in sym_buf */
|
||||
uInt sym_end; /* symbol table full when sym_next reaches this */
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
|
@ -325,20 +320,22 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
|||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
{ uch cc = (c); \
|
||||
s->d_buf[s->last_lit] = 0; \
|
||||
s->l_buf[s->last_lit++] = cc; \
|
||||
s->sym_buf[s->sym_next++] = 0; \
|
||||
s->sym_buf[s->sym_next++] = 0; \
|
||||
s->sym_buf[s->sym_next++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (uch)(length); \
|
||||
ush dist = (ush)(distance); \
|
||||
s->d_buf[s->last_lit] = dist; \
|
||||
s->l_buf[s->last_lit++] = len; \
|
||||
s->sym_buf[s->sym_next++] = (uch)dist; \
|
||||
s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \
|
||||
s->sym_buf[s->sym_next++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
#else
|
||||
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
|
|
BIN
zlib/doc/crc-doc.1.0.pdf
Normal file
BIN
zlib/doc/crc-doc.1.0.pdf
Normal file
Binary file not shown.
|
@ -38,15 +38,15 @@ The Algorithm
|
|||
|
||||
The algorithm works by dividing the set of bytecodes [0..255] into three
|
||||
categories:
|
||||
- The white list of textual bytecodes:
|
||||
- The allow list of textual bytecodes:
|
||||
9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
|
||||
- The gray list of tolerated bytecodes:
|
||||
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
|
||||
- The black list of undesired, non-textual bytecodes:
|
||||
- The block list of undesired, non-textual bytecodes:
|
||||
0 (NUL) to 6, 14 to 31.
|
||||
|
||||
If a file contains at least one byte that belongs to the white list and
|
||||
no byte that belongs to the black list, then the file is categorized as
|
||||
If a file contains at least one byte that belongs to the allow list and
|
||||
no byte that belongs to the block list, then the file is categorized as
|
||||
plain text; otherwise, it is categorized as binary. (The boundary case,
|
||||
when the file is empty, automatically falls into the latter category.)
|
||||
|
||||
|
@ -84,9 +84,9 @@ consistent results, regardless what alphabet encoding is being used.
|
|||
results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
|
||||
|
||||
There is an extra category of plain text files that are "polluted" with
|
||||
one or more black-listed codes, either by mistake or by peculiar design
|
||||
one or more block-listed codes, either by mistake or by peculiar design
|
||||
considerations. In such cases, a scheme that tolerates a small fraction
|
||||
of black-listed codes would provide an increased recall (i.e. more true
|
||||
of block-listed codes would provide an increased recall (i.e. more true
|
||||
positives). This, however, incurs a reduced precision overall, since
|
||||
false positives are more likely to appear in binary files that contain
|
||||
large chunks of textual data. Furthermore, "polluted" plain text should
|
||||
|
|
|
@ -34,6 +34,10 @@ gzlog.h
|
|||
and deflateSetDictionary()
|
||||
- illustrates use of a gzip header extra field
|
||||
|
||||
gznorm.c
|
||||
normalize a gzip file by combining members into a single member
|
||||
- demonstrates how to concatenate deflate streams using Z_BLOCK
|
||||
|
||||
zlib_how.html
|
||||
painfully comprehensive description of zpipe.c (see below)
|
||||
- describes in excruciating detail the use of deflate() and inflate()
|
||||
|
@ -44,6 +48,7 @@ zpipe.c
|
|||
- deeply commented in zlib_how.html (see above)
|
||||
|
||||
zran.c
|
||||
zran.h
|
||||
index a zlib or gzip stream and randomly access it
|
||||
- illustrates the use of Z_BLOCK, inflatePrime(), and
|
||||
inflateSetDictionary() to provide random access
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* enough.c -- determine the maximum size of inflate's Huffman code tables over
|
||||
* all possible valid and complete Huffman codes, subject to a length limit.
|
||||
* Copyright (C) 2007, 2008, 2012 Mark Adler
|
||||
* Version 1.4 18 August 2012 Mark Adler
|
||||
* all possible valid and complete prefix codes, subject to a length limit.
|
||||
* Copyright (C) 2007, 2008, 2012, 2018 Mark Adler
|
||||
* Version 1.5 5 August 2018 Mark Adler
|
||||
*/
|
||||
|
||||
/* Version history:
|
||||
|
@ -17,101 +17,107 @@
|
|||
1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
|
||||
Clean up comparisons of different types
|
||||
Clean up code indentation
|
||||
1.5 5 Aug 2018 Clean up code style, formatting, and comments
|
||||
Show all the codes for the maximum, and only the maximum
|
||||
*/
|
||||
|
||||
/*
|
||||
Examine all possible Huffman codes for a given number of symbols and a
|
||||
maximum code length in bits to determine the maximum table size for zilb's
|
||||
inflate. Only complete Huffman codes are counted.
|
||||
Examine all possible prefix codes for a given number of symbols and a
|
||||
maximum code length in bits to determine the maximum table size for zlib's
|
||||
inflate. Only complete prefix codes are counted.
|
||||
|
||||
Two codes are considered distinct if the vectors of the number of codes per
|
||||
length are not identical. So permutations of the symbol assignments result
|
||||
length are not identical. So permutations of the symbol assignments result
|
||||
in the same code for the counting, as do permutations of the assignments of
|
||||
the bit values to the codes (i.e. only canonical codes are counted).
|
||||
|
||||
We build a code from shorter to longer lengths, determining how many symbols
|
||||
are coded at each length. At each step, we have how many symbols remain to
|
||||
are coded at each length. At each step, we have how many symbols remain to
|
||||
be coded, what the last code length used was, and how many bit patterns of
|
||||
that length remain unused. Then we add one to the code length and double the
|
||||
number of unused patterns to graduate to the next code length. We then
|
||||
number of unused patterns to graduate to the next code length. We then
|
||||
assign all portions of the remaining symbols to that code length that
|
||||
preserve the properties of a correct and eventually complete code. Those
|
||||
preserve the properties of a correct and eventually complete code. Those
|
||||
properties are: we cannot use more bit patterns than are available; and when
|
||||
all the symbols are used, there are exactly zero possible bit patterns
|
||||
remaining.
|
||||
all the symbols are used, there are exactly zero possible bit patterns left
|
||||
unused.
|
||||
|
||||
The inflate Huffman decoding algorithm uses two-level lookup tables for
|
||||
speed. There is a single first-level table to decode codes up to root bits
|
||||
in length (root == 9 in the current inflate implementation). The table
|
||||
has 1 << root entries and is indexed by the next root bits of input. Codes
|
||||
shorter than root bits have replicated table entries, so that the correct
|
||||
entry is pointed to regardless of the bits that follow the short code. If
|
||||
the code is longer than root bits, then the table entry points to a second-
|
||||
level table. The size of that table is determined by the longest code with
|
||||
that root-bit prefix. If that longest code has length len, then the table
|
||||
has size 1 << (len - root), to index the remaining bits in that set of
|
||||
codes. Each subsequent root-bit prefix then has its own sub-table. The
|
||||
total number of table entries required by the code is calculated
|
||||
incrementally as the number of codes at each bit length is populated. When
|
||||
all of the codes are shorter than root bits, then root is reduced to the
|
||||
longest code length, resulting in a single, smaller, one-level table.
|
||||
speed. There is a single first-level table to decode codes up to root bits
|
||||
in length (root == 9 for literal/length codes and root == 6 for distance
|
||||
codes, in the current inflate implementation). The base table has 1 << root
|
||||
entries and is indexed by the next root bits of input. Codes shorter than
|
||||
root bits have replicated table entries, so that the correct entry is
|
||||
pointed to regardless of the bits that follow the short code. If the code is
|
||||
longer than root bits, then the table entry points to a second-level table.
|
||||
The size of that table is determined by the longest code with that root-bit
|
||||
prefix. If that longest code has length len, then the table has size 1 <<
|
||||
(len - root), to index the remaining bits in that set of codes. Each
|
||||
subsequent root-bit prefix then has its own sub-table. The total number of
|
||||
table entries required by the code is calculated incrementally as the number
|
||||
of codes at each bit length is populated. When all of the codes are shorter
|
||||
than root bits, then root is reduced to the longest code length, resulting
|
||||
in a single, smaller, one-level table.
|
||||
|
||||
The inflate algorithm also provides for small values of root (relative to
|
||||
the log2 of the number of symbols), where the shortest code has more bits
|
||||
than root. In that case, root is increased to the length of the shortest
|
||||
code. This program, by design, does not handle that case, so it is verified
|
||||
that the number of symbols is less than 2^(root + 1).
|
||||
than root. In that case, root is increased to the length of the shortest
|
||||
code. This program, by design, does not handle that case, so it is verified
|
||||
that the number of symbols is less than 1 << (root + 1).
|
||||
|
||||
In order to speed up the examination (by about ten orders of magnitude for
|
||||
the default arguments), the intermediate states in the build-up of a code
|
||||
are remembered and previously visited branches are pruned. The memory
|
||||
are remembered and previously visited branches are pruned. The memory
|
||||
required for this will increase rapidly with the total number of symbols and
|
||||
the maximum code length in bits. However this is a very small price to pay
|
||||
the maximum code length in bits. However this is a very small price to pay
|
||||
for the vast speedup.
|
||||
|
||||
First, all of the possible Huffman codes are counted, and reachable
|
||||
First, all of the possible prefix codes are counted, and reachable
|
||||
intermediate states are noted by a non-zero count in a saved-results array.
|
||||
Second, the intermediate states that lead to (root + 1) bit or longer codes
|
||||
are used to look at all sub-codes from those junctures for their inflate
|
||||
memory usage. (The amount of memory used is not affected by the number of
|
||||
memory usage. (The amount of memory used is not affected by the number of
|
||||
codes of root bits or less in length.) Third, the visited states in the
|
||||
construction of those sub-codes and the associated calculation of the table
|
||||
size is recalled in order to avoid recalculating from the same juncture.
|
||||
Beginning the code examination at (root + 1) bit codes, which is enabled by
|
||||
identifying the reachable nodes, accounts for about six of the orders of
|
||||
magnitude of improvement for the default arguments. About another four
|
||||
orders of magnitude come from not revisiting previous states. Out of
|
||||
approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
|
||||
magnitude of improvement for the default arguments. About another four
|
||||
orders of magnitude come from not revisiting previous states. Out of
|
||||
approximately 2x10^16 possible prefix codes, only about 2x10^6 sub-codes
|
||||
need to be examined to cover all of the possible table memory usage cases
|
||||
for the default arguments of 286 symbols limited to 15-bit codes.
|
||||
|
||||
Note that an unsigned long long type is used for counting. It is quite easy
|
||||
to exceed the capacity of an eight-byte integer with a large number of
|
||||
symbols and a large maximum code length, so multiple-precision arithmetic
|
||||
would need to replace the unsigned long long arithmetic in that case. This
|
||||
program will abort if an overflow occurs. The big_t type identifies where
|
||||
the counting takes place.
|
||||
Note that the uintmax_t type is used for counting. It is quite easy to
|
||||
exceed the capacity of an eight-byte integer with a large number of symbols
|
||||
and a large maximum code length, so multiple-precision arithmetic would need
|
||||
to replace the integer arithmetic in that case. This program will abort if
|
||||
an overflow occurs. The big_t type identifies where the counting takes
|
||||
place.
|
||||
|
||||
An unsigned long long type is also used for calculating the number of
|
||||
possible codes remaining at the maximum length. This limits the maximum
|
||||
code length to the number of bits in a long long minus the number of bits
|
||||
needed to represent the symbols in a flat code. The code_t type identifies
|
||||
where the bit pattern counting takes place.
|
||||
The uintmax_t type is also used for calculating the number of possible codes
|
||||
remaining at the maximum length. This limits the maximum code length to the
|
||||
number of bits in a long long minus the number of bits needed to represent
|
||||
the symbols in a flat code. The code_t type identifies where the bit-pattern
|
||||
counting takes place.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define local static
|
||||
|
||||
/* special data types */
|
||||
typedef unsigned long long big_t; /* type for code counting */
|
||||
typedef unsigned long long code_t; /* type for bit pattern counting */
|
||||
struct tab { /* type for been here check */
|
||||
size_t len; /* length of bit vector in char's */
|
||||
char *vec; /* allocated bit vector */
|
||||
// Special data types.
|
||||
typedef uintmax_t big_t; // type for code counting
|
||||
#define PRIbig "ju" // printf format for big_t
|
||||
typedef uintmax_t code_t; // type for bit pattern counting
|
||||
struct tab { // type for been-here check
|
||||
size_t len; // allocated length of bit vector in octets
|
||||
char *vec; // allocated bit vector
|
||||
};
|
||||
|
||||
/* The array for saving results, num[], is indexed with this triplet:
|
||||
|
@ -126,447 +132,466 @@ struct tab { /* type for been here check */
|
|||
left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
|
||||
len: 1..max - 1 (max == maximum code length in bits)
|
||||
|
||||
syms == 2 is not saved since that immediately leads to a single code. left
|
||||
syms == 2 is not saved since that immediately leads to a single code. left
|
||||
must be even, since it represents the number of available bit patterns at
|
||||
the current length, which is double the number at the previous length.
|
||||
left ends at syms-1 since left == syms immediately results in a single code.
|
||||
the current length, which is double the number at the previous length. left
|
||||
ends at syms-1 since left == syms immediately results in a single code.
|
||||
(left > sym is not allowed since that would result in an incomplete code.)
|
||||
len is less than max, since the code completes immediately when len == max.
|
||||
|
||||
The offset into the array is calculated for the three indices with the
|
||||
first one (syms) being outermost, and the last one (len) being innermost.
|
||||
We build the array with length max-1 lists for the len index, with syms-3
|
||||
of those for each symbol. There are totsym-2 of those, with each one
|
||||
varying in length as a function of sym. See the calculation of index in
|
||||
count() for the index, and the calculation of size in main() for the size
|
||||
of the array.
|
||||
The offset into the array is calculated for the three indices with the first
|
||||
one (syms) being outermost, and the last one (len) being innermost. We build
|
||||
the array with length max-1 lists for the len index, with syms-3 of those
|
||||
for each symbol. There are totsym-2 of those, with each one varying in
|
||||
length as a function of sym. See the calculation of index in map() for the
|
||||
index, and the calculation of size in main() for the size of the array.
|
||||
|
||||
For the deflate example of 286 symbols limited to 15-bit codes, the array
|
||||
has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than
|
||||
half of the space allocated for saved results is actually used -- not all
|
||||
possible triplets are reached in the generation of valid Huffman codes.
|
||||
has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than half
|
||||
of the space allocated for saved results is actually used -- not all
|
||||
possible triplets are reached in the generation of valid prefix codes.
|
||||
*/
|
||||
|
||||
/* The array for tracking visited states, done[], is itself indexed identically
|
||||
to the num[] array as described above for the (syms, left, len) triplet.
|
||||
Each element in the array is further indexed by the (mem, rem) doublet,
|
||||
where mem is the amount of inflate table space used so far, and rem is the
|
||||
remaining unused entries in the current inflate sub-table. Each indexed
|
||||
remaining unused entries in the current inflate sub-table. Each indexed
|
||||
element is simply one bit indicating whether the state has been visited or
|
||||
not. Since the ranges for mem and rem are not known a priori, each bit
|
||||
not. Since the ranges for mem and rem are not known a priori, each bit
|
||||
vector is of a variable size, and grows as needed to accommodate the visited
|
||||
states. mem and rem are used to calculate a single index in a triangular
|
||||
array. Since the range of mem is expected in the default case to be about
|
||||
states. mem and rem are used to calculate a single index in a triangular
|
||||
array. Since the range of mem is expected in the default case to be about
|
||||
ten times larger than the range of rem, the array is skewed to reduce the
|
||||
memory usage, with eight times the range for mem than for rem. See the
|
||||
calculations for offset and bit in beenhere() for the details.
|
||||
memory usage, with eight times the range for mem than for rem. See the
|
||||
calculations for offset and bit in been_here() for the details.
|
||||
|
||||
For the deflate example of 286 symbols limited to 15-bit codes, the bit
|
||||
vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
|
||||
array itself.
|
||||
vectors grow to total 5.5 MB, in addition to the 4.3 MB done array itself.
|
||||
*/
|
||||
|
||||
/* Globals to avoid propagating constants or constant pointers recursively */
|
||||
local int max; /* maximum allowed bit length for the codes */
|
||||
local int root; /* size of base code table in bits */
|
||||
local int large; /* largest code table so far */
|
||||
local size_t size; /* number of elements in num and done */
|
||||
local int *code; /* number of symbols assigned to each bit length */
|
||||
local big_t *num; /* saved results array for code counting */
|
||||
local struct tab *done; /* states already evaluated array */
|
||||
// Type for a variable-length, allocated string.
|
||||
typedef struct {
|
||||
char *str; // pointer to allocated string
|
||||
size_t size; // size of allocation
|
||||
size_t len; // length of string, not including terminating zero
|
||||
} string_t;
|
||||
|
||||
/* Index function for num[] and done[] */
|
||||
#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
|
||||
|
||||
/* Free allocated space. Uses globals code, num, and done. */
|
||||
local void cleanup(void)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
if (done != NULL) {
|
||||
for (n = 0; n < size; n++)
|
||||
if (done[n].len)
|
||||
free(done[n].vec);
|
||||
free(done);
|
||||
}
|
||||
if (num != NULL)
|
||||
free(num);
|
||||
if (code != NULL)
|
||||
free(code);
|
||||
// Clear a string_t.
|
||||
local void string_clear(string_t *s) {
|
||||
s->str[0] = 0;
|
||||
s->len = 0;
|
||||
}
|
||||
|
||||
/* Return the number of possible Huffman codes using bit patterns of lengths
|
||||
len through max inclusive, coding syms symbols, with left bit patterns of
|
||||
length len unused -- return -1 if there is an overflow in the counting.
|
||||
Keep a record of previous results in num to prevent repeating the same
|
||||
calculation. Uses the globals max and num. */
|
||||
local big_t count(int syms, int len, int left)
|
||||
{
|
||||
big_t sum; /* number of possible codes from this juncture */
|
||||
big_t got; /* value returned from count() */
|
||||
int least; /* least number of syms to use at this juncture */
|
||||
int most; /* most number of syms to use at this juncture */
|
||||
int use; /* number of bit patterns to use in next call */
|
||||
size_t index; /* index of this case in *num */
|
||||
// Initialize a string_t.
|
||||
local void string_init(string_t *s) {
|
||||
s->size = 16;
|
||||
s->str = malloc(s->size);
|
||||
assert(s->str != NULL && "out of memory");
|
||||
string_clear(s);
|
||||
}
|
||||
|
||||
/* see if only one possible code */
|
||||
// Release the allocation of a string_t.
|
||||
local void string_free(string_t *s) {
|
||||
free(s->str);
|
||||
s->str = NULL;
|
||||
s->size = 0;
|
||||
s->len = 0;
|
||||
}
|
||||
|
||||
// Save the results of printf with fmt and the subsequent argument list to s.
|
||||
// Each call appends to s. The allocated space for s is increased as needed.
|
||||
local void string_printf(string_t *s, char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
size_t len = s->len;
|
||||
int ret = vsnprintf(s->str + len, s->size - len, fmt, ap);
|
||||
assert(ret >= 0 && "out of memory");
|
||||
s->len += ret;
|
||||
if (s->size < s->len + 1) {
|
||||
do {
|
||||
s->size <<= 1;
|
||||
assert(s->size != 0 && "overflow");
|
||||
} while (s->size < s->len + 1);
|
||||
s->str = realloc(s->str, s->size);
|
||||
assert(s->str != NULL && "out of memory");
|
||||
vsnprintf(s->str + len, s->size - len, fmt, ap);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Globals to avoid propagating constants or constant pointers recursively.
|
||||
struct {
|
||||
int max; // maximum allowed bit length for the codes
|
||||
int root; // size of base code table in bits
|
||||
int large; // largest code table so far
|
||||
size_t size; // number of elements in num and done
|
||||
big_t tot; // total number of codes with maximum tables size
|
||||
string_t out; // display of subcodes for maximum tables size
|
||||
int *code; // number of symbols assigned to each bit length
|
||||
big_t *num; // saved results array for code counting
|
||||
struct tab *done; // states already evaluated array
|
||||
} g;
|
||||
|
||||
// Index function for num[] and done[].
|
||||
local inline size_t map(int syms, int left, int len) {
|
||||
return ((size_t)((syms - 1) >> 1) * ((syms - 2) >> 1) +
|
||||
(left >> 1) - 1) * (g.max - 1) +
|
||||
len - 1;
|
||||
}
|
||||
|
||||
// Free allocated space in globals.
|
||||
local void cleanup(void) {
|
||||
if (g.done != NULL) {
|
||||
for (size_t n = 0; n < g.size; n++)
|
||||
if (g.done[n].len)
|
||||
free(g.done[n].vec);
|
||||
g.size = 0;
|
||||
free(g.done); g.done = NULL;
|
||||
}
|
||||
free(g.num); g.num = NULL;
|
||||
free(g.code); g.code = NULL;
|
||||
string_free(&g.out);
|
||||
}
|
||||
|
||||
// Return the number of possible prefix codes using bit patterns of lengths len
|
||||
// through max inclusive, coding syms symbols, with left bit patterns of length
|
||||
// len unused -- return -1 if there is an overflow in the counting. Keep a
|
||||
// record of previous results in num to prevent repeating the same calculation.
|
||||
local big_t count(int syms, int left, int len) {
|
||||
// see if only one possible code
|
||||
if (syms == left)
|
||||
return 1;
|
||||
|
||||
/* note and verify the expected state */
|
||||
assert(syms > left && left > 0 && len < max);
|
||||
// note and verify the expected state
|
||||
assert(syms > left && left > 0 && len < g.max);
|
||||
|
||||
/* see if we've done this one already */
|
||||
index = INDEX(syms, left, len);
|
||||
got = num[index];
|
||||
// see if we've done this one already
|
||||
size_t index = map(syms, left, len);
|
||||
big_t got = g.num[index];
|
||||
if (got)
|
||||
return got; /* we have -- return the saved result */
|
||||
return got; // we have -- return the saved result
|
||||
|
||||
/* we need to use at least this many bit patterns so that the code won't be
|
||||
incomplete at the next length (more bit patterns than symbols) */
|
||||
least = (left << 1) - syms;
|
||||
// we need to use at least this many bit patterns so that the code won't be
|
||||
// incomplete at the next length (more bit patterns than symbols)
|
||||
int least = (left << 1) - syms;
|
||||
if (least < 0)
|
||||
least = 0;
|
||||
|
||||
/* we can use at most this many bit patterns, lest there not be enough
|
||||
available for the remaining symbols at the maximum length (if there were
|
||||
no limit to the code length, this would become: most = left - 1) */
|
||||
most = (((code_t)left << (max - len)) - syms) /
|
||||
(((code_t)1 << (max - len)) - 1);
|
||||
// we can use at most this many bit patterns, lest there not be enough
|
||||
// available for the remaining symbols at the maximum length (if there were
|
||||
// no limit to the code length, this would become: most = left - 1)
|
||||
int most = (((code_t)left << (g.max - len)) - syms) /
|
||||
(((code_t)1 << (g.max - len)) - 1);
|
||||
|
||||
/* count all possible codes from this juncture and add them up */
|
||||
sum = 0;
|
||||
for (use = least; use <= most; use++) {
|
||||
got = count(syms - use, len + 1, (left - use) << 1);
|
||||
// count all possible codes from this juncture and add them up
|
||||
big_t sum = 0;
|
||||
for (int use = least; use <= most; use++) {
|
||||
got = count(syms - use, (left - use) << 1, len + 1);
|
||||
sum += got;
|
||||
if (got == (big_t)0 - 1 || sum < got) /* overflow */
|
||||
return (big_t)0 - 1;
|
||||
if (got == (big_t)-1 || sum < got) // overflow
|
||||
return (big_t)-1;
|
||||
}
|
||||
|
||||
/* verify that all recursive calls are productive */
|
||||
// verify that all recursive calls are productive
|
||||
assert(sum != 0);
|
||||
|
||||
/* save the result and return it */
|
||||
num[index] = sum;
|
||||
// save the result and return it
|
||||
g.num[index] = sum;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Return true if we've been here before, set to true if not. Set a bit in a
|
||||
bit vector to indicate visiting this state. Each (syms,len,left) state
|
||||
has a variable size bit vector indexed by (mem,rem). The bit vector is
|
||||
lengthened if needed to allow setting the (mem,rem) bit. */
|
||||
local int beenhere(int syms, int len, int left, int mem, int rem)
|
||||
{
|
||||
size_t index; /* index for this state's bit vector */
|
||||
size_t offset; /* offset in this state's bit vector */
|
||||
int bit; /* mask for this state's bit */
|
||||
size_t length; /* length of the bit vector in bytes */
|
||||
char *vector; /* new or enlarged bit vector */
|
||||
|
||||
/* point to vector for (syms,left,len), bit in vector for (mem,rem) */
|
||||
index = INDEX(syms, left, len);
|
||||
mem -= 1 << root;
|
||||
offset = (mem >> 3) + rem;
|
||||
// Return true if we've been here before, set to true if not. Set a bit in a
|
||||
// bit vector to indicate visiting this state. Each (syms,len,left) state has a
|
||||
// variable size bit vector indexed by (mem,rem). The bit vector is lengthened
|
||||
// as needed to allow setting the (mem,rem) bit.
|
||||
local int been_here(int syms, int left, int len, int mem, int rem) {
|
||||
// point to vector for (syms,left,len), bit in vector for (mem,rem)
|
||||
size_t index = map(syms, left, len);
|
||||
mem -= 1 << g.root; // mem always includes the root table
|
||||
mem >>= 1; // mem and rem are always even
|
||||
rem >>= 1;
|
||||
size_t offset = (mem >> 3) + rem;
|
||||
offset = ((offset * (offset + 1)) >> 1) + rem;
|
||||
bit = 1 << (mem & 7);
|
||||
int bit = 1 << (mem & 7);
|
||||
|
||||
/* see if we've been here */
|
||||
length = done[index].len;
|
||||
if (offset < length && (done[index].vec[offset] & bit) != 0)
|
||||
return 1; /* done this! */
|
||||
// see if we've been here
|
||||
size_t length = g.done[index].len;
|
||||
if (offset < length && (g.done[index].vec[offset] & bit) != 0)
|
||||
return 1; // done this!
|
||||
|
||||
/* we haven't been here before -- set the bit to show we have now */
|
||||
// we haven't been here before -- set the bit to show we have now
|
||||
|
||||
/* see if we need to lengthen the vector in order to set the bit */
|
||||
// see if we need to lengthen the vector in order to set the bit
|
||||
if (length <= offset) {
|
||||
/* if we have one already, enlarge it, zero out the appended space */
|
||||
// if we have one already, enlarge it, zero out the appended space
|
||||
char *vector;
|
||||
if (length) {
|
||||
do {
|
||||
length <<= 1;
|
||||
} while (length <= offset);
|
||||
vector = realloc(done[index].vec, length);
|
||||
if (vector != NULL)
|
||||
memset(vector + done[index].len, 0, length - done[index].len);
|
||||
vector = realloc(g.done[index].vec, length);
|
||||
assert(vector != NULL && "out of memory");
|
||||
memset(vector + g.done[index].len, 0, length - g.done[index].len);
|
||||
}
|
||||
|
||||
/* otherwise we need to make a new vector and zero it out */
|
||||
// otherwise we need to make a new vector and zero it out
|
||||
else {
|
||||
length = 1 << (len - root);
|
||||
length = 16;
|
||||
while (length <= offset)
|
||||
length <<= 1;
|
||||
vector = calloc(length, sizeof(char));
|
||||
vector = calloc(length, 1);
|
||||
assert(vector != NULL && "out of memory");
|
||||
}
|
||||
|
||||
/* in either case, bail if we can't get the memory */
|
||||
if (vector == NULL) {
|
||||
fputs("abort: unable to allocate enough memory\n", stderr);
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* install the new vector */
|
||||
done[index].len = length;
|
||||
done[index].vec = vector;
|
||||
// install the new vector
|
||||
g.done[index].len = length;
|
||||
g.done[index].vec = vector;
|
||||
}
|
||||
|
||||
/* set the bit */
|
||||
done[index].vec[offset] |= bit;
|
||||
// set the bit
|
||||
g.done[index].vec[offset] |= bit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Examine all possible codes from the given node (syms, len, left). Compute
|
||||
the amount of memory required to build inflate's decoding tables, where the
|
||||
number of code structures used so far is mem, and the number remaining in
|
||||
the current sub-table is rem. Uses the globals max, code, root, large, and
|
||||
done. */
|
||||
local void examine(int syms, int len, int left, int mem, int rem)
|
||||
{
|
||||
int least; /* least number of syms to use at this juncture */
|
||||
int most; /* most number of syms to use at this juncture */
|
||||
int use; /* number of bit patterns to use in next call */
|
||||
|
||||
/* see if we have a complete code */
|
||||
// Examine all possible codes from the given node (syms, len, left). Compute
|
||||
// the amount of memory required to build inflate's decoding tables, where the
|
||||
// number of code structures used so far is mem, and the number remaining in
|
||||
// the current sub-table is rem.
|
||||
local void examine(int syms, int left, int len, int mem, int rem) {
|
||||
// see if we have a complete code
|
||||
if (syms == left) {
|
||||
/* set the last code entry */
|
||||
code[len] = left;
|
||||
// set the last code entry
|
||||
g.code[len] = left;
|
||||
|
||||
/* complete computation of memory used by this code */
|
||||
// complete computation of memory used by this code
|
||||
while (rem < left) {
|
||||
left -= rem;
|
||||
rem = 1 << (len - root);
|
||||
rem = 1 << (len - g.root);
|
||||
mem += rem;
|
||||
}
|
||||
assert(rem == left);
|
||||
|
||||
/* if this is a new maximum, show the entries used and the sub-code */
|
||||
if (mem > large) {
|
||||
large = mem;
|
||||
printf("max %d: ", mem);
|
||||
for (use = root + 1; use <= max; use++)
|
||||
if (code[use])
|
||||
printf("%d[%d] ", code[use], use);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
// if this is at the maximum, show the sub-code
|
||||
if (mem >= g.large) {
|
||||
// if this is a new maximum, update the maximum and clear out the
|
||||
// printed sub-codes from the previous maximum
|
||||
if (mem > g.large) {
|
||||
g.large = mem;
|
||||
string_clear(&g.out);
|
||||
}
|
||||
|
||||
// compute the starting state for this sub-code
|
||||
syms = 0;
|
||||
left = 1 << g.max;
|
||||
for (int bits = g.max; bits > g.root; bits--) {
|
||||
syms += g.code[bits];
|
||||
left -= g.code[bits];
|
||||
assert((left & 1) == 0);
|
||||
left >>= 1;
|
||||
}
|
||||
|
||||
// print the starting state and the resulting sub-code to g.out
|
||||
string_printf(&g.out, "<%u, %u, %u>:",
|
||||
syms, g.root + 1, ((1 << g.root) - left) << 1);
|
||||
for (int bits = g.root + 1; bits <= g.max; bits++)
|
||||
if (g.code[bits])
|
||||
string_printf(&g.out, " %d[%d]", g.code[bits], bits);
|
||||
string_printf(&g.out, "\n");
|
||||
}
|
||||
|
||||
/* remove entries as we drop back down in the recursion */
|
||||
code[len] = 0;
|
||||
// remove entries as we drop back down in the recursion
|
||||
g.code[len] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* prune the tree if we can */
|
||||
if (beenhere(syms, len, left, mem, rem))
|
||||
// prune the tree if we can
|
||||
if (been_here(syms, left, len, mem, rem))
|
||||
return;
|
||||
|
||||
/* we need to use at least this many bit patterns so that the code won't be
|
||||
incomplete at the next length (more bit patterns than symbols) */
|
||||
least = (left << 1) - syms;
|
||||
// we need to use at least this many bit patterns so that the code won't be
|
||||
// incomplete at the next length (more bit patterns than symbols)
|
||||
int least = (left << 1) - syms;
|
||||
if (least < 0)
|
||||
least = 0;
|
||||
|
||||
/* we can use at most this many bit patterns, lest there not be enough
|
||||
available for the remaining symbols at the maximum length (if there were
|
||||
no limit to the code length, this would become: most = left - 1) */
|
||||
most = (((code_t)left << (max - len)) - syms) /
|
||||
(((code_t)1 << (max - len)) - 1);
|
||||
// we can use at most this many bit patterns, lest there not be enough
|
||||
// available for the remaining symbols at the maximum length (if there were
|
||||
// no limit to the code length, this would become: most = left - 1)
|
||||
int most = (((code_t)left << (g.max - len)) - syms) /
|
||||
(((code_t)1 << (g.max - len)) - 1);
|
||||
|
||||
/* occupy least table spaces, creating new sub-tables as needed */
|
||||
use = least;
|
||||
// occupy least table spaces, creating new sub-tables as needed
|
||||
int use = least;
|
||||
while (rem < use) {
|
||||
use -= rem;
|
||||
rem = 1 << (len - root);
|
||||
rem = 1 << (len - g.root);
|
||||
mem += rem;
|
||||
}
|
||||
rem -= use;
|
||||
|
||||
/* examine codes from here, updating table space as we go */
|
||||
// examine codes from here, updating table space as we go
|
||||
for (use = least; use <= most; use++) {
|
||||
code[len] = use;
|
||||
examine(syms - use, len + 1, (left - use) << 1,
|
||||
mem + (rem ? 1 << (len - root) : 0), rem << 1);
|
||||
g.code[len] = use;
|
||||
examine(syms - use, (left - use) << 1, len + 1,
|
||||
mem + (rem ? 1 << (len - g.root) : 0), rem << 1);
|
||||
if (rem == 0) {
|
||||
rem = 1 << (len - root);
|
||||
rem = 1 << (len - g.root);
|
||||
mem += rem;
|
||||
}
|
||||
rem--;
|
||||
}
|
||||
|
||||
/* remove entries as we drop back down in the recursion */
|
||||
code[len] = 0;
|
||||
// remove entries as we drop back down in the recursion
|
||||
g.code[len] = 0;
|
||||
}
|
||||
|
||||
/* Look at all sub-codes starting with root + 1 bits. Look at only the valid
|
||||
intermediate code states (syms, left, len). For each completed code,
|
||||
calculate the amount of memory required by inflate to build the decoding
|
||||
tables. Find the maximum amount of memory required and show the code that
|
||||
requires that maximum. Uses the globals max, root, and num. */
|
||||
local void enough(int syms)
|
||||
{
|
||||
int n; /* number of remaing symbols for this node */
|
||||
int left; /* number of unused bit patterns at this length */
|
||||
size_t index; /* index of this case in *num */
|
||||
// Look at all sub-codes starting with root + 1 bits. Look at only the valid
|
||||
// intermediate code states (syms, left, len). For each completed code,
|
||||
// calculate the amount of memory required by inflate to build the decoding
|
||||
// tables. Find the maximum amount of memory required and show the codes that
|
||||
// require that maximum.
|
||||
local void enough(int syms) {
|
||||
// clear code
|
||||
for (int n = 0; n <= g.max; n++)
|
||||
g.code[n] = 0;
|
||||
|
||||
/* clear code */
|
||||
for (n = 0; n <= max; n++)
|
||||
code[n] = 0;
|
||||
// look at all (root + 1) bit and longer codes
|
||||
string_clear(&g.out); // empty saved results
|
||||
g.large = 1 << g.root; // base table
|
||||
if (g.root < g.max) // otherwise, there's only a base table
|
||||
for (int n = 3; n <= syms; n++)
|
||||
for (int left = 2; left < n; left += 2) {
|
||||
// look at all reachable (root + 1) bit nodes, and the
|
||||
// resulting codes (complete at root + 2 or more)
|
||||
size_t index = map(n, left, g.root + 1);
|
||||
if (g.root + 1 < g.max && g.num[index]) // reachable node
|
||||
examine(n, left, g.root + 1, 1 << g.root, 0);
|
||||
|
||||
/* look at all (root + 1) bit and longer codes */
|
||||
large = 1 << root; /* base table */
|
||||
if (root < max) /* otherwise, there's only a base table */
|
||||
for (n = 3; n <= syms; n++)
|
||||
for (left = 2; left < n; left += 2)
|
||||
{
|
||||
/* look at all reachable (root + 1) bit nodes, and the
|
||||
resulting codes (complete at root + 2 or more) */
|
||||
index = INDEX(n, left, root + 1);
|
||||
if (root + 1 < max && num[index]) /* reachable node */
|
||||
examine(n, root + 1, left, 1 << root, 0);
|
||||
|
||||
/* also look at root bit codes with completions at root + 1
|
||||
bits (not saved in num, since complete), just in case */
|
||||
if (num[index - 1] && n <= left << 1)
|
||||
examine((n - left) << 1, root + 1, (n - left) << 1,
|
||||
1 << root, 0);
|
||||
// also look at root bit codes with completions at root + 1
|
||||
// bits (not saved in num, since complete), just in case
|
||||
if (g.num[index - 1] && n <= left << 1)
|
||||
examine((n - left) << 1, (n - left) << 1, g.root + 1,
|
||||
1 << g.root, 0);
|
||||
}
|
||||
|
||||
/* done */
|
||||
printf("done: maximum of %d table entries\n", large);
|
||||
// done
|
||||
printf("maximum of %d table entries for root = %d\n", g.large, g.root);
|
||||
fputs(g.out.str, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
Examine and show the total number of possible Huffman codes for a given
|
||||
maximum number of symbols, initial root table size, and maximum code length
|
||||
in bits -- those are the command arguments in that order. The default
|
||||
values are 286, 9, and 15 respectively, for the deflate literal/length code.
|
||||
The possible codes are counted for each number of coded symbols from two to
|
||||
the maximum. The counts for each of those and the total number of codes are
|
||||
shown. The maximum number of inflate table entires is then calculated
|
||||
across all possible codes. Each new maximum number of table entries and the
|
||||
associated sub-code (starting at root + 1 == 10 bits) is shown.
|
||||
// Examine and show the total number of possible prefix codes for a given
|
||||
// maximum number of symbols, initial root table size, and maximum code length
|
||||
// in bits -- those are the command arguments in that order. The default values
|
||||
// are 286, 9, and 15 respectively, for the deflate literal/length code. The
|
||||
// possible codes are counted for each number of coded symbols from two to the
|
||||
// maximum. The counts for each of those and the total number of codes are
|
||||
// shown. The maximum number of inflate table entries is then calculated across
|
||||
// all possible codes. Each new maximum number of table entries and the
|
||||
// associated sub-code (starting at root + 1 == 10 bits) is shown.
|
||||
//
|
||||
// To count and examine prefix codes that are not length-limited, provide a
|
||||
// maximum length equal to the number of symbols minus one.
|
||||
//
|
||||
// For the deflate literal/length code, use "enough". For the deflate distance
|
||||
// code, use "enough 30 6".
|
||||
int main(int argc, char **argv) {
|
||||
// set up globals for cleanup()
|
||||
g.code = NULL;
|
||||
g.num = NULL;
|
||||
g.done = NULL;
|
||||
string_init(&g.out);
|
||||
|
||||
To count and examine Huffman codes that are not length-limited, provide a
|
||||
maximum length equal to the number of symbols minus one.
|
||||
|
||||
For the deflate literal/length code, use "enough". For the deflate distance
|
||||
code, use "enough 30 6".
|
||||
|
||||
This uses the %llu printf format to print big_t numbers, which assumes that
|
||||
big_t is an unsigned long long. If the big_t type is changed (for example
|
||||
to a multiple precision type), the method of printing will also need to be
|
||||
updated.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int syms; /* total number of symbols to code */
|
||||
int n; /* number of symbols to code for this run */
|
||||
big_t got; /* return value of count() */
|
||||
big_t sum; /* accumulated number of codes over n */
|
||||
code_t word; /* for counting bits in code_t */
|
||||
|
||||
/* set up globals for cleanup() */
|
||||
code = NULL;
|
||||
num = NULL;
|
||||
done = NULL;
|
||||
|
||||
/* get arguments -- default to the deflate literal/length code */
|
||||
syms = 286;
|
||||
root = 9;
|
||||
max = 15;
|
||||
// get arguments -- default to the deflate literal/length code
|
||||
int syms = 286;
|
||||
g.root = 9;
|
||||
g.max = 15;
|
||||
if (argc > 1) {
|
||||
syms = atoi(argv[1]);
|
||||
if (argc > 2) {
|
||||
root = atoi(argv[2]);
|
||||
g.root = atoi(argv[2]);
|
||||
if (argc > 3)
|
||||
max = atoi(argv[3]);
|
||||
g.max = atoi(argv[3]);
|
||||
}
|
||||
}
|
||||
if (argc > 4 || syms < 2 || root < 1 || max < 1) {
|
||||
if (argc > 4 || syms < 2 || g.root < 1 || g.max < 1) {
|
||||
fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
|
||||
stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if not restricting the code length, the longest is syms - 1 */
|
||||
if (max > syms - 1)
|
||||
max = syms - 1;
|
||||
// if not restricting the code length, the longest is syms - 1
|
||||
if (g.max > syms - 1)
|
||||
g.max = syms - 1;
|
||||
|
||||
/* determine the number of bits in a code_t */
|
||||
for (n = 0, word = 1; word; n++, word <<= 1)
|
||||
;
|
||||
// determine the number of bits in a code_t
|
||||
int bits = 0;
|
||||
for (code_t word = 1; word; word <<= 1)
|
||||
bits++;
|
||||
|
||||
/* make sure that the calculation of most will not overflow */
|
||||
if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
|
||||
// make sure that the calculation of most will not overflow
|
||||
if (g.max > bits || (code_t)(syms - 2) >= ((code_t)-1 >> (g.max - 1))) {
|
||||
fputs("abort: code length too long for internal types\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reject impossible code requests */
|
||||
if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
|
||||
// reject impossible code requests
|
||||
if ((code_t)(syms - 1) > ((code_t)1 << g.max) - 1) {
|
||||
fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
|
||||
syms, max);
|
||||
syms, g.max);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* allocate code vector */
|
||||
code = calloc(max + 1, sizeof(int));
|
||||
if (code == NULL) {
|
||||
fputs("abort: unable to allocate enough memory\n", stderr);
|
||||
return 1;
|
||||
}
|
||||
// allocate code vector
|
||||
g.code = calloc(g.max + 1, sizeof(int));
|
||||
assert(g.code != NULL && "out of memory");
|
||||
|
||||
/* determine size of saved results array, checking for overflows,
|
||||
allocate and clear the array (set all to zero with calloc()) */
|
||||
if (syms == 2) /* iff max == 1 */
|
||||
num = NULL; /* won't be saving any results */
|
||||
// determine size of saved results array, checking for overflows,
|
||||
// allocate and clear the array (set all to zero with calloc())
|
||||
if (syms == 2) // iff max == 1
|
||||
g.num = NULL; // won't be saving any results
|
||||
else {
|
||||
size = syms >> 1;
|
||||
if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
|
||||
(size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
|
||||
(size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
|
||||
(num = calloc(size, sizeof(big_t))) == NULL) {
|
||||
fputs("abort: unable to allocate enough memory\n", stderr);
|
||||
cleanup();
|
||||
return 1;
|
||||
}
|
||||
g.size = syms >> 1;
|
||||
int n = (syms - 1) >> 1;
|
||||
assert(g.size <= (size_t)-1 / n && "overflow");
|
||||
g.size *= n;
|
||||
n = g.max - 1;
|
||||
assert(g.size <= (size_t)-1 / n && "overflow");
|
||||
g.size *= n;
|
||||
g.num = calloc(g.size, sizeof(big_t));
|
||||
assert(g.num != NULL && "out of memory");
|
||||
}
|
||||
|
||||
/* count possible codes for all numbers of symbols, add up counts */
|
||||
sum = 0;
|
||||
for (n = 2; n <= syms; n++) {
|
||||
got = count(n, 1, 2);
|
||||
// count possible codes for all numbers of symbols, add up counts
|
||||
big_t sum = 0;
|
||||
for (int n = 2; n <= syms; n++) {
|
||||
big_t got = count(n, 2, 1);
|
||||
sum += got;
|
||||
if (got == (big_t)0 - 1 || sum < got) { /* overflow */
|
||||
fputs("abort: can't count that high!\n", stderr);
|
||||
cleanup();
|
||||
return 1;
|
||||
}
|
||||
printf("%llu %d-codes\n", got, n);
|
||||
assert(got != (big_t)-1 && sum >= got && "overflow");
|
||||
}
|
||||
printf("%llu total codes for 2 to %d symbols", sum, syms);
|
||||
if (max < syms - 1)
|
||||
printf(" (%d-bit length limit)\n", max);
|
||||
printf("%"PRIbig" total codes for 2 to %d symbols", sum, syms);
|
||||
if (g.max < syms - 1)
|
||||
printf(" (%d-bit length limit)\n", g.max);
|
||||
else
|
||||
puts(" (no length limit)");
|
||||
|
||||
/* allocate and clear done array for beenhere() */
|
||||
// allocate and clear done array for been_here()
|
||||
if (syms == 2)
|
||||
done = NULL;
|
||||
else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
|
||||
(done = calloc(size, sizeof(struct tab))) == NULL) {
|
||||
fputs("abort: unable to allocate enough memory\n", stderr);
|
||||
cleanup();
|
||||
return 1;
|
||||
g.done = NULL;
|
||||
else {
|
||||
g.done = calloc(g.size, sizeof(struct tab));
|
||||
assert(g.done != NULL && "out of memory");
|
||||
}
|
||||
|
||||
/* find and show maximum inflate table usage */
|
||||
if (root > max) /* reduce root to max length */
|
||||
root = max;
|
||||
if ((code_t)syms < ((code_t)1 << (root + 1)))
|
||||
// find and show maximum inflate table usage
|
||||
if (g.root > g.max) // reduce root to max length
|
||||
g.root = g.max;
|
||||
if ((code_t)syms < ((code_t)1 << (g.root + 1)))
|
||||
enough(syms);
|
||||
else
|
||||
puts("cannot handle minimum code lengths > root");
|
||||
fputs("cannot handle minimum code lengths > root", stderr);
|
||||
|
||||
/* done */
|
||||
// done
|
||||
cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
data in order to determine how much of that input will compress to
|
||||
nearly the requested output block size. The first pass generates
|
||||
enough deflate blocks to produce output to fill the requested
|
||||
output size plus a specfied excess amount (see the EXCESS define
|
||||
output size plus a specified excess amount (see the EXCESS define
|
||||
below). The last deflate block may go quite a bit past that, but
|
||||
is discarded. The second pass decompresses and recompresses just
|
||||
the compressed data that fit in the requested plus excess sized
|
||||
|
@ -109,7 +109,7 @@ local int recompress(z_streamp inf, z_streamp def)
|
|||
if (ret == Z_MEM_ERROR)
|
||||
return ret;
|
||||
|
||||
/* compress what was decompresed until done or no room */
|
||||
/* compress what was decompressed until done or no room */
|
||||
def->avail_in = RAWLEN - inf->avail_out;
|
||||
def->next_in = raw;
|
||||
if (inf->avail_out != 0)
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
gun will also decompress files made by Unix compress, which uses LZW
|
||||
compression. These files are automatically detected by virtue of their
|
||||
magic header bytes. Since the end of Unix compress stream is marked by the
|
||||
end-of-file, they cannot be concantenated. If a Unix compress stream is
|
||||
end-of-file, they cannot be concatenated. If a Unix compress stream is
|
||||
encountered in an input file, it is the last stream in that file.
|
||||
|
||||
Like gunzip and uncompress, the file attributes of the original compressed
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* - Add L to constants in lseek() calls
|
||||
* - Remove some debugging information in error messages
|
||||
* - Use new data_type definition for zlib 1.2.1
|
||||
* - Simplfy and unify file operations
|
||||
* - Simplify and unify file operations
|
||||
* - Finish off gzip file in gztack()
|
||||
* - Use deflatePrime() instead of adding empty blocks
|
||||
* - Keep gzip file clean on appended file read errors
|
||||
|
@ -54,7 +54,7 @@
|
|||
block boundary to facilitate locating and modifying the last block bit at
|
||||
the start of the final deflate block. Also whether using Z_BLOCK or not,
|
||||
another required feature of zlib 1.2.x is that inflate() now provides the
|
||||
number of unusued bits in the last input byte used. gzappend will not work
|
||||
number of unused bits in the last input byte used. gzappend will not work
|
||||
with versions of zlib earlier than 1.2.1.
|
||||
|
||||
gzappend first decompresses the gzip file internally, discarding all but
|
||||
|
@ -137,7 +137,7 @@ local void rotate(unsigned char *list, unsigned len, unsigned rot)
|
|||
/* do simple left shift by one */
|
||||
if (rot == 1) {
|
||||
tmp = *list;
|
||||
memcpy(list, list + 1, len - 1);
|
||||
memmove(list, list + 1, len - 1);
|
||||
*last = tmp;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* gzlog.c
|
||||
* Copyright (C) 2004, 2008, 2012, 2016 Mark Adler, all rights reserved
|
||||
* Copyright (C) 2004, 2008, 2012, 2016, 2019 Mark Adler, all rights reserved
|
||||
* For conditions of distribution and use, see copyright notice in gzlog.h
|
||||
* version 2.2, 14 Aug 2012
|
||||
* version 2.3, 25 May 2019
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -756,12 +756,14 @@ local int log_recover(struct log *log, int op)
|
|||
return -2;
|
||||
}
|
||||
if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
|
||||
free(data);
|
||||
log_log(log, op, ".add file read failure");
|
||||
return -1;
|
||||
}
|
||||
ret = (size_t)read(fd, data, len) != len;
|
||||
close(fd);
|
||||
if (ret) {
|
||||
free(data);
|
||||
log_log(log, op, ".add file read failure");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
its new size at that time. After each write operation, the log file is a
|
||||
valid gzip file that can decompressed to recover what was written.
|
||||
|
||||
The gzlog operations can be interupted at any point due to an application or
|
||||
The gzlog operations can be interrupted at any point due to an application or
|
||||
system crash, and the log file will be recovered the next time the log is
|
||||
opened with gzlog_open().
|
||||
*/
|
||||
|
|
470
zlib/examples/gznorm.c
Normal file
470
zlib/examples/gznorm.c
Normal file
|
@ -0,0 +1,470 @@
|
|||
/* gznorm.c -- normalize a gzip stream
|
||||
* Copyright (C) 2018 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
* Version 1.0 7 Oct 2018 Mark Adler */
|
||||
|
||||
// gznorm takes a gzip stream, potentially containing multiple members, and
|
||||
// converts it to a gzip stream with a single member. In addition the gzip
|
||||
// header is normalized, removing the file name and time stamp, and setting the
|
||||
// other header contents (XFL, OS) to fixed values. gznorm does not recompress
|
||||
// the data, so it is fast, but no advantage is gained from the history that
|
||||
// could be available across member boundaries.
|
||||
|
||||
#include <stdio.h> // fread, fwrite, putc, fflush, ferror, fprintf,
|
||||
// vsnprintf, stdout, stderr, NULL, FILE
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <string.h> // strerror
|
||||
#include <errno.h> // errno
|
||||
#include <stdarg.h> // va_list, va_start, va_end
|
||||
#include "zlib.h" // inflateInit2, inflate, inflateReset, inflateEnd,
|
||||
// z_stream, z_off_t, crc32_combine, Z_NULL, Z_BLOCK,
|
||||
// Z_OK, Z_STREAM_END, Z_BUF_ERROR, Z_DATA_ERROR,
|
||||
// Z_MEM_ERROR
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
#else
|
||||
# define SET_BINARY_MODE(file)
|
||||
#endif
|
||||
|
||||
#define local static
|
||||
|
||||
// printf to an allocated string. Return the string, or NULL if the printf or
|
||||
// allocation fails.
|
||||
local char *aprintf(char *fmt, ...) {
|
||||
// Get the length of the result of the printf.
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int len = vsnprintf(NULL, 0, fmt, args);
|
||||
va_end(args);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
|
||||
// Allocate the required space and printf to it.
|
||||
char *str = malloc(len + 1);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(str, len + 1, fmt, args);
|
||||
va_end(args);
|
||||
return str;
|
||||
}
|
||||
|
||||
// Return with an error, putting an allocated error message in *err. Doing an
|
||||
// inflateEnd() on an already ended state, or one with state set to Z_NULL, is
|
||||
// permitted.
|
||||
#define BYE(...) \
|
||||
do { \
|
||||
inflateEnd(&strm); \
|
||||
*err = aprintf(__VA_ARGS__); \
|
||||
return 1; \
|
||||
} while (0)
|
||||
|
||||
// Chunk size for buffered reads and for decompression. Twice this many bytes
|
||||
// will be allocated on the stack by gzip_normalize(). Must fit in an unsigned.
|
||||
#define CHUNK 16384
|
||||
|
||||
// Read a gzip stream from in and write an equivalent normalized gzip stream to
|
||||
// out. If given no input, an empty gzip stream will be written. If successful,
|
||||
// 0 is returned, and *err is set to NULL. On error, 1 is returned, where the
|
||||
// details of the error are returned in *err, a pointer to an allocated string.
|
||||
//
|
||||
// The input may be a stream with multiple gzip members, which is converted to
|
||||
// a single gzip member on the output. Each gzip member is decompressed at the
|
||||
// level of deflate blocks. This enables clearing the last-block bit, shifting
|
||||
// the compressed data to concatenate to the previous member's compressed data,
|
||||
// which can end at an arbitrary bit boundary, and identifying stored blocks in
|
||||
// order to resynchronize those to byte boundaries. The deflate compressed data
|
||||
// is terminated with a 10-bit empty fixed block. If any members on the input
|
||||
// end with a 10-bit empty fixed block, then that block is excised from the
|
||||
// stream. This avoids appending empty fixed blocks for every normalization,
|
||||
// and assures that gzip_normalize applied a second time will not change the
|
||||
// input. The pad bits after stored block headers and after the final deflate
|
||||
// block are all forced to zeros.
|
||||
local int gzip_normalize(FILE *in, FILE *out, char **err) {
|
||||
// initialize the inflate engine to process a gzip member
|
||||
z_stream strm;
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
if (inflateInit2(&strm, 15 + 16) != Z_OK)
|
||||
BYE("out of memory");
|
||||
|
||||
// State while processing the input gzip stream.
|
||||
enum { // BETWEEN -> HEAD -> BLOCK -> TAIL -> BETWEEN -> ...
|
||||
BETWEEN, // between gzip members (must end in this state)
|
||||
HEAD, // reading a gzip header
|
||||
BLOCK, // reading deflate blocks
|
||||
TAIL // reading a gzip trailer
|
||||
} state = BETWEEN; // current component being processed
|
||||
unsigned long crc = 0; // accumulated CRC of uncompressed data
|
||||
unsigned long len = 0; // accumulated length of uncompressed data
|
||||
unsigned long buf = 0; // deflate stream bit buffer of num bits
|
||||
int num = 0; // number of bits in buf (at bottom)
|
||||
|
||||
// Write a canonical gzip header (no mod time, file name, comment, extra
|
||||
// block, or extra flags, and OS is marked as unknown).
|
||||
fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
|
||||
|
||||
// Process the gzip stream from in until reaching the end of the input,
|
||||
// encountering invalid input, or experiencing an i/o error.
|
||||
int more; // true if not at the end of the input
|
||||
do {
|
||||
// State inside this loop.
|
||||
unsigned char *put; // next input buffer location to process
|
||||
int prev; // number of bits from previous block in
|
||||
// the bit buffer, or -1 if not at the
|
||||
// start of a block
|
||||
unsigned long long memb; // uncompressed length of member
|
||||
size_t tail; // number of trailer bytes read (0..8)
|
||||
unsigned long part; // accumulated trailer component
|
||||
|
||||
// Get the next chunk of input from in.
|
||||
unsigned char dat[CHUNK];
|
||||
strm.avail_in = fread(dat, 1, CHUNK, in);
|
||||
if (strm.avail_in == 0)
|
||||
break;
|
||||
more = strm.avail_in == CHUNK;
|
||||
strm.next_in = put = dat;
|
||||
|
||||
// Run that chunk of input through the inflate engine to exhaustion.
|
||||
do {
|
||||
// At this point it is assured that strm.avail_in > 0.
|
||||
|
||||
// Inflate until the end of a gzip component (header, deflate
|
||||
// block, trailer) is reached, or until all of the chunk is
|
||||
// consumed. The resulting decompressed data is discarded, though
|
||||
// the total size of the decompressed data in each member is
|
||||
// tracked, for the calculation of the total CRC.
|
||||
do {
|
||||
// inflate and handle any errors
|
||||
unsigned char scrap[CHUNK];
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = scrap;
|
||||
int ret = inflate(&strm, Z_BLOCK);
|
||||
if (ret == Z_MEM_ERROR)
|
||||
BYE("out of memory");
|
||||
if (ret == Z_DATA_ERROR)
|
||||
BYE("input invalid: %s", strm.msg);
|
||||
if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END)
|
||||
BYE("internal error");
|
||||
|
||||
// Update the number of uncompressed bytes generated in this
|
||||
// member. The actual count (not modulo 2^32) is required to
|
||||
// correctly compute the total CRC.
|
||||
unsigned got = CHUNK - strm.avail_out;
|
||||
memb += got;
|
||||
if (memb < got)
|
||||
BYE("overflow error");
|
||||
|
||||
// Continue to process this chunk until it is consumed, or
|
||||
// until the end of a component (header, deflate block, or
|
||||
// trailer) is reached.
|
||||
} while (strm.avail_out == 0 && (strm.data_type & 0x80) == 0);
|
||||
|
||||
// Since strm.avail_in was > 0 for the inflate call, some input was
|
||||
// just consumed. It is therefore assured that put < strm.next_in.
|
||||
|
||||
// Disposition the consumed component or part of a component.
|
||||
switch (state) {
|
||||
case BETWEEN:
|
||||
state = HEAD;
|
||||
// Fall through to HEAD when some or all of the header is
|
||||
// processed.
|
||||
|
||||
case HEAD:
|
||||
// Discard the header.
|
||||
if (strm.data_type & 0x80) {
|
||||
// End of header reached -- deflate blocks follow.
|
||||
put = strm.next_in;
|
||||
prev = num;
|
||||
memb = 0;
|
||||
state = BLOCK;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLOCK:
|
||||
// Copy the deflate stream to the output, but with the
|
||||
// last-block-bit cleared. Re-synchronize stored block
|
||||
// headers to the output byte boundaries. The bytes at
|
||||
// put..strm.next_in-1 is the compressed data that has been
|
||||
// processed and is ready to be copied to the output.
|
||||
|
||||
// At this point, it is assured that new compressed data is
|
||||
// available, i.e., put < strm.next_in. If prev is -1, then
|
||||
// that compressed data starts in the middle of a deflate
|
||||
// block. If prev is not -1, then the bits in the bit
|
||||
// buffer, possibly combined with the bits in *put, contain
|
||||
// the three-bit header of the new deflate block. In that
|
||||
// case, prev is the number of bits from the previous block
|
||||
// that remain in the bit buffer. Since num is the number
|
||||
// of bits in the bit buffer, we have that num - prev is
|
||||
// the number of bits from the new block currently in the
|
||||
// bit buffer.
|
||||
|
||||
// If strm.data_type & 0xc0 is 0x80, then the last byte of
|
||||
// the available compressed data includes the last bits of
|
||||
// the end of a deflate block. In that case, that last byte
|
||||
// also has strm.data_type & 0x1f bits of the next deflate
|
||||
// block, in the range 0..7. If strm.data_type & 0xc0 is
|
||||
// 0xc0, then the last byte of the compressed data is the
|
||||
// end of the deflate stream, followed by strm.data_type &
|
||||
// 0x1f pad bits, also in the range 0..7.
|
||||
|
||||
// Set bits to the number of bits not yet consumed from the
|
||||
// last byte. If we are at the end of the block, bits is
|
||||
// either the number of bits in the last byte belonging to
|
||||
// the next block, or the number of pad bits after the
|
||||
// final block. In either of those cases, bits is in the
|
||||
// range 0..7.
|
||||
; // (required due to C syntax oddity)
|
||||
int bits = strm.data_type & 0x1f;
|
||||
|
||||
if (prev != -1) {
|
||||
// We are at the start of a new block. Clear the last
|
||||
// block bit, and check for special cases. If it is a
|
||||
// stored block, then emit the header and pad to the
|
||||
// next byte boundary. If it is a final, empty fixed
|
||||
// block, then excise it.
|
||||
|
||||
// Some or all of the three header bits for this block
|
||||
// may already be in the bit buffer. Load any remaining
|
||||
// header bits into the bit buffer.
|
||||
if (num - prev < 3) {
|
||||
buf += (unsigned long)*put++ << num;
|
||||
num += 8;
|
||||
}
|
||||
|
||||
// Set last to have a 1 in the position of the last
|
||||
// block bit in the bit buffer.
|
||||
unsigned long last = (unsigned long)1 << prev;
|
||||
|
||||
if (((buf >> prev) & 7) == 3) {
|
||||
// This is a final fixed block. Load at least ten
|
||||
// bits from this block, including the header, into
|
||||
// the bit buffer. We already have at least three,
|
||||
// so at most one more byte needs to be loaded.
|
||||
if (num - prev < 10) {
|
||||
if (put == strm.next_in)
|
||||
// Need to go get and process more input.
|
||||
// We'll end up back here to finish this.
|
||||
break;
|
||||
buf += (unsigned long)*put++ << num;
|
||||
num += 8;
|
||||
}
|
||||
if (((buf >> prev) & 0x3ff) == 3) {
|
||||
// That final fixed block is empty. Delete it
|
||||
// to avoid adding an empty block every time a
|
||||
// gzip stream is normalized.
|
||||
num = prev;
|
||||
buf &= last - 1; // zero the pad bits
|
||||
}
|
||||
}
|
||||
else if (((buf >> prev) & 6) == 0) {
|
||||
// This is a stored block. Flush to the next
|
||||
// byte boundary after the three-bit header.
|
||||
num = (prev + 10) & ~7;
|
||||
buf &= last - 1; // zero the pad bits
|
||||
}
|
||||
|
||||
// Clear the last block bit.
|
||||
buf &= ~last;
|
||||
|
||||
// Write out complete bytes in the bit buffer.
|
||||
while (num >= 8) {
|
||||
putc(buf, out);
|
||||
buf >>= 8;
|
||||
num -= 8;
|
||||
}
|
||||
|
||||
// If no more bytes left to process, then we have
|
||||
// consumed the byte that had bits from the next block.
|
||||
if (put == strm.next_in)
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
// We are done handling the deflate block header. Now copy
|
||||
// all or almost all of the remaining compressed data that
|
||||
// has been processed so far. Don't copy one byte at the
|
||||
// end if it contains bits from the next deflate block or
|
||||
// pad bits at the end of a deflate block.
|
||||
|
||||
// mix is 1 if we are at the end of a deflate block, and if
|
||||
// some of the bits in the last byte follow this block. mix
|
||||
// is 0 if we are in the middle of a deflate block, if the
|
||||
// deflate block ended on a byte boundary, or if all of the
|
||||
// compressed data processed so far has been consumed.
|
||||
int mix = (strm.data_type & 0x80) && bits;
|
||||
|
||||
// Copy all of the processed compressed data to the output,
|
||||
// except for the last byte if it contains bits from the
|
||||
// next deflate block or pad bits at the end of the deflate
|
||||
// stream. Copy the data after shifting in num bits from
|
||||
// buf in front of it, leaving num bits from the end of the
|
||||
// compressed data in buf when done.
|
||||
unsigned char *end = strm.next_in - mix;
|
||||
if (put < end) {
|
||||
if (num)
|
||||
// Insert num bits from buf before the data being
|
||||
// copied.
|
||||
do {
|
||||
buf += (unsigned)(*put++) << num;
|
||||
putc(buf, out);
|
||||
buf >>= 8;
|
||||
} while (put < end);
|
||||
else {
|
||||
// No shifting needed -- write directly.
|
||||
fwrite(put, 1, end - put, out);
|
||||
put = end;
|
||||
}
|
||||
}
|
||||
|
||||
// Process the last processed byte if it wasn't written.
|
||||
if (mix) {
|
||||
// Load the last byte into the bit buffer.
|
||||
buf += (unsigned)(*put++) << num;
|
||||
num += 8;
|
||||
|
||||
if (strm.data_type & 0x40) {
|
||||
// We are at the end of the deflate stream and
|
||||
// there are bits pad bits. Discard the pad bits
|
||||
// and write a byte to the output, if available.
|
||||
// Leave the num bits left over in buf to prepend
|
||||
// to the next deflate stream.
|
||||
num -= bits;
|
||||
if (num >= 8) {
|
||||
putc(buf, out);
|
||||
num -= 8;
|
||||
buf >>= 8;
|
||||
}
|
||||
|
||||
// Force the pad bits in the bit buffer to zeros.
|
||||
buf &= ((unsigned long)1 << num) - 1;
|
||||
|
||||
// Don't need to set prev here since going to TAIL.
|
||||
}
|
||||
else
|
||||
// At the end of an internal deflate block. Leave
|
||||
// the last byte in the bit buffer to examine on
|
||||
// the next entry to BLOCK, when more bits from the
|
||||
// next block will be available.
|
||||
prev = num - bits; // number of bits in buffer
|
||||
// from current block
|
||||
}
|
||||
|
||||
// Don't have a byte left over, so we are in the middle of
|
||||
// a deflate block, or the deflate block ended on a byte
|
||||
// boundary. Set prev appropriately for the next entry into
|
||||
// BLOCK.
|
||||
else if (strm.data_type & 0x80)
|
||||
// The block ended on a byte boundary, so no header
|
||||
// bits are in the bit buffer.
|
||||
prev = num;
|
||||
else
|
||||
// In the middle of a deflate block, so no header here.
|
||||
prev = -1;
|
||||
|
||||
// Check for the end of the deflate stream.
|
||||
if ((strm.data_type & 0xc0) == 0xc0) {
|
||||
// That ends the deflate stream on the input side, the
|
||||
// pad bits were discarded, and any remaining bits from
|
||||
// the last block in the stream are saved in the bit
|
||||
// buffer to prepend to the next stream. Process the
|
||||
// gzip trailer next.
|
||||
tail = 0;
|
||||
part = 0;
|
||||
state = TAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAIL:
|
||||
// Accumulate available trailer bytes to update the total
|
||||
// CRC and the total uncompressed length.
|
||||
do {
|
||||
part = (part >> 8) + ((unsigned long)(*put++) << 24);
|
||||
tail++;
|
||||
if (tail == 4) {
|
||||
// Update the total CRC.
|
||||
z_off_t len2 = memb;
|
||||
if (len2 < 0 || (unsigned long long)len2 != memb)
|
||||
BYE("overflow error");
|
||||
crc = crc ? crc32_combine(crc, part, len2) : part;
|
||||
part = 0;
|
||||
}
|
||||
else if (tail == 8) {
|
||||
// Update the total uncompressed length. (It's ok
|
||||
// if this sum is done modulo 2^32.)
|
||||
len += part;
|
||||
|
||||
// At the end of a member. Set up to inflate an
|
||||
// immediately following gzip member. (If we made
|
||||
// it this far, then the trailer was valid.)
|
||||
if (inflateReset(&strm) != Z_OK)
|
||||
BYE("internal error");
|
||||
state = BETWEEN;
|
||||
break;
|
||||
}
|
||||
} while (put < strm.next_in);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process the input buffer until completely consumed.
|
||||
} while (strm.avail_in > 0);
|
||||
|
||||
// Process input until end of file, invalid input, or i/o error.
|
||||
} while (more);
|
||||
|
||||
// Done with the inflate engine.
|
||||
inflateEnd(&strm);
|
||||
|
||||
// Verify the validity of the input.
|
||||
if (state != BETWEEN)
|
||||
BYE("input invalid: incomplete gzip stream");
|
||||
|
||||
// Write the remaining deflate stream bits, followed by a terminating
|
||||
// deflate fixed block.
|
||||
buf += (unsigned long)3 << num;
|
||||
putc(buf, out);
|
||||
putc(buf >> 8, out);
|
||||
if (num > 6)
|
||||
putc(0, out);
|
||||
|
||||
// Write the gzip trailer, which is the CRC and the uncompressed length
|
||||
// modulo 2^32, both in little-endian order.
|
||||
putc(crc, out);
|
||||
putc(crc >> 8, out);
|
||||
putc(crc >> 16, out);
|
||||
putc(crc >> 24, out);
|
||||
putc(len, out);
|
||||
putc(len >> 8, out);
|
||||
putc(len >> 16, out);
|
||||
putc(len >> 24, out);
|
||||
fflush(out);
|
||||
|
||||
// Check for any i/o errors.
|
||||
if (ferror(in) || ferror(out))
|
||||
BYE("i/o error: %s", strerror(errno));
|
||||
|
||||
// All good!
|
||||
*err = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Normalize the gzip stream on stdin, writing the result to stdout.
|
||||
int main(void) {
|
||||
// Avoid end-of-line conversions on evil operating systems.
|
||||
SET_BINARY_MODE(stdin);
|
||||
SET_BINARY_MODE(stdout);
|
||||
|
||||
// Normalize from stdin to stdout, returning 1 on error, 0 if ok.
|
||||
char *err;
|
||||
int ret = gzip_normalize(stdin, stdout, &err);
|
||||
if (ret)
|
||||
fprintf(stderr, "gznorm error: %s\n", err);
|
||||
free(err);
|
||||
return ret;
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
/* zran.c -- example of zlib/gzip stream indexing and random access
|
||||
* Copyright (C) 2005, 2012 Mark Adler
|
||||
* Copyright (C) 2005, 2012, 2018 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
Version 1.1 29 Sep 2012 Mark Adler */
|
||||
* Version 1.2 14 Oct 2018 Mark Adler */
|
||||
|
||||
/* Version History:
|
||||
1.0 29 May 2005 First version
|
||||
1.1 29 Sep 2012 Fix memory reallocation error
|
||||
1.2 14 Oct 2018 Handle gzip streams with multiple members
|
||||
Add a header file to facilitate usage in applications
|
||||
*/
|
||||
|
||||
/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
|
||||
|
@ -19,12 +21,12 @@
|
|||
An access point can be created at the start of any deflate block, by saving
|
||||
the starting file offset and bit of that block, and the 32K bytes of
|
||||
uncompressed data that precede that block. Also the uncompressed offset of
|
||||
that block is saved to provide a referece for locating a desired starting
|
||||
point in the uncompressed stream. build_index() works by decompressing the
|
||||
input zlib or gzip stream a block at a time, and at the end of each block
|
||||
deciding if enough uncompressed data has gone by to justify the creation of
|
||||
a new access point. If so, that point is saved in a data structure that
|
||||
grows as needed to accommodate the points.
|
||||
that block is saved to provide a reference for locating a desired starting
|
||||
point in the uncompressed stream. deflate_index_build() works by
|
||||
decompressing the input zlib or gzip stream a block at a time, and at the
|
||||
end of each block deciding if enough uncompressed data has gone by to
|
||||
justify the creation of a new access point. If so, that point is saved in a
|
||||
data structure that grows as needed to accommodate the points.
|
||||
|
||||
To use the index, an offset in the uncompressed data is provided, for which
|
||||
the latest access point at or preceding that offset is located in the index.
|
||||
|
@ -43,7 +45,8 @@
|
|||
There is some fair bit of overhead to starting inflation for the random
|
||||
access, mainly copying the 32K byte dictionary. So if small pieces of the
|
||||
file are being accessed, it would make sense to implement a cache to hold
|
||||
some lookahead and avoid many calls to extract() for small lengths.
|
||||
some lookahead and avoid many calls to deflate_index_extract() for small
|
||||
lengths.
|
||||
|
||||
Another way to build an index would be to use inflateCopy(). That would
|
||||
not be constrained to have access points at block boundaries, but requires
|
||||
|
@ -56,30 +59,21 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "zlib.h"
|
||||
#include "zran.h"
|
||||
|
||||
#define local static
|
||||
|
||||
#define SPAN 1048576L /* desired distance between access points */
|
||||
#define WINSIZE 32768U /* sliding window size */
|
||||
#define CHUNK 16384 /* file input buffer size */
|
||||
|
||||
/* access point entry */
|
||||
/* Access point entry. */
|
||||
struct point {
|
||||
off_t out; /* corresponding offset in uncompressed data */
|
||||
off_t in; /* offset in input file of first full byte */
|
||||
int bits; /* number of bits (1-7) from byte at in - 1, or 0 */
|
||||
int bits; /* number of bits (1-7) from byte at in-1, or 0 */
|
||||
unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */
|
||||
};
|
||||
|
||||
/* access point list */
|
||||
struct access {
|
||||
int have; /* number of list entries filled in */
|
||||
int size; /* number of list entries allocated */
|
||||
struct point *list; /* allocated list */
|
||||
};
|
||||
|
||||
/* Deallocate an index built by build_index() */
|
||||
local void free_index(struct access *index)
|
||||
/* See comments in zran.h. */
|
||||
void deflate_index_free(struct deflate_index *index)
|
||||
{
|
||||
if (index != NULL) {
|
||||
free(index->list);
|
||||
|
@ -87,39 +81,43 @@ local void free_index(struct access *index)
|
|||
}
|
||||
}
|
||||
|
||||
/* Add an entry to the access point list. If out of memory, deallocate the
|
||||
existing list and return NULL. */
|
||||
local struct access *addpoint(struct access *index, int bits,
|
||||
off_t in, off_t out, unsigned left, unsigned char *window)
|
||||
/* Add an entry to the access point list. If out of memory, deallocate the
|
||||
existing list and return NULL. index->gzip is the allocated size of the
|
||||
index in point entries, until it is time for deflate_index_build() to
|
||||
return, at which point gzip is set to indicate a gzip file or not.
|
||||
*/
|
||||
static struct deflate_index *addpoint(struct deflate_index *index, int bits,
|
||||
off_t in, off_t out, unsigned left,
|
||||
unsigned char *window)
|
||||
{
|
||||
struct point *next;
|
||||
|
||||
/* if list is empty, create it (start with eight points) */
|
||||
if (index == NULL) {
|
||||
index = malloc(sizeof(struct access));
|
||||
index = malloc(sizeof(struct deflate_index));
|
||||
if (index == NULL) return NULL;
|
||||
index->list = malloc(sizeof(struct point) << 3);
|
||||
if (index->list == NULL) {
|
||||
free(index);
|
||||
return NULL;
|
||||
}
|
||||
index->size = 8;
|
||||
index->gzip = 8;
|
||||
index->have = 0;
|
||||
}
|
||||
|
||||
/* if list is full, make it bigger */
|
||||
else if (index->have == index->size) {
|
||||
index->size <<= 1;
|
||||
next = realloc(index->list, sizeof(struct point) * index->size);
|
||||
else if (index->have == index->gzip) {
|
||||
index->gzip <<= 1;
|
||||
next = realloc(index->list, sizeof(struct point) * index->gzip);
|
||||
if (next == NULL) {
|
||||
free_index(index);
|
||||
deflate_index_free(index);
|
||||
return NULL;
|
||||
}
|
||||
index->list = next;
|
||||
}
|
||||
|
||||
/* fill in entry and increment how many we have */
|
||||
next = index->list + index->have;
|
||||
next = (struct point *)(index->list) + index->have;
|
||||
next->bits = bits;
|
||||
next->in = in;
|
||||
next->out = out;
|
||||
|
@ -133,20 +131,14 @@ local struct access *addpoint(struct access *index, int bits,
|
|||
return index;
|
||||
}
|
||||
|
||||
/* Make one entire pass through the compressed stream and build an index, with
|
||||
access points about every span bytes of uncompressed output -- span is
|
||||
chosen to balance the speed of random access against the memory requirements
|
||||
of the list, about 32K bytes per access point. Note that data after the end
|
||||
of the first zlib or gzip stream in the file is ignored. build_index()
|
||||
returns the number of access points on success (>= 1), Z_MEM_ERROR for out
|
||||
of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
|
||||
file read error. On success, *built points to the resulting index. */
|
||||
local int build_index(FILE *in, off_t span, struct access **built)
|
||||
/* See comments in zran.h. */
|
||||
int deflate_index_build(FILE *in, off_t span, struct deflate_index **built)
|
||||
{
|
||||
int ret;
|
||||
int gzip = 0; /* true if reading a gzip file */
|
||||
off_t totin, totout; /* our own total counters to avoid 4GB limit */
|
||||
off_t last; /* totout value of last access point */
|
||||
struct access *index; /* access points being generated */
|
||||
struct deflate_index *index; /* access points being generated */
|
||||
z_stream strm;
|
||||
unsigned char input[CHUNK];
|
||||
unsigned char window[WINSIZE];
|
||||
|
@ -163,7 +155,7 @@ local int build_index(FILE *in, off_t span, struct access **built)
|
|||
|
||||
/* inflate the input, maintain a sliding window, and build an index -- this
|
||||
also validates the integrity of the compressed data using the check
|
||||
information at the end of the gzip or zlib stream */
|
||||
information in the gzip or zlib stream */
|
||||
totin = totout = last = 0;
|
||||
index = NULL; /* will be allocated by first addpoint() */
|
||||
strm.avail_out = 0;
|
||||
|
@ -172,14 +164,19 @@ local int build_index(FILE *in, off_t span, struct access **built)
|
|||
strm.avail_in = fread(input, 1, CHUNK, in);
|
||||
if (ferror(in)) {
|
||||
ret = Z_ERRNO;
|
||||
goto build_index_error;
|
||||
goto deflate_index_build_error;
|
||||
}
|
||||
if (strm.avail_in == 0) {
|
||||
ret = Z_DATA_ERROR;
|
||||
goto build_index_error;
|
||||
goto deflate_index_build_error;
|
||||
}
|
||||
strm.next_in = input;
|
||||
|
||||
/* check for a gzip stream */
|
||||
if (totin == 0 && strm.avail_in >= 3 &&
|
||||
input[0] == 31 && input[1] == 139 && input[2] == 8)
|
||||
gzip = 1;
|
||||
|
||||
/* process all of that, or until end of stream */
|
||||
do {
|
||||
/* reset sliding window if necessary */
|
||||
|
@ -198,9 +195,17 @@ local int build_index(FILE *in, off_t span, struct access **built)
|
|||
if (ret == Z_NEED_DICT)
|
||||
ret = Z_DATA_ERROR;
|
||||
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
|
||||
goto build_index_error;
|
||||
if (ret == Z_STREAM_END)
|
||||
goto deflate_index_build_error;
|
||||
if (ret == Z_STREAM_END) {
|
||||
if (gzip &&
|
||||
(strm.avail_in || ungetc(getc(in), in) != EOF)) {
|
||||
ret = inflateReset(&strm);
|
||||
if (ret != Z_OK)
|
||||
goto deflate_index_build_error;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* if at end of block, consider adding an index entry (note that if
|
||||
data_type indicates an end-of-block, then all of the
|
||||
|
@ -217,7 +222,7 @@ local int build_index(FILE *in, off_t span, struct access **built)
|
|||
totout, strm.avail_out, window);
|
||||
if (index == NULL) {
|
||||
ret = Z_MEM_ERROR;
|
||||
goto build_index_error;
|
||||
goto deflate_index_build_error;
|
||||
}
|
||||
last = totout;
|
||||
}
|
||||
|
@ -227,27 +232,21 @@ local int build_index(FILE *in, off_t span, struct access **built)
|
|||
/* clean up and return index (release unused entries in list) */
|
||||
(void)inflateEnd(&strm);
|
||||
index->list = realloc(index->list, sizeof(struct point) * index->have);
|
||||
index->size = index->have;
|
||||
index->gzip = gzip;
|
||||
index->length = totout;
|
||||
*built = index;
|
||||
return index->size;
|
||||
return index->have;
|
||||
|
||||
/* return error */
|
||||
build_index_error:
|
||||
deflate_index_build_error:
|
||||
(void)inflateEnd(&strm);
|
||||
if (index != NULL)
|
||||
free_index(index);
|
||||
deflate_index_free(index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Use the index to read len bytes from offset into buf, return bytes read or
|
||||
negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past
|
||||
the end of the uncompressed data, then extract() will return a value less
|
||||
than len, indicating how much as actually read into buf. This function
|
||||
should not return a data error unless the file was modified since the index
|
||||
was generated. extract() may also return Z_ERRNO if there is an error on
|
||||
reading or seeking the input file. */
|
||||
local int extract(FILE *in, struct access *index, off_t offset,
|
||||
unsigned char *buf, int len)
|
||||
/* See comments in zran.h. */
|
||||
int deflate_index_extract(FILE *in, struct deflate_index *index, off_t offset,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
int ret, skip;
|
||||
z_stream strm;
|
||||
|
@ -276,12 +275,12 @@ local int extract(FILE *in, struct access *index, off_t offset,
|
|||
return ret;
|
||||
ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
|
||||
if (ret == -1)
|
||||
goto extract_ret;
|
||||
goto deflate_index_extract_ret;
|
||||
if (here->bits) {
|
||||
ret = getc(in);
|
||||
if (ret == -1) {
|
||||
ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
|
||||
goto extract_ret;
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
(void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
|
||||
}
|
||||
|
@ -293,21 +292,21 @@ local int extract(FILE *in, struct access *index, off_t offset,
|
|||
skip = 1; /* while skipping to offset */
|
||||
do {
|
||||
/* define where to put uncompressed data, and how much */
|
||||
if (offset == 0 && skip) { /* at offset now */
|
||||
strm.avail_out = len;
|
||||
strm.next_out = buf;
|
||||
skip = 0; /* only do this once */
|
||||
}
|
||||
if (offset > WINSIZE) { /* skip WINSIZE bytes */
|
||||
strm.avail_out = WINSIZE;
|
||||
strm.next_out = discard;
|
||||
offset -= WINSIZE;
|
||||
}
|
||||
else if (offset != 0) { /* last skip */
|
||||
else if (offset > 0) { /* last skip */
|
||||
strm.avail_out = (unsigned)offset;
|
||||
strm.next_out = discard;
|
||||
offset = 0;
|
||||
}
|
||||
else if (skip) { /* at offset now */
|
||||
strm.avail_out = len;
|
||||
strm.next_out = buf;
|
||||
skip = 0; /* only do this once */
|
||||
}
|
||||
|
||||
/* uncompress until avail_out filled, or end of stream */
|
||||
do {
|
||||
|
@ -315,11 +314,11 @@ local int extract(FILE *in, struct access *index, off_t offset,
|
|||
strm.avail_in = fread(input, 1, CHUNK, in);
|
||||
if (ferror(in)) {
|
||||
ret = Z_ERRNO;
|
||||
goto extract_ret;
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
if (strm.avail_in == 0) {
|
||||
ret = Z_DATA_ERROR;
|
||||
goto extract_ret;
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
strm.next_in = input;
|
||||
}
|
||||
|
@ -327,41 +326,99 @@ local int extract(FILE *in, struct access *index, off_t offset,
|
|||
if (ret == Z_NEED_DICT)
|
||||
ret = Z_DATA_ERROR;
|
||||
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
|
||||
goto extract_ret;
|
||||
if (ret == Z_STREAM_END)
|
||||
break;
|
||||
goto deflate_index_extract_ret;
|
||||
if (ret == Z_STREAM_END) {
|
||||
/* the raw deflate stream has ended */
|
||||
if (index->gzip == 0)
|
||||
/* this is a zlib stream that has ended -- done */
|
||||
break;
|
||||
|
||||
/* near the end of a gzip member, which might be followed by
|
||||
another gzip member -- skip the gzip trailer and see if
|
||||
there is more input after it */
|
||||
if (strm.avail_in < 8) {
|
||||
fseeko(in, 8 - strm.avail_in, SEEK_CUR);
|
||||
strm.avail_in = 0;
|
||||
}
|
||||
else {
|
||||
strm.avail_in -= 8;
|
||||
strm.next_in += 8;
|
||||
}
|
||||
if (strm.avail_in == 0 && ungetc(getc(in), in) == EOF)
|
||||
/* the input ended after the gzip trailer -- done */
|
||||
break;
|
||||
|
||||
/* there is more input, so another gzip member should follow --
|
||||
validate and skip the gzip header */
|
||||
ret = inflateReset2(&strm, 31);
|
||||
if (ret != Z_OK)
|
||||
goto deflate_index_extract_ret;
|
||||
do {
|
||||
if (strm.avail_in == 0) {
|
||||
strm.avail_in = fread(input, 1, CHUNK, in);
|
||||
if (ferror(in)) {
|
||||
ret = Z_ERRNO;
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
if (strm.avail_in == 0) {
|
||||
ret = Z_DATA_ERROR;
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
strm.next_in = input;
|
||||
}
|
||||
ret = inflate(&strm, Z_BLOCK);
|
||||
if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
|
||||
goto deflate_index_extract_ret;
|
||||
} while ((strm.data_type & 128) == 0);
|
||||
|
||||
/* set up to continue decompression of the raw deflate stream
|
||||
that follows the gzip header */
|
||||
ret = inflateReset2(&strm, -15);
|
||||
if (ret != Z_OK)
|
||||
goto deflate_index_extract_ret;
|
||||
}
|
||||
|
||||
/* continue to process the available input before reading more */
|
||||
} while (strm.avail_out != 0);
|
||||
|
||||
/* if reach end of stream, then don't keep trying to get more */
|
||||
if (ret == Z_STREAM_END)
|
||||
/* reached the end of the compressed data -- return the data that
|
||||
was available, possibly less than requested */
|
||||
break;
|
||||
|
||||
/* do until offset reached and requested data read, or stream ends */
|
||||
/* do until offset reached and requested data read */
|
||||
} while (skip);
|
||||
|
||||
/* compute number of uncompressed bytes read after offset */
|
||||
/* compute the number of uncompressed bytes read after the offset */
|
||||
ret = skip ? 0 : len - strm.avail_out;
|
||||
|
||||
/* clean up and return bytes read or error */
|
||||
extract_ret:
|
||||
/* clean up and return the bytes read, or the negative error */
|
||||
deflate_index_extract_ret:
|
||||
(void)inflateEnd(&strm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Demonstrate the use of build_index() and extract() by processing the file
|
||||
provided on the command line, and the extracting 16K from about 2/3rds of
|
||||
the way through the uncompressed output, and writing that to stdout. */
|
||||
#ifdef TEST
|
||||
|
||||
#define SPAN 1048576L /* desired distance between access points */
|
||||
#define LEN 16384 /* number of bytes to extract */
|
||||
|
||||
/* Demonstrate the use of deflate_index_build() and deflate_index_extract() by
|
||||
processing the file provided on the command line, and extracting LEN bytes
|
||||
from 2/3rds of the way through the uncompressed output, writing that to
|
||||
stdout. An offset can be provided as the second argument, in which case the
|
||||
data is extracted from there instead. */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int len;
|
||||
off_t offset;
|
||||
off_t offset = -1;
|
||||
FILE *in;
|
||||
struct access *index = NULL;
|
||||
unsigned char buf[CHUNK];
|
||||
struct deflate_index *index = NULL;
|
||||
unsigned char buf[LEN];
|
||||
|
||||
/* open input file */
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: zran file.gz\n");
|
||||
if (argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "usage: zran file.gz [offset]\n");
|
||||
return 1;
|
||||
}
|
||||
in = fopen(argv[1], "rb");
|
||||
|
@ -370,8 +427,18 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* get optional offset */
|
||||
if (argc == 3) {
|
||||
char *end;
|
||||
offset = strtoll(argv[2], &end, 10);
|
||||
if (*end || offset < 0) {
|
||||
fprintf(stderr, "zran: %s is not a valid offset\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* build index */
|
||||
len = build_index(in, SPAN, &index);
|
||||
len = deflate_index_build(in, SPAN, &index);
|
||||
if (len < 0) {
|
||||
fclose(in);
|
||||
switch (len) {
|
||||
|
@ -392,8 +459,9 @@ int main(int argc, char **argv)
|
|||
fprintf(stderr, "zran: built index with %d access points\n", len);
|
||||
|
||||
/* use index by reading some bytes from an arbitrary offset */
|
||||
offset = (index->list[index->have - 1].out << 1) / 3;
|
||||
len = extract(in, index, offset, buf, CHUNK);
|
||||
if (offset == -1)
|
||||
offset = (index->length << 1) / 3;
|
||||
len = deflate_index_extract(in, index, offset, buf, LEN);
|
||||
if (len < 0)
|
||||
fprintf(stderr, "zran: extraction failed: %s error\n",
|
||||
len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
|
||||
|
@ -403,7 +471,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* clean up and exit */
|
||||
free_index(index);
|
||||
deflate_index_free(index);
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
40
zlib/examples/zran.h
Normal file
40
zlib/examples/zran.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* zran.h -- example of zlib/gzip stream indexing and random access
|
||||
* Copyright (C) 2005, 2012, 2018 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
* Version 1.2 14 Oct 2018 Mark Adler */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "zlib.h"
|
||||
|
||||
/* Access point list. */
|
||||
struct deflate_index {
|
||||
int have; /* number of list entries */
|
||||
int gzip; /* 1 if the index is of a gzip file, 0 if it is of a
|
||||
zlib stream */
|
||||
off_t length; /* total length of uncompressed data */
|
||||
void *list; /* allocated list of entries */
|
||||
};
|
||||
|
||||
/* Make one entire pass through a zlib or gzip compressed stream and build an
|
||||
index, with access points about every span bytes of uncompressed output.
|
||||
gzip files with multiple members are indexed in their entirety. span should
|
||||
be chosen to balance the speed of random access against the memory
|
||||
requirements of the list, about 32K bytes per access point. The return value
|
||||
is the number of access points on success (>= 1), Z_MEM_ERROR for out of
|
||||
memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a file
|
||||
read error. On success, *built points to the resulting index. */
|
||||
int deflate_index_build(FILE *in, off_t span, struct deflate_index **built);
|
||||
|
||||
/* Deallocate an index built by deflate_index_build() */
|
||||
void deflate_index_free(struct deflate_index *index);
|
||||
|
||||
/* Use the index to read len bytes from offset into buf. Return bytes read or
|
||||
negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past
|
||||
the end of the uncompressed data, then deflate_index_extract() will return a
|
||||
value less than len, indicating how much was actually read into buf. This
|
||||
function should not return a data error unless the file was modified since
|
||||
the index was generated, since deflate_index_build() validated all of the
|
||||
input. deflate_index_extract() will return Z_ERRNO if there is an error on
|
||||
reading or seeking the input file. */
|
||||
int deflate_index_extract(FILE *in, struct deflate_index *index, off_t offset,
|
||||
unsigned char *buf, int len);
|
|
@ -1,5 +1,5 @@
|
|||
/* gzguts.h -- zlib internal header definitions for gz* operations
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* Copyright (C) 2004-2019 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#if defined(_WIN32)
|
||||
# define WIDECHAR
|
||||
#endif
|
||||
|
||||
|
@ -190,6 +190,7 @@ typedef struct {
|
|||
/* just for writing */
|
||||
int level; /* compression level */
|
||||
int strategy; /* compression strategy */
|
||||
int reset; /* true if a reset is pending after a Z_FINISH */
|
||||
/* seek request */
|
||||
z_off64_t skip; /* amount to skip (already rewound if backwards) */
|
||||
int seek; /* true if seek request pending */
|
||||
|
|
10
zlib/gzlib.c
10
zlib/gzlib.c
|
@ -1,11 +1,11 @@
|
|||
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* Copyright (C) 2004-2019 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
|
||||
#if defined(_WIN32) && !defined(__BORLANDC__)
|
||||
# define LSEEK _lseeki64
|
||||
#else
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
|
@ -30,7 +30,7 @@ local gzFile gz_open OF((const void *, int, const char *));
|
|||
|
||||
The gz_strwinerror function does not change the current setting of
|
||||
GetLastError. */
|
||||
char ZLIB_INTERNAL *gz_strwinerror (error)
|
||||
char ZLIB_INTERNAL *gz_strwinerror(error)
|
||||
DWORD error;
|
||||
{
|
||||
static char buf[1024];
|
||||
|
@ -81,6 +81,8 @@ local void gz_reset(state)
|
|||
state->past = 0; /* have not read past end yet */
|
||||
state->how = LOOK; /* look for gzip header */
|
||||
}
|
||||
else /* for writing ... */
|
||||
state->reset = 0; /* no deflateReset pending */
|
||||
state->seek = 0; /* no seek request pending */
|
||||
gz_error(state, Z_OK, NULL); /* clear error */
|
||||
state->x.pos = 0; /* no uncompressed data yet */
|
||||
|
@ -397,7 +399,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
|||
/* if within raw area while reading, just go there */
|
||||
if (state->mode == GZ_READ && state->how == COPY &&
|
||||
state->x.pos + offset >= 0) {
|
||||
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
|
||||
ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
state->x.have = 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* gzread.c -- zlib functions for reading gzip files
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -157,11 +157,9 @@ local int gz_look(state)
|
|||
the output buffer is larger than the input buffer, which also assures
|
||||
space for gzungetc() */
|
||||
state->x.next = state->out;
|
||||
if (strm->avail_in) {
|
||||
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||
state->x.have = strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
}
|
||||
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||
state->x.have = strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
state->how = COPY;
|
||||
state->direct = 1;
|
||||
return 0;
|
||||
|
@ -314,9 +312,9 @@ local z_size_t gz_read(state, buf, len)
|
|||
got = 0;
|
||||
do {
|
||||
/* set n to the maximum amount of len that fits in an unsigned int */
|
||||
n = -1;
|
||||
n = (unsigned)-1;
|
||||
if (n > len)
|
||||
n = len;
|
||||
n = (unsigned)len;
|
||||
|
||||
/* first just try copying data from the output buffer */
|
||||
if (state->x.have) {
|
||||
|
@ -397,7 +395,7 @@ int ZEXPORT gzread(file, buf, len)
|
|||
}
|
||||
|
||||
/* read len or fewer bytes to buf */
|
||||
len = gz_read(state, buf, len);
|
||||
len = (unsigned)gz_read(state, buf, len);
|
||||
|
||||
/* check for an error */
|
||||
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||
|
@ -447,7 +445,6 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
|
|||
int ZEXPORT gzgetc(file)
|
||||
gzFile file;
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[1];
|
||||
gz_statep state;
|
||||
|
||||
|
@ -469,8 +466,7 @@ int ZEXPORT gzgetc(file)
|
|||
}
|
||||
|
||||
/* nothing there -- try gz_read() */
|
||||
ret = gz_read(state, buf, 1);
|
||||
return ret < 1 ? -1 : buf[0];
|
||||
return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
|
||||
}
|
||||
|
||||
int ZEXPORT gzgetc_(file)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* gzwrite.c -- zlib functions for writing gzip files
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* Copyright (C) 2004-2019 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -97,6 +97,15 @@ local int gz_comp(state, flush)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* check for a pending reset */
|
||||
if (state->reset) {
|
||||
/* don't start a new gzip member unless there is data to write */
|
||||
if (strm->avail_in == 0)
|
||||
return 0;
|
||||
deflateReset(strm);
|
||||
state->reset = 0;
|
||||
}
|
||||
|
||||
/* run deflate() on provided input until it produces no more output */
|
||||
ret = Z_OK;
|
||||
do {
|
||||
|
@ -134,7 +143,7 @@ local int gz_comp(state, flush)
|
|||
|
||||
/* if that completed a deflate stream, allow another to start */
|
||||
if (flush == Z_FINISH)
|
||||
deflateReset(strm);
|
||||
state->reset = 1;
|
||||
|
||||
/* all done, no errors */
|
||||
return 0;
|
||||
|
@ -209,7 +218,7 @@ local z_size_t gz_write(state, buf, len)
|
|||
state->in);
|
||||
copy = state->size - have;
|
||||
if (copy > len)
|
||||
copy = len;
|
||||
copy = (unsigned)len;
|
||||
memcpy(state->in + have, buf, copy);
|
||||
state->strm.avail_in += copy;
|
||||
state->x.pos += copy;
|
||||
|
@ -229,7 +238,7 @@ local z_size_t gz_write(state, buf, len)
|
|||
do {
|
||||
unsigned n = (unsigned)-1;
|
||||
if (n > len)
|
||||
n = len;
|
||||
n = (unsigned)len;
|
||||
state->strm.avail_in = n;
|
||||
state->x.pos += n;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
|
@ -349,12 +358,11 @@ int ZEXPORT gzputc(file, c)
|
|||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzputs(file, str)
|
||||
int ZEXPORT gzputs(file, s)
|
||||
gzFile file;
|
||||
const char *str;
|
||||
const char *s;
|
||||
{
|
||||
int ret;
|
||||
z_size_t len;
|
||||
z_size_t len, put;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
|
@ -367,9 +375,13 @@ int ZEXPORT gzputs(file, str)
|
|||
return -1;
|
||||
|
||||
/* write string */
|
||||
len = strlen(str);
|
||||
ret = gz_write(state, str, len);
|
||||
return ret == 0 && len != 0 ? -1 : ret;
|
||||
len = strlen(s);
|
||||
if ((int)len < 0 || (unsigned)len != len) {
|
||||
gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
|
||||
return -1;
|
||||
}
|
||||
put = gz_write(state, s, len);
|
||||
return put < len ? -1 : (int)len;
|
||||
}
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
|
@ -441,7 +453,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
|
|||
strm->avail_in = state->size;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return state->err;
|
||||
memcpy(state->in, state->in + state->size, left);
|
||||
memmove(state->in, state->in + state->size, left);
|
||||
strm->next_in = state->in;
|
||||
strm->avail_in = left;
|
||||
}
|
||||
|
@ -462,7 +474,7 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
|
|||
#else /* !STDC && !Z_HAVE_STDARG_H */
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
gzFile file;
|
||||
const char *format;
|
||||
|
@ -540,7 +552,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
|||
strm->avail_in = state->size;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return state->err;
|
||||
memcpy(state->in, state->in + state->size, left);
|
||||
memmove(state->in, state->in + state->size, left);
|
||||
strm->next_in = state->in;
|
||||
strm->avail_in = left;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* infback.c -- inflate using a call-back interface
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* Copyright (C) 1995-2022 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -66,6 +66,7 @@ int stream_size;
|
|||
state->window = window;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
state->sane = 1;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
|
@ -477,6 +478,7 @@ void FAR *out_desc;
|
|||
}
|
||||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN;
|
||||
/* fallthrough */
|
||||
|
||||
case LEN:
|
||||
/* use inflate_fast() if we have enough input and output */
|
||||
|
@ -604,25 +606,27 @@ void FAR *out_desc;
|
|||
break;
|
||||
|
||||
case DONE:
|
||||
/* inflate stream terminated properly -- write leftover output */
|
||||
/* inflate stream terminated properly */
|
||||
ret = Z_STREAM_END;
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left))
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
goto inf_leave;
|
||||
|
||||
case BAD:
|
||||
ret = Z_DATA_ERROR;
|
||||
goto inf_leave;
|
||||
|
||||
default: /* can't happen, but makes compilers happy */
|
||||
default:
|
||||
/* can't happen, but makes compilers happy */
|
||||
ret = Z_STREAM_ERROR;
|
||||
goto inf_leave;
|
||||
}
|
||||
|
||||
/* Return unused input */
|
||||
/* Write leftover output and return unused input */
|
||||
inf_leave:
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left) &&
|
||||
ret == Z_STREAM_END)
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
strm->next_in = next;
|
||||
strm->avail_in = have;
|
||||
return ret;
|
||||
|
|
|
@ -70,7 +70,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code here; /* retrieved table entry */
|
||||
code const *here; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
|
@ -107,20 +107,20 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = lcode[hold & lmask];
|
||||
here = lcode + (hold & lmask);
|
||||
dolen:
|
||||
op = (unsigned)(here.bits);
|
||||
op = (unsigned)(here->bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
op = (unsigned)(here->op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
*out++ = (unsigned char)(here.val);
|
||||
"inflate: literal 0x%02x\n", here->val));
|
||||
*out++ = (unsigned char)(here->val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(here.val);
|
||||
len = (unsigned)(here->val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
|
@ -138,14 +138,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
here = dcode + (hold & dmask);
|
||||
dodist:
|
||||
op = (unsigned)(here.bits);
|
||||
op = (unsigned)(here->bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
op = (unsigned)(here->op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(here.val);
|
||||
dist = (unsigned)(here->val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
|
@ -264,7 +264,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
here = dcode + here->val + (hold & ((1U << op) - 1));
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
|
@ -274,7 +274,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
|||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
here = lcode + here->val + (hold & ((1U << op) - 1));
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inflate.c -- zlib decompression
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* Copyright (C) 1995-2022 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -130,6 +130,7 @@ z_streamp strm;
|
|||
state->mode = HEAD;
|
||||
state->last = 0;
|
||||
state->havedict = 0;
|
||||
state->flags = -1;
|
||||
state->dmax = 32768U;
|
||||
state->head = Z_NULL;
|
||||
state->hold = 0;
|
||||
|
@ -167,6 +168,8 @@ int windowBits;
|
|||
|
||||
/* extract wrap request from windowBits parameter */
|
||||
if (windowBits < 0) {
|
||||
if (windowBits < -15)
|
||||
return Z_STREAM_ERROR;
|
||||
wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
|
@ -447,10 +450,10 @@ unsigned copy;
|
|||
|
||||
/* check function to use adler32() for zlib or crc32() for gzip */
|
||||
#ifdef GUNZIP
|
||||
# define UPDATE(check, buf, len) \
|
||||
# define UPDATE_CHECK(check, buf, len) \
|
||||
(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
|
||||
#else
|
||||
# define UPDATE(check, buf, len) adler32(check, buf, len)
|
||||
# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
|
||||
#endif
|
||||
|
||||
/* check macros for header crc */
|
||||
|
@ -670,7 +673,6 @@ int flush;
|
|||
state->mode = FLAGS;
|
||||
break;
|
||||
}
|
||||
state->flags = 0; /* expect zlib header */
|
||||
if (state->head != Z_NULL)
|
||||
state->head->done = -1;
|
||||
if (!(state->wrap & 1) || /* check if zlib header allowed */
|
||||
|
@ -697,6 +699,7 @@ int flush;
|
|||
break;
|
||||
}
|
||||
state->dmax = 1U << len;
|
||||
state->flags = 0; /* indicate zlib header */
|
||||
Tracev((stderr, "inflate: zlib header ok\n"));
|
||||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = hold & 0x200 ? DICTID : TYPE;
|
||||
|
@ -722,6 +725,7 @@ int flush;
|
|||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = TIME;
|
||||
/* fallthrough */
|
||||
case TIME:
|
||||
NEEDBITS(32);
|
||||
if (state->head != Z_NULL)
|
||||
|
@ -730,6 +734,7 @@ int flush;
|
|||
CRC4(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = OS;
|
||||
/* fallthrough */
|
||||
case OS:
|
||||
NEEDBITS(16);
|
||||
if (state->head != Z_NULL) {
|
||||
|
@ -740,6 +745,7 @@ int flush;
|
|||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = EXLEN;
|
||||
/* fallthrough */
|
||||
case EXLEN:
|
||||
if (state->flags & 0x0400) {
|
||||
NEEDBITS(16);
|
||||
|
@ -753,14 +759,16 @@ int flush;
|
|||
else if (state->head != Z_NULL)
|
||||
state->head->extra = Z_NULL;
|
||||
state->mode = EXTRA;
|
||||
/* fallthrough */
|
||||
case EXTRA:
|
||||
if (state->flags & 0x0400) {
|
||||
copy = state->length;
|
||||
if (copy > have) copy = have;
|
||||
if (copy) {
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->extra != Z_NULL) {
|
||||
len = state->head->extra_len - state->length;
|
||||
state->head->extra != Z_NULL &&
|
||||
(len = state->head->extra_len - state->length) <
|
||||
state->head->extra_max) {
|
||||
zmemcpy(state->head->extra + len, next,
|
||||
len + copy > state->head->extra_max ?
|
||||
state->head->extra_max - len : copy);
|
||||
|
@ -775,6 +783,7 @@ int flush;
|
|||
}
|
||||
state->length = 0;
|
||||
state->mode = NAME;
|
||||
/* fallthrough */
|
||||
case NAME:
|
||||
if (state->flags & 0x0800) {
|
||||
if (have == 0) goto inf_leave;
|
||||
|
@ -796,6 +805,7 @@ int flush;
|
|||
state->head->name = Z_NULL;
|
||||
state->length = 0;
|
||||
state->mode = COMMENT;
|
||||
/* fallthrough */
|
||||
case COMMENT:
|
||||
if (state->flags & 0x1000) {
|
||||
if (have == 0) goto inf_leave;
|
||||
|
@ -816,6 +826,7 @@ int flush;
|
|||
else if (state->head != Z_NULL)
|
||||
state->head->comment = Z_NULL;
|
||||
state->mode = HCRC;
|
||||
/* fallthrough */
|
||||
case HCRC:
|
||||
if (state->flags & 0x0200) {
|
||||
NEEDBITS(16);
|
||||
|
@ -839,6 +850,7 @@ int flush;
|
|||
strm->adler = state->check = ZSWAP32(hold);
|
||||
INITBITS();
|
||||
state->mode = DICT;
|
||||
/* fallthrough */
|
||||
case DICT:
|
||||
if (state->havedict == 0) {
|
||||
RESTORE();
|
||||
|
@ -846,8 +858,10 @@ int flush;
|
|||
}
|
||||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = TYPE;
|
||||
/* fallthrough */
|
||||
case TYPE:
|
||||
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
|
||||
/* fallthrough */
|
||||
case TYPEDO:
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
|
@ -898,8 +912,10 @@ int flush;
|
|||
INITBITS();
|
||||
state->mode = COPY_;
|
||||
if (flush == Z_TREES) goto inf_leave;
|
||||
/* fallthrough */
|
||||
case COPY_:
|
||||
state->mode = COPY;
|
||||
/* fallthrough */
|
||||
case COPY:
|
||||
copy = state->length;
|
||||
if (copy) {
|
||||
|
@ -935,6 +951,7 @@ int flush;
|
|||
Tracev((stderr, "inflate: table sizes ok\n"));
|
||||
state->have = 0;
|
||||
state->mode = LENLENS;
|
||||
/* fallthrough */
|
||||
case LENLENS:
|
||||
while (state->have < state->ncode) {
|
||||
NEEDBITS(3);
|
||||
|
@ -956,6 +973,7 @@ int flush;
|
|||
Tracev((stderr, "inflate: code lengths ok\n"));
|
||||
state->have = 0;
|
||||
state->mode = CODELENS;
|
||||
/* fallthrough */
|
||||
case CODELENS:
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
|
@ -1039,8 +1057,10 @@ int flush;
|
|||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN_;
|
||||
if (flush == Z_TREES) goto inf_leave;
|
||||
/* fallthrough */
|
||||
case LEN_:
|
||||
state->mode = LEN;
|
||||
/* fallthrough */
|
||||
case LEN:
|
||||
if (have >= 6 && left >= 258) {
|
||||
RESTORE();
|
||||
|
@ -1090,6 +1110,7 @@ int flush;
|
|||
}
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
state->mode = LENEXT;
|
||||
/* fallthrough */
|
||||
case LENEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
|
@ -1100,6 +1121,7 @@ int flush;
|
|||
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||
state->was = state->length;
|
||||
state->mode = DIST;
|
||||
/* fallthrough */
|
||||
case DIST:
|
||||
for (;;) {
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
|
@ -1127,6 +1149,7 @@ int flush;
|
|||
state->offset = (unsigned)here.val;
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
state->mode = DISTEXT;
|
||||
/* fallthrough */
|
||||
case DISTEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
|
@ -1143,6 +1166,7 @@ int flush;
|
|||
#endif
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
state->mode = MATCH;
|
||||
/* fallthrough */
|
||||
case MATCH:
|
||||
if (left == 0) goto inf_leave;
|
||||
copy = out - left;
|
||||
|
@ -1202,7 +1226,7 @@ int flush;
|
|||
state->total += out;
|
||||
if ((state->wrap & 4) && out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, put - out, out);
|
||||
UPDATE_CHECK(state->check, put - out, out);
|
||||
out = left;
|
||||
if ((state->wrap & 4) && (
|
||||
#ifdef GUNZIP
|
||||
|
@ -1218,10 +1242,11 @@ int flush;
|
|||
}
|
||||
#ifdef GUNZIP
|
||||
state->mode = LENGTH;
|
||||
/* fallthrough */
|
||||
case LENGTH:
|
||||
if (state->wrap && state->flags) {
|
||||
NEEDBITS(32);
|
||||
if (hold != (state->total & 0xffffffffUL)) {
|
||||
if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
|
||||
strm->msg = (char *)"incorrect length check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
|
@ -1231,6 +1256,7 @@ int flush;
|
|||
}
|
||||
#endif
|
||||
state->mode = DONE;
|
||||
/* fallthrough */
|
||||
case DONE:
|
||||
ret = Z_STREAM_END;
|
||||
goto inf_leave;
|
||||
|
@ -1240,6 +1266,7 @@ int flush;
|
|||
case MEM:
|
||||
return Z_MEM_ERROR;
|
||||
case SYNC:
|
||||
/* fallthrough */
|
||||
default:
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
|
@ -1265,7 +1292,7 @@ int flush;
|
|||
state->total += out;
|
||||
if ((state->wrap & 4) && out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, strm->next_out - out, out);
|
||||
UPDATE_CHECK(state->check, strm->next_out - out, out);
|
||||
strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
|
||||
(state->mode == TYPE ? 128 : 0) +
|
||||
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
|
||||
|
@ -1401,6 +1428,7 @@ int ZEXPORT inflateSync(strm)
|
|||
z_streamp strm;
|
||||
{
|
||||
unsigned len; /* number of bytes to look at or looked at */
|
||||
int flags; /* temporary to save header status */
|
||||
unsigned long in, out; /* temporary to save total_in and total_out */
|
||||
unsigned char buf[4]; /* to restore bit buffer to byte string */
|
||||
struct inflate_state FAR *state;
|
||||
|
@ -1433,9 +1461,15 @@ z_streamp strm;
|
|||
|
||||
/* return no joy or set up to restart inflate() on a new block */
|
||||
if (state->have != 4) return Z_DATA_ERROR;
|
||||
if (state->flags == -1)
|
||||
state->wrap = 0; /* if no header yet, treat as raw */
|
||||
else
|
||||
state->wrap &= ~4; /* no point in computing a check value now */
|
||||
flags = state->flags;
|
||||
in = strm->total_in; out = strm->total_out;
|
||||
inflateReset(strm);
|
||||
strm->total_in = in; strm->total_out = out;
|
||||
state->flags = flags;
|
||||
state->mode = TYPE;
|
||||
return Z_OK;
|
||||
}
|
||||
|
@ -1531,7 +1565,7 @@ int check;
|
|||
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (check)
|
||||
if (check && state->wrap)
|
||||
state->wrap |= 4;
|
||||
else
|
||||
state->wrap &= ~4;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* Copyright (C) 1995-2019 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -86,7 +86,8 @@ struct inflate_state {
|
|||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
|
||||
bit 2 true to validate check value */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
int flags; /* gzip header method and flags, 0 if zlib, or
|
||||
-1 if raw or no header yet */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
unsigned long check; /* protected copy of check value */
|
||||
unsigned long total; /* protected copy of output count */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2017 Mark Adler
|
||||
* Copyright (C) 1995-2022 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
|||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
|
||||
" inflate 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
|
||||
|
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
|||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 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,
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef struct {
|
|||
/* Maximum size of the dynamic table. The maximum number of code structures is
|
||||
1444, which is the sum of 852 for literal/length codes and 592 for distance
|
||||
codes. These values were found by exhaustive searches using the program
|
||||
examples/enough.c found in the zlib distribtution. The arguments to that
|
||||
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 30 6 15" for distance codes returns 592.
|
||||
|
|
|
@ -14,9 +14,9 @@ $! 0.02 20061008 Adapt to new Makefile.in
|
|||
$! 0.03 20091224 Add support for large file check
|
||||
$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
|
||||
$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
|
||||
$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
|
||||
$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new examples
|
||||
$! subdir path, update module search in makefile.in
|
||||
$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
|
||||
$! 0.07 20120115 Triggered by work done by Alexey Chupahin completely redesigned
|
||||
$! shared image creation
|
||||
$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
|
||||
$! image
|
||||
|
|
|
@ -440,9 +440,8 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
|
|||
CHECK_ERR(err, "inflateSync");
|
||||
|
||||
err = inflate(&d_stream, Z_FINISH);
|
||||
if (err != Z_DATA_ERROR) {
|
||||
fprintf(stderr, "inflate should report DATA_ERROR\n");
|
||||
/* Because of incorrect adler32 */
|
||||
if (err != Z_STREAM_END) {
|
||||
fprintf(stderr, "inflate should report Z_STREAM_END\n");
|
||||
exit(1);
|
||||
}
|
||||
err = inflateEnd(&d_stream);
|
||||
|
@ -556,7 +555,8 @@ int main(argc, argv)
|
|||
exit(1);
|
||||
|
||||
} else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
|
||||
fprintf(stderr, "warning: different zlib version\n");
|
||||
fprintf(stderr, "warning: different zlib version linked: %s\n",
|
||||
zlibVersion());
|
||||
}
|
||||
|
||||
printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
|
||||
|
|
|
@ -500,7 +500,7 @@ void file_uncompress(file)
|
|||
char *infile, *outfile;
|
||||
FILE *out;
|
||||
gzFile in;
|
||||
unsigned len = strlen(file);
|
||||
z_size_t len = strlen(file);
|
||||
|
||||
if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
|
||||
fprintf(stderr, "%s: filename too long\n", prog);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" ?>
|
||||
<package name="zlib" version="1.2.11">
|
||||
<library name="zlib" dlversion="1.2.11" dlname="z">
|
||||
<package name="zlib" version="1.2.13">
|
||||
<library name="zlib" dlversion="1.2.13" dlname="z">
|
||||
<property name="description"> zip compression library </property>
|
||||
<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
|
||||
|
||||
|
|
192
zlib/trees.c
192
zlib/trees.c
|
@ -1,5 +1,5 @@
|
|||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995-2017 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2021 Jean-loup Gailly
|
||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
@ -149,7 +149,7 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
|||
local void compress_block OF((deflate_state *s, const ct_data *ltree,
|
||||
const ct_data *dtree));
|
||||
local int detect_data_type OF((deflate_state *s));
|
||||
local unsigned bi_reverse OF((unsigned value, int length));
|
||||
local unsigned bi_reverse OF((unsigned code, int len));
|
||||
local void bi_windup OF((deflate_state *s));
|
||||
local void bi_flush OF((deflate_state *s));
|
||||
|
||||
|
@ -193,7 +193,7 @@ local void send_bits(s, value, length)
|
|||
s->bits_sent += (ulg)length;
|
||||
|
||||
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
||||
* (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid))
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (s->bi_valid > (int)Buf_size - length) {
|
||||
|
@ -256,7 +256,7 @@ local void tr_static_init()
|
|||
length = 0;
|
||||
for (code = 0; code < LENGTH_CODES-1; code++) {
|
||||
base_length[code] = length;
|
||||
for (n = 0; n < (1<<extra_lbits[code]); n++) {
|
||||
for (n = 0; n < (1 << extra_lbits[code]); n++) {
|
||||
_length_code[length++] = (uch)code;
|
||||
}
|
||||
}
|
||||
|
@ -265,13 +265,13 @@ local void tr_static_init()
|
|||
* in two different ways: code 284 + 5 bits or code 285, so we
|
||||
* overwrite length_code[255] to use the best encoding:
|
||||
*/
|
||||
_length_code[length-1] = (uch)code;
|
||||
_length_code[length - 1] = (uch)code;
|
||||
|
||||
/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
|
||||
dist = 0;
|
||||
for (code = 0 ; code < 16; code++) {
|
||||
base_dist[code] = dist;
|
||||
for (n = 0; n < (1<<extra_dbits[code]); n++) {
|
||||
for (n = 0; n < (1 << extra_dbits[code]); n++) {
|
||||
_dist_code[dist++] = (uch)code;
|
||||
}
|
||||
}
|
||||
|
@ -279,11 +279,11 @@ local void tr_static_init()
|
|||
dist >>= 7; /* from now on, all distances are divided by 128 */
|
||||
for ( ; code < D_CODES; code++) {
|
||||
base_dist[code] = dist << 7;
|
||||
for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
|
||||
for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
|
||||
_dist_code[256 + dist++] = (uch)code;
|
||||
}
|
||||
}
|
||||
Assert (dist == 256, "tr_static_init: 256+dist != 512");
|
||||
Assert (dist == 256, "tr_static_init: 256 + dist != 512");
|
||||
|
||||
/* Construct the codes of the static literal tree */
|
||||
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
|
||||
|
@ -312,7 +312,7 @@ local void tr_static_init()
|
|||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Genererate the file trees.h describing the static trees.
|
||||
* Generate the file trees.h describing the static trees.
|
||||
*/
|
||||
#ifdef GEN_TREES_H
|
||||
# ifndef ZLIB_DEBUG
|
||||
|
@ -321,7 +321,7 @@ local void tr_static_init()
|
|||
|
||||
# define SEPARATOR(i, last, width) \
|
||||
((i) == (last)? "\n};\n\n" : \
|
||||
((i) % (width) == (width)-1 ? ",\n" : ", "))
|
||||
((i) % (width) == (width) - 1 ? ",\n" : ", "))
|
||||
|
||||
void gen_trees_header()
|
||||
{
|
||||
|
@ -416,7 +416,7 @@ local void init_block(s)
|
|||
|
||||
s->dyn_ltree[END_BLOCK].Freq = 1;
|
||||
s->opt_len = s->static_len = 0L;
|
||||
s->last_lit = s->matches = 0;
|
||||
s->sym_next = s->matches = 0;
|
||||
}
|
||||
|
||||
#define SMALLEST 1
|
||||
|
@ -458,7 +458,7 @@ local void pqdownheap(s, tree, k)
|
|||
while (j <= s->heap_len) {
|
||||
/* Set j to the smallest of the two sons: */
|
||||
if (j < s->heap_len &&
|
||||
smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
|
||||
smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) {
|
||||
j++;
|
||||
}
|
||||
/* Exit if v is smaller than both sons */
|
||||
|
@ -507,7 +507,7 @@ local void gen_bitlen(s, desc)
|
|||
*/
|
||||
tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
|
||||
|
||||
for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
|
||||
for (h = s->heap_max + 1; h < HEAP_SIZE; h++) {
|
||||
n = s->heap[h];
|
||||
bits = tree[tree[n].Dad].Len + 1;
|
||||
if (bits > max_length) bits = max_length, overflow++;
|
||||
|
@ -518,7 +518,7 @@ local void gen_bitlen(s, desc)
|
|||
|
||||
s->bl_count[bits]++;
|
||||
xbits = 0;
|
||||
if (n >= base) xbits = extra[n-base];
|
||||
if (n >= base) xbits = extra[n - base];
|
||||
f = tree[n].Freq;
|
||||
s->opt_len += (ulg)f * (unsigned)(bits + xbits);
|
||||
if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
|
||||
|
@ -530,10 +530,10 @@ local void gen_bitlen(s, desc)
|
|||
|
||||
/* Find the first bit length which could increase: */
|
||||
do {
|
||||
bits = max_length-1;
|
||||
bits = max_length - 1;
|
||||
while (s->bl_count[bits] == 0) bits--;
|
||||
s->bl_count[bits]--; /* move one leaf down the tree */
|
||||
s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
|
||||
s->bl_count[bits]--; /* move one leaf down the tree */
|
||||
s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */
|
||||
s->bl_count[max_length]--;
|
||||
/* The brother of the overflow item also moves one step up,
|
||||
* but this does not affect bl_count[max_length]
|
||||
|
@ -569,7 +569,7 @@ local void gen_bitlen(s, desc)
|
|||
* OUT assertion: the field code is set for all tree elements of non
|
||||
* zero code length.
|
||||
*/
|
||||
local void gen_codes (tree, max_code, bl_count)
|
||||
local void gen_codes(tree, max_code, bl_count)
|
||||
ct_data *tree; /* the tree to decorate */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
ushf *bl_count; /* number of codes at each bit length */
|
||||
|
@ -583,13 +583,13 @@ local void gen_codes (tree, max_code, bl_count)
|
|||
* without bit reversal.
|
||||
*/
|
||||
for (bits = 1; bits <= MAX_BITS; bits++) {
|
||||
code = (code + bl_count[bits-1]) << 1;
|
||||
code = (code + bl_count[bits - 1]) << 1;
|
||||
next_code[bits] = (ush)code;
|
||||
}
|
||||
/* Check that the bit counts in bl_count are consistent. The last code
|
||||
* must be all ones.
|
||||
*/
|
||||
Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
|
||||
Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
|
||||
"inconsistent bit counts");
|
||||
Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
||||
|
||||
|
@ -600,7 +600,7 @@ local void gen_codes (tree, max_code, bl_count)
|
|||
tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
|
||||
|
||||
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
|
||||
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
|
||||
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,7 +624,7 @@ local void build_tree(s, desc)
|
|||
int node; /* new node being created */
|
||||
|
||||
/* Construct the initial heap, with least frequent element in
|
||||
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
|
||||
* heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1].
|
||||
* heap[0] is not used.
|
||||
*/
|
||||
s->heap_len = 0, s->heap_max = HEAP_SIZE;
|
||||
|
@ -652,7 +652,7 @@ local void build_tree(s, desc)
|
|||
}
|
||||
desc->max_code = max_code;
|
||||
|
||||
/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
||||
/* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree,
|
||||
* establish sub-heaps of increasing lengths:
|
||||
*/
|
||||
for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
|
||||
|
@ -700,7 +700,7 @@ local void build_tree(s, desc)
|
|||
* Scan a literal or distance tree to determine the frequencies of the codes
|
||||
* in the bit length tree.
|
||||
*/
|
||||
local void scan_tree (s, tree, max_code)
|
||||
local void scan_tree(s, tree, max_code)
|
||||
deflate_state *s;
|
||||
ct_data *tree; /* the tree to be scanned */
|
||||
int max_code; /* and its largest code of non zero frequency */
|
||||
|
@ -714,10 +714,10 @@ local void scan_tree (s, tree, max_code)
|
|||
int min_count = 4; /* min repeat count */
|
||||
|
||||
if (nextlen == 0) max_count = 138, min_count = 3;
|
||||
tree[max_code+1].Len = (ush)0xffff; /* guard */
|
||||
tree[max_code + 1].Len = (ush)0xffff; /* guard */
|
||||
|
||||
for (n = 0; n <= max_code; n++) {
|
||||
curlen = nextlen; nextlen = tree[n+1].Len;
|
||||
curlen = nextlen; nextlen = tree[n + 1].Len;
|
||||
if (++count < max_count && curlen == nextlen) {
|
||||
continue;
|
||||
} else if (count < min_count) {
|
||||
|
@ -745,7 +745,7 @@ local void scan_tree (s, tree, max_code)
|
|||
* Send a literal or distance tree in compressed form, using the codes in
|
||||
* bl_tree.
|
||||
*/
|
||||
local void send_tree (s, tree, max_code)
|
||||
local void send_tree(s, tree, max_code)
|
||||
deflate_state *s;
|
||||
ct_data *tree; /* the tree to be scanned */
|
||||
int max_code; /* and its largest code of non zero frequency */
|
||||
|
@ -758,11 +758,11 @@ local void send_tree (s, tree, max_code)
|
|||
int max_count = 7; /* max repeat count */
|
||||
int min_count = 4; /* min repeat count */
|
||||
|
||||
/* tree[max_code+1].Len = -1; */ /* guard already set */
|
||||
/* tree[max_code + 1].Len = -1; */ /* guard already set */
|
||||
if (nextlen == 0) max_count = 138, min_count = 3;
|
||||
|
||||
for (n = 0; n <= max_code; n++) {
|
||||
curlen = nextlen; nextlen = tree[n+1].Len;
|
||||
curlen = nextlen; nextlen = tree[n + 1].Len;
|
||||
if (++count < max_count && curlen == nextlen) {
|
||||
continue;
|
||||
} else if (count < min_count) {
|
||||
|
@ -773,13 +773,13 @@ local void send_tree (s, tree, max_code)
|
|||
send_code(s, curlen, s->bl_tree); count--;
|
||||
}
|
||||
Assert(count >= 3 && count <= 6, " 3_6?");
|
||||
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
|
||||
send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2);
|
||||
|
||||
} else if (count <= 10) {
|
||||
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
|
||||
send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3);
|
||||
|
||||
} else {
|
||||
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
|
||||
send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7);
|
||||
}
|
||||
count = 0; prevlen = curlen;
|
||||
if (nextlen == 0) {
|
||||
|
@ -807,8 +807,8 @@ local int build_bl_tree(s)
|
|||
|
||||
/* Build the bit length tree: */
|
||||
build_tree(s, (tree_desc *)(&(s->bl_desc)));
|
||||
/* opt_len now includes the length of the tree representations, except
|
||||
* the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
|
||||
/* opt_len now includes the length of the tree representations, except the
|
||||
* lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts.
|
||||
*/
|
||||
|
||||
/* Determine the number of bit length codes to send. The pkzip format
|
||||
|
@ -819,7 +819,7 @@ local int build_bl_tree(s)
|
|||
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
|
||||
}
|
||||
/* Update opt_len to include the bit length tree and counts */
|
||||
s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
|
||||
s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4;
|
||||
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
|
||||
s->opt_len, s->static_len));
|
||||
|
||||
|
@ -841,19 +841,19 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
|||
Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
|
||||
"too many codes");
|
||||
Tracev((stderr, "\nbl counts: "));
|
||||
send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
|
||||
send_bits(s, dcodes-1, 5);
|
||||
send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
|
||||
send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
|
||||
send_bits(s, dcodes - 1, 5);
|
||||
send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
|
||||
for (rank = 0; rank < blcodes; rank++) {
|
||||
Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
|
||||
send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
|
||||
}
|
||||
Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
|
||||
|
||||
send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
|
||||
send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */
|
||||
Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
|
||||
|
||||
send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
|
||||
send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */
|
||||
Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
||||
}
|
||||
|
||||
|
@ -866,17 +866,18 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
|||
ulg stored_len; /* length of input block */
|
||||
int last; /* one if this is the last block for a file */
|
||||
{
|
||||
send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
|
||||
send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
put_short(s, (ush)stored_len);
|
||||
put_short(s, (ush)~stored_len);
|
||||
zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
|
||||
if (stored_len)
|
||||
zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
|
||||
s->pending += stored_len;
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
|
||||
s->compressed_len += (stored_len + 4) << 3;
|
||||
s->bits_sent += 2*16;
|
||||
s->bits_sent += stored_len<<3;
|
||||
s->bits_sent += stored_len << 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -942,14 +943,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
|||
max_blindex = build_bl_tree(s);
|
||||
|
||||
/* Determine the best encoding. Compute the block lengths in bytes. */
|
||||
opt_lenb = (s->opt_len+3+7)>>3;
|
||||
static_lenb = (s->static_len+3+7)>>3;
|
||||
opt_lenb = (s->opt_len + 3 + 7) >> 3;
|
||||
static_lenb = (s->static_len + 3 + 7) >> 3;
|
||||
|
||||
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
||||
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
||||
s->last_lit));
|
||||
s->sym_next / 3));
|
||||
|
||||
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
|
||||
#ifndef FORCE_STATIC
|
||||
if (static_lenb <= opt_lenb || s->strategy == Z_FIXED)
|
||||
#endif
|
||||
opt_lenb = static_lenb;
|
||||
|
||||
} else {
|
||||
Assert(buf != (char*)0, "lost buf");
|
||||
|
@ -959,7 +963,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
|||
#ifdef FORCE_STORED
|
||||
if (buf != (char*)0) { /* force stored block */
|
||||
#else
|
||||
if (stored_len+4 <= opt_lenb && buf != (char*)0) {
|
||||
if (stored_len + 4 <= opt_lenb && buf != (char*)0) {
|
||||
/* 4: two words for the lengths */
|
||||
#endif
|
||||
/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
||||
|
@ -970,21 +974,17 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
|||
*/
|
||||
_tr_stored_block(s, buf, stored_len, last);
|
||||
|
||||
#ifdef FORCE_STATIC
|
||||
} else if (static_lenb >= 0) { /* force static trees */
|
||||
#else
|
||||
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
||||
#endif
|
||||
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
||||
} else if (static_lenb == opt_lenb) {
|
||||
send_bits(s, (STATIC_TREES<<1) + last, 3);
|
||||
compress_block(s, (const ct_data *)static_ltree,
|
||||
(const ct_data *)static_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 3 + s->static_len;
|
||||
#endif
|
||||
} else {
|
||||
send_bits(s, (DYN_TREES<<1)+last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
||||
max_blindex+1);
|
||||
send_bits(s, (DYN_TREES<<1) + last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1,
|
||||
max_blindex + 1);
|
||||
compress_block(s, (const ct_data *)s->dyn_ltree,
|
||||
(const ct_data *)s->dyn_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
|
@ -1003,21 +1003,22 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
|||
s->compressed_len += 7; /* align on byte boundary */
|
||||
#endif
|
||||
}
|
||||
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
||||
s->compressed_len-7*last));
|
||||
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3,
|
||||
s->compressed_len - 7*last));
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Save the match info and tally the frequency counts. Return true if
|
||||
* the current block must be flushed.
|
||||
*/
|
||||
int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
int ZLIB_INTERNAL _tr_tally(s, dist, lc)
|
||||
deflate_state *s;
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */
|
||||
{
|
||||
s->d_buf[s->last_lit] = (ush)dist;
|
||||
s->l_buf[s->last_lit++] = (uch)lc;
|
||||
s->sym_buf[s->sym_next++] = (uch)dist;
|
||||
s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
|
||||
s->sym_buf[s->sym_next++] = (uch)lc;
|
||||
if (dist == 0) {
|
||||
/* lc is the unmatched char */
|
||||
s->dyn_ltree[lc].Freq++;
|
||||
|
@ -1029,33 +1030,10 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
|||
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
|
||||
(ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
|
||||
|
||||
s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
|
||||
s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++;
|
||||
s->dyn_dtree[d_code(dist)].Freq++;
|
||||
}
|
||||
|
||||
#ifdef TRUNCATE_BLOCK
|
||||
/* Try to guess if it is profitable to stop the current block here */
|
||||
if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
|
||||
/* Compute an upper bound for the compressed length */
|
||||
ulg out_length = (ulg)s->last_lit*8L;
|
||||
ulg in_length = (ulg)((long)s->strstart - s->block_start);
|
||||
int dcode;
|
||||
for (dcode = 0; dcode < D_CODES; dcode++) {
|
||||
out_length += (ulg)s->dyn_dtree[dcode].Freq *
|
||||
(5L+extra_dbits[dcode]);
|
||||
}
|
||||
out_length >>= 3;
|
||||
Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
|
||||
s->last_lit, in_length, out_length,
|
||||
100L - out_length*100L/in_length));
|
||||
if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
|
||||
}
|
||||
#endif
|
||||
return (s->last_lit == s->lit_bufsize-1);
|
||||
/* We avoid equality with lit_bufsize because of wraparound at 64K
|
||||
* on 16 bit machines and because stored blocks are restricted to
|
||||
* 64K-1 bytes.
|
||||
*/
|
||||
return (s->sym_next == s->sym_end);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -1068,20 +1046,21 @@ local void compress_block(s, ltree, dtree)
|
|||
{
|
||||
unsigned dist; /* distance of matched string */
|
||||
int lc; /* match length or unmatched char (if dist == 0) */
|
||||
unsigned lx = 0; /* running index in l_buf */
|
||||
unsigned sx = 0; /* running index in sym_buf */
|
||||
unsigned code; /* the code to send */
|
||||
int extra; /* number of extra bits to send */
|
||||
|
||||
if (s->last_lit != 0) do {
|
||||
dist = s->d_buf[lx];
|
||||
lc = s->l_buf[lx++];
|
||||
if (s->sym_next != 0) do {
|
||||
dist = s->sym_buf[sx++] & 0xff;
|
||||
dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
|
||||
lc = s->sym_buf[sx++];
|
||||
if (dist == 0) {
|
||||
send_code(s, lc, ltree); /* send a literal byte */
|
||||
Tracecv(isgraph(lc), (stderr," '%c' ", lc));
|
||||
} else {
|
||||
/* Here, lc is the match length - MIN_MATCH */
|
||||
code = _length_code[lc];
|
||||
send_code(s, code+LITERALS+1, ltree); /* send the length code */
|
||||
send_code(s, code + LITERALS + 1, ltree); /* send length code */
|
||||
extra = extra_lbits[code];
|
||||
if (extra != 0) {
|
||||
lc -= base_length[code];
|
||||
|
@ -1099,11 +1078,10 @@ local void compress_block(s, ltree, dtree)
|
|||
}
|
||||
} /* literal or match pair ? */
|
||||
|
||||
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
|
||||
Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
|
||||
"pendingBuf overflow");
|
||||
/* Check that the overlay between pending_buf and sym_buf is ok: */
|
||||
Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
|
||||
|
||||
} while (lx < s->last_lit);
|
||||
} while (sx < s->sym_next);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
}
|
||||
|
@ -1112,9 +1090,9 @@ local void compress_block(s, ltree, dtree)
|
|||
* Check if the data type is TEXT or BINARY, using the following algorithm:
|
||||
* - TEXT if the two conditions below are satisfied:
|
||||
* a) There are no non-portable control characters belonging to the
|
||||
* "black list" (0..6, 14..25, 28..31).
|
||||
* "block list" (0..6, 14..25, 28..31).
|
||||
* b) There is at least one printable character belonging to the
|
||||
* "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
|
||||
* "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
|
||||
* - BINARY otherwise.
|
||||
* - The following partially-portable control characters form a
|
||||
* "gray list" that is ignored in this detection algorithm:
|
||||
|
@ -1124,19 +1102,19 @@ local void compress_block(s, ltree, dtree)
|
|||
local int detect_data_type(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
/* black_mask is the bit mask of black-listed bytes
|
||||
/* block_mask is the bit mask of block-listed bytes
|
||||
* set bits 0..6, 14..25, and 28..31
|
||||
* 0xf3ffc07f = binary 11110011111111111100000001111111
|
||||
*/
|
||||
unsigned long black_mask = 0xf3ffc07fUL;
|
||||
unsigned long block_mask = 0xf3ffc07fUL;
|
||||
int n;
|
||||
|
||||
/* Check for non-textual ("black-listed") bytes. */
|
||||
for (n = 0; n <= 31; n++, black_mask >>= 1)
|
||||
if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
|
||||
/* Check for non-textual ("block-listed") bytes. */
|
||||
for (n = 0; n <= 31; n++, block_mask >>= 1)
|
||||
if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
|
||||
return Z_BINARY;
|
||||
|
||||
/* Check for textual ("white-listed") bytes. */
|
||||
/* Check for textual ("allow-listed") bytes. */
|
||||
if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
|
||||
|| s->dyn_ltree[13].Freq != 0)
|
||||
return Z_TEXT;
|
||||
|
@ -1144,7 +1122,7 @@ local int detect_data_type(s)
|
|||
if (s->dyn_ltree[n].Freq != 0)
|
||||
return Z_TEXT;
|
||||
|
||||
/* There are no "black-listed" or "white-listed" bytes:
|
||||
/* There are no "block-listed" or "allow-listed" bytes:
|
||||
* this stream either is empty or has tolerated ("gray-listed") bytes only.
|
||||
*/
|
||||
return Z_BINARY;
|
||||
|
@ -1198,6 +1176,6 @@ local void bi_windup(s)
|
|||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->bits_sent = (s->bits_sent+7) & ~7;
|
||||
s->bits_sent = (s->bits_sent + 7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
Z_DATA_ERROR if the input data was corrupted, including if the input data is
|
||||
an incomplete zlib stream.
|
||||
*/
|
||||
int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
|
@ -83,7 +83,7 @@ int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
|
|||
err;
|
||||
}
|
||||
|
||||
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||
int ZEXPORT uncompress(dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
# Usage:
|
||||
# make -f win32/Makefile.bor
|
||||
# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
|
||||
|
||||
# ------------ Borland C++ ------------
|
||||
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#
|
||||
# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
|
||||
#
|
||||
# To use the asm code, type:
|
||||
# cp contrib/asm?86/match.S ./match.S
|
||||
# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
|
||||
#
|
||||
# To install libz.a, zconf.h and zlib.h in the system directories, type:
|
||||
#
|
||||
# make install -fwin32/Makefile.gcc
|
||||
|
@ -38,7 +34,6 @@ IMPLIB = libz.dll.a
|
|||
#
|
||||
SHARED_MODE=0
|
||||
|
||||
#LOC = -DASMV
|
||||
#LOC = -DZLIB_DEBUG -g
|
||||
|
||||
PREFIX =
|
||||
|
|
|
@ -4,10 +4,6 @@
|
|||
# Usage:
|
||||
# nmake -f win32/Makefile.msc (standard build)
|
||||
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
|
||||
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
|
||||
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
|
||||
# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
|
||||
# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
|
||||
|
||||
# The toplevel directory of the source tree.
|
||||
#
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.11 is a general purpose data compression library. All the code is
|
||||
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://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
||||
|
@ -22,7 +22,7 @@ before asking for help.
|
|||
|
||||
Manifest:
|
||||
|
||||
The package zlib-1.2.11-win32-x86.zip will contain the following files:
|
||||
The package zlib-1.2.13-win32-x86.zip will contain the following files:
|
||||
|
||||
README-WIN32.txt This document
|
||||
ChangeLog Changes since previous zlib packages
|
||||
|
|
|
@ -69,6 +69,7 @@ EXPORTS
|
|||
gzoffset64
|
||||
adler32_combine64
|
||||
crc32_combine64
|
||||
crc32_combine_gen64
|
||||
; checksum functions
|
||||
adler32
|
||||
adler32_z
|
||||
|
@ -76,6 +77,8 @@ EXPORTS
|
|||
crc32_z
|
||||
adler32_combine
|
||||
crc32_combine
|
||||
crc32_combine_gen
|
||||
crc32_combine_op
|
||||
; various hacks, don't look :)
|
||||
deflateInit_
|
||||
deflateInit2_
|
||||
|
|
|
@ -26,7 +26,7 @@ BEGIN
|
|||
VALUE "FileDescription", "zlib data compression library\0"
|
||||
VALUE "FileVersion", ZLIB_VERSION "\0"
|
||||
VALUE "InternalName", "zlib1.dll\0"
|
||||
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
|
||||
VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0"
|
||||
VALUE "OriginalFilename", "zlib1.dll\0"
|
||||
VALUE "ProductName", "zlib\0"
|
||||
VALUE "ProductVersion", ZLIB_VERSION "\0"
|
||||
|
|
19
zlib/zconf.h
19
zlib/zconf.h
|
@ -38,6 +38,9 @@
|
|||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define crc32_combine_gen z_crc32_combine_gen
|
||||
# define crc32_combine_gen64 z_crc32_combine_gen64
|
||||
# define crc32_combine_op z_crc32_combine_op
|
||||
# define crc32_z z_crc32_z
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
|
@ -349,6 +352,9 @@
|
|||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
|
@ -467,11 +473,18 @@ typedef uLong FAR uLongf;
|
|||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# ifdef __WATCOMC__
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# if defined(Z_HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define crc32_combine_gen z_crc32_combine_gen
|
||||
# define crc32_combine_gen64 z_crc32_combine_gen64
|
||||
# define crc32_combine_op z_crc32_combine_op
|
||||
# define crc32_z z_crc32_z
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
|
@ -351,6 +354,9 @@
|
|||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
|
@ -469,11 +475,18 @@ typedef uLong FAR uLongf;
|
|||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# ifdef __WATCOMC__
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# if defined(Z_HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define crc32_combine_gen z_crc32_combine_gen
|
||||
# define crc32_combine_gen64 z_crc32_combine_gen64
|
||||
# define crc32_combine_op z_crc32_combine_op
|
||||
# define crc32_z z_crc32_z
|
||||
# define deflate z_deflate
|
||||
# define deflateBound z_deflateBound
|
||||
|
@ -349,6 +352,9 @@
|
|||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
|
@ -467,11 +473,18 @@ typedef uLong FAR uLongf;
|
|||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# ifdef __WATCOMC__
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_HAVE_UNISTD_H
|
||||
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
# endif
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# if defined(Z_HAVE_UNISTD_H)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH ZLIB 3 "15 Jan 2017"
|
||||
.TH ZLIB 3 "13 Oct 2022"
|
||||
.SH NAME
|
||||
zlib \- compression/decompression library
|
||||
.SH SYNOPSIS
|
||||
|
@ -105,9 +105,9 @@ before asking for help.
|
|||
Send questions and/or comments to zlib@gzip.org,
|
||||
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
|
||||
.SH AUTHORS AND LICENSE
|
||||
Version 1.2.11
|
||||
Version 1.2.13
|
||||
.LP
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||||
.LP
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
BIN
zlib/zlib.3.pdf
BIN
zlib/zlib.3.pdf
Binary file not shown.
235
zlib/zlib.h
235
zlib/zlib.h
|
@ -1,7 +1,7 @@
|
|||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.11, January 15th, 2017
|
||||
version 1.2.13, October 13th, 2022
|
||||
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
Copyright (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
|
||||
|
@ -37,11 +37,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.11"
|
||||
#define ZLIB_VERNUM 0x12b0
|
||||
#define ZLIB_VERSION "1.2.13"
|
||||
#define ZLIB_VERNUM 0x12d0
|
||||
#define ZLIB_VER_MAJOR 1
|
||||
#define ZLIB_VER_MINOR 2
|
||||
#define ZLIB_VER_REVISION 11
|
||||
#define ZLIB_VER_REVISION 13
|
||||
#define ZLIB_VER_SUBREVISION 0
|
||||
|
||||
/*
|
||||
|
@ -276,7 +276,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
|||
== 0), or after each call of deflate(). If deflate returns Z_OK and with
|
||||
zero avail_out, it must be called again after making room in the output
|
||||
buffer because there might be more output pending. See deflatePending(),
|
||||
which can be used if desired to determine whether or not there is more ouput
|
||||
which can be used if desired to determine whether or not there is more output
|
||||
in that case.
|
||||
|
||||
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
|
||||
|
@ -543,8 +543,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
|||
int strategy));
|
||||
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc, zfree and opaque must be initialized before by the
|
||||
caller.
|
||||
fields zalloc, zfree and opaque must be initialized before by the caller.
|
||||
|
||||
The method parameter is the compression method. It must be Z_DEFLATED in
|
||||
this version of the library.
|
||||
|
@ -661,7 +660,7 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
|
|||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If deflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
Similarly, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
deflateGetDictionary() may return a length less than the window size, even
|
||||
when more than the window size in input has been provided. It may return up
|
||||
|
@ -712,11 +711,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
|||
used to switch between compression and straight copy of the input data, or
|
||||
to switch to a different kind of input data requiring a different strategy.
|
||||
If the compression approach (which is a function of the level) or the
|
||||
strategy is changed, and if any input has been consumed in a previous
|
||||
deflate() call, then the input available so far is compressed with the old
|
||||
level and strategy using deflate(strm, Z_BLOCK). There are three approaches
|
||||
for the compression levels 0, 1..3, and 4..9 respectively. The new level
|
||||
and strategy will take effect at the next call of deflate().
|
||||
strategy is changed, and if there have been any deflate() calls since the
|
||||
state was initialized or reset, then the input available so far is
|
||||
compressed with the old level and strategy using deflate(strm, Z_BLOCK).
|
||||
There are three approaches for the compression levels 0, 1..3, and 4..9
|
||||
respectively. The new level and strategy will take effect at the next call
|
||||
of deflate().
|
||||
|
||||
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
|
||||
not have enough output space to complete, then the parameter change will not
|
||||
|
@ -865,9 +865,11 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
|||
detection, or add 16 to decode only the gzip format (the zlib format will
|
||||
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
|
||||
CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
|
||||
below), inflate() will not automatically decode concatenated gzip streams.
|
||||
inflate() will return Z_STREAM_END at the end of the gzip stream. The state
|
||||
would need to be reset to continue decoding a subsequent gzip stream.
|
||||
below), inflate() will *not* automatically decode concatenated gzip members.
|
||||
inflate() will return Z_STREAM_END at the end of the gzip member. The state
|
||||
would need to be reset to continue decoding a subsequent gzip member. This
|
||||
*must* be done if there is more data after a gzip member, in order for the
|
||||
decompression to be compliant with the gzip standard (RFC 1952).
|
||||
|
||||
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
|
||||
|
@ -913,7 +915,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
|
|||
to dictionary. dictionary must have enough space, where 32768 bytes is
|
||||
always enough. If inflateGetDictionary() is called with dictionary equal to
|
||||
Z_NULL, then only the dictionary length is returned, and nothing is copied.
|
||||
Similary, if dictLength is Z_NULL, then it is not set.
|
||||
Similarly, if dictLength is Z_NULL, then it is not set.
|
||||
|
||||
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
|
||||
stream state is inconsistent.
|
||||
|
@ -1302,14 +1304,14 @@ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
|
|||
/*
|
||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
|
||||
Opens a gzip (.gz) file for reading or writing. The mode parameter is as
|
||||
in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
|
||||
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
||||
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
||||
for fixed code compression as in "wb9F". (See the description of
|
||||
deflateInit2 for more information about the strategy parameter.) 'T' will
|
||||
request transparent writing or appending with no compression and not using
|
||||
the gzip format.
|
||||
Open the gzip (.gz) file at path for reading and decompressing, or
|
||||
compressing and writing. The mode parameter is as in fopen ("rb" or "wb")
|
||||
but can also include a compression level ("wb9") or a strategy: 'f' for
|
||||
filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h",
|
||||
'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression
|
||||
as in "wb9F". (See the description of deflateInit2 for more information
|
||||
about the strategy parameter.) 'T' will request transparent writing or
|
||||
appending with no compression and not using the gzip format.
|
||||
|
||||
"a" can be used instead of "w" to request that the gzip stream that will
|
||||
be written be appended to the file. "+" will result in an error, since
|
||||
|
@ -1339,9 +1341,9 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
|||
|
||||
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||
/*
|
||||
gzdopen associates a gzFile with the file descriptor fd. File descriptors
|
||||
are obtained from calls like open, dup, creat, pipe or fileno (if the file
|
||||
has been previously opened with fopen). The mode parameter is as in gzopen.
|
||||
Associate a gzFile with the file descriptor fd. File descriptors are
|
||||
obtained from calls like open, dup, creat, pipe or fileno (if the file has
|
||||
been previously opened with fopen). The mode parameter is as in gzopen.
|
||||
|
||||
The next call of gzclose on the returned gzFile will also close the file
|
||||
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
||||
|
@ -1362,13 +1364,13 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
|||
|
||||
ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
|
||||
/*
|
||||
Set the internal buffer size used by this library's functions. The
|
||||
default buffer size is 8192 bytes. This function must be called after
|
||||
gzopen() or gzdopen(), and before any other calls that read or write the
|
||||
file. The buffer memory allocation is always deferred to the first read or
|
||||
write. Three times that size in buffer space is allocated. A larger buffer
|
||||
size of, for example, 64K or 128K bytes will noticeably increase the speed
|
||||
of decompression (reading).
|
||||
Set the internal buffer size used by this library's functions for file to
|
||||
size. The default buffer size is 8192 bytes. This function must be called
|
||||
after gzopen() or gzdopen(), and before any other calls that read or write
|
||||
the file. The buffer memory allocation is always deferred to the first read
|
||||
or write. Three times that size in buffer space is allocated. A larger
|
||||
buffer size of, for example, 64K or 128K bytes will noticeably increase the
|
||||
speed of decompression (reading).
|
||||
|
||||
The new buffer size also affects the maximum length for gzprintf().
|
||||
|
||||
|
@ -1378,9 +1380,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
|
|||
|
||||
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||
/*
|
||||
Dynamically update the compression level or strategy. See the description
|
||||
of deflateInit2 for the meaning of these parameters. Previously provided
|
||||
data is flushed before the parameter change.
|
||||
Dynamically update the compression level and strategy for file. See the
|
||||
description of deflateInit2 for the meaning of these parameters. Previously
|
||||
provided data is flushed before applying the parameter changes.
|
||||
|
||||
gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
|
||||
opened for writing, Z_ERRNO if there is an error writing the flushed data,
|
||||
|
@ -1389,7 +1391,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
|||
|
||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||
/*
|
||||
Reads the given number of uncompressed bytes from the compressed file. If
|
||||
Read and decompress up to len uncompressed bytes from file into buf. If
|
||||
the input file is not in gzip format, gzread copies the given number of
|
||||
bytes into the buffer directly from the file.
|
||||
|
||||
|
@ -1420,11 +1422,11 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
|||
ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
|
||||
gzFile file));
|
||||
/*
|
||||
Read up to nitems items of size size from file to buf, otherwise operating
|
||||
as gzread() does. This duplicates the interface of stdio's fread(), with
|
||||
size_t request and return types. If the library defines size_t, then
|
||||
z_size_t is identical to size_t. If not, then z_size_t is an unsigned
|
||||
integer type that can contain a pointer.
|
||||
Read and decompress up to nitems items of size size from file into buf,
|
||||
otherwise operating as gzread() does. This duplicates the interface of
|
||||
stdio's fread(), with size_t request and return types. If the library
|
||||
defines size_t, then z_size_t is identical to size_t. If not, then z_size_t
|
||||
is an unsigned integer type that can contain a pointer.
|
||||
|
||||
gzfread() returns the number of full items read of size size, or zero if
|
||||
the end of the file was reached and a full item could not be read, or if
|
||||
|
@ -1435,26 +1437,24 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
|
|||
|
||||
In the event that the end of file is reached and only a partial item is
|
||||
available at the end, i.e. the remaining uncompressed data length is not a
|
||||
multiple of size, then the final partial item is nevetheless read into buf
|
||||
multiple of size, then the final partial item is nevertheless read into buf
|
||||
and the end-of-file flag is set. The length of the partial item read is not
|
||||
provided, but could be inferred from the result of gztell(). This behavior
|
||||
is the same as the behavior of fread() implementations in common libraries,
|
||||
but it prevents the direct use of gzfread() to read a concurrently written
|
||||
file, reseting and retrying on end-of-file, when size is not 1.
|
||||
file, resetting and retrying on end-of-file, when size is not 1.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||
voidpc buf, unsigned len));
|
||||
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
|
||||
/*
|
||||
Writes the given number of uncompressed bytes into the compressed file.
|
||||
gzwrite returns the number of uncompressed bytes written or 0 in case of
|
||||
error.
|
||||
Compress and write the len uncompressed bytes at buf to file. gzwrite
|
||||
returns the number of uncompressed bytes written or 0 in case of error.
|
||||
*/
|
||||
|
||||
ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
|
||||
z_size_t nitems, gzFile file));
|
||||
/*
|
||||
gzfwrite() writes nitems items of size size from buf to file, duplicating
|
||||
Compress and write nitems items of size size from buf to file, duplicating
|
||||
the interface of stdio's fwrite(), with size_t request and return types. If
|
||||
the library defines size_t, then z_size_t is identical to size_t. If not,
|
||||
then z_size_t is an unsigned integer type that can contain a pointer.
|
||||
|
@ -1467,22 +1467,22 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
|
|||
|
||||
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
|
||||
/*
|
||||
Converts, formats, and writes the arguments to the compressed file under
|
||||
control of the format string, as in fprintf. gzprintf returns the number of
|
||||
Convert, format, compress, and write the arguments (...) to file under
|
||||
control of the string format, as in fprintf. gzprintf returns the number of
|
||||
uncompressed bytes actually written, or a negative zlib error code in case
|
||||
of error. The number of uncompressed bytes written is limited to 8191, or
|
||||
one less than the buffer size given to gzbuffer(). The caller should assure
|
||||
that this limit is not exceeded. If it is exceeded, then gzprintf() will
|
||||
return an error (0) with nothing written. In this case, there may also be a
|
||||
buffer overflow with unpredictable consequences, which is possible only if
|
||||
zlib was compiled with the insecure functions sprintf() or vsprintf()
|
||||
zlib was compiled with the insecure functions sprintf() or vsprintf(),
|
||||
because the secure snprintf() or vsnprintf() functions were not available.
|
||||
This can be determined using zlibCompileFlags().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
|
||||
/*
|
||||
Writes the given null-terminated string to the compressed file, excluding
|
||||
Compress and write the given null-terminated string s to file, excluding
|
||||
the terminating null character.
|
||||
|
||||
gzputs returns the number of characters written, or -1 in case of error.
|
||||
|
@ -1490,11 +1490,12 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
|
|||
|
||||
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
|
||||
/*
|
||||
Reads bytes from the compressed file until len-1 characters are read, or a
|
||||
newline character is read and transferred to buf, or an end-of-file
|
||||
condition is encountered. If any characters are read or if len == 1, the
|
||||
string is terminated with a null character. If no characters are read due
|
||||
to an end-of-file or len < 1, then the buffer is left untouched.
|
||||
Read and decompress bytes from file into buf, until len-1 characters are
|
||||
read, or until a newline character is read and transferred to buf, or an
|
||||
end-of-file condition is encountered. If any characters are read or if len
|
||||
is one, the string is terminated with a null character. If no characters
|
||||
are read due to an end-of-file or len is less than one, then the buffer is
|
||||
left untouched.
|
||||
|
||||
gzgets returns buf which is a null-terminated string, or it returns NULL
|
||||
for end-of-file or in case of error. If there was an error, the contents at
|
||||
|
@ -1503,13 +1504,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
|
|||
|
||||
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||
/*
|
||||
Writes c, converted to an unsigned char, into the compressed file. gzputc
|
||||
Compress and write c, converted to an unsigned char, into file. gzputc
|
||||
returns the value that was written, or -1 in case of error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||
/*
|
||||
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
||||
Read and decompress one byte from file. gzgetc returns this byte or -1
|
||||
in case of end of file or error. This is implemented as a macro for speed.
|
||||
As such, it does not do all of the checking the other functions do. I.e.
|
||||
it does not check to see if file is NULL, nor whether the structure file
|
||||
|
@ -1518,8 +1519,8 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
|||
|
||||
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
||||
/*
|
||||
Push one character back onto the stream to be read as the first character
|
||||
on the next read. At least one character of push-back is allowed.
|
||||
Push c back onto the stream for file to be read as the first character on
|
||||
the next read. At least one character of push-back is always allowed.
|
||||
gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
|
||||
fail if c is -1, and may fail if a character has been pushed but not read
|
||||
yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
|
||||
|
@ -1530,9 +1531,9 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
|||
|
||||
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
|
||||
/*
|
||||
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). gzflush is only permitted when writing.
|
||||
Flush all pending output to file. The parameter flush is as in the
|
||||
deflate() function. The return value is the zlib error number (see function
|
||||
gzerror below). gzflush is only permitted when writing.
|
||||
|
||||
If the flush parameter is Z_FINISH, the remaining data is written and the
|
||||
gzip stream is completed in the output. If gzwrite() is called again, a new
|
||||
|
@ -1547,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
|
|||
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
|
||||
z_off_t offset, int whence));
|
||||
|
||||
Sets the starting position for the next gzread or gzwrite on the given
|
||||
compressed file. The offset represents a number of bytes in the
|
||||
Set the starting position to offset relative to whence for the next gzread
|
||||
or gzwrite on file. The offset represents a number of bytes in the
|
||||
uncompressed data stream. The whence parameter is defined as in lseek(2);
|
||||
the value SEEK_END is not supported.
|
||||
|
||||
|
@ -1565,18 +1566,18 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
|
|||
|
||||
ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
|
||||
/*
|
||||
Rewinds the given file. This function is supported only for reading.
|
||||
Rewind file. This function is supported only for reading.
|
||||
|
||||
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
|
||||
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET).
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
|
||||
|
||||
Returns the starting position for the next gzread or gzwrite on the given
|
||||
compressed file. This position represents a number of bytes in the
|
||||
uncompressed data stream, and is zero when starting, even if appending or
|
||||
reading a gzip stream from the middle of a file using gzdopen().
|
||||
Return the starting position for the next gzread or gzwrite on file.
|
||||
This position represents a number of bytes in the uncompressed data stream,
|
||||
and is zero when starting, even if appending or reading a gzip stream from
|
||||
the middle of a file using gzdopen().
|
||||
|
||||
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
|
||||
*/
|
||||
|
@ -1584,22 +1585,22 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
|
|||
/*
|
||||
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
|
||||
|
||||
Returns the current offset in the file being read or written. This offset
|
||||
includes the count of bytes that precede the gzip stream, for example when
|
||||
appending or when using gzdopen() for reading. When reading, the offset
|
||||
does not include as yet unused buffered input. This information can be used
|
||||
for a progress indicator. On error, gzoffset() returns -1.
|
||||
Return the current compressed (actual) read or write offset of file. This
|
||||
offset includes the count of bytes that precede the gzip stream, for example
|
||||
when appending or when using gzdopen() for reading. When reading, the
|
||||
offset does not include as yet unused buffered input. This information can
|
||||
be used for a progress indicator. On error, gzoffset() returns -1.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||
/*
|
||||
Returns true (1) if the end-of-file indicator has been set while reading,
|
||||
false (0) otherwise. Note that the end-of-file indicator is set only if the
|
||||
read tried to go past the end of the input, but came up short. Therefore,
|
||||
just like feof(), gzeof() may return false even if there is no more data to
|
||||
read, in the event that the last read request was for the exact number of
|
||||
bytes remaining in the input file. This will happen if the input file size
|
||||
is an exact multiple of the buffer size.
|
||||
Return true (1) if the end-of-file indicator for file has been set while
|
||||
reading, false (0) otherwise. Note that the end-of-file indicator is set
|
||||
only if the read tried to go past the end of the input, but came up short.
|
||||
Therefore, just like feof(), gzeof() may return false even if there is no
|
||||
more data to read, in the event that the last read request was for the exact
|
||||
number of bytes remaining in the input file. This will happen if the input
|
||||
file size is an exact multiple of the buffer size.
|
||||
|
||||
If gzeof() returns true, then the read functions will return no more data,
|
||||
unless the end-of-file indicator is reset by gzclearerr() and the input file
|
||||
|
@ -1608,7 +1609,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
|||
|
||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||
/*
|
||||
Returns true (1) if file is being copied directly while reading, or false
|
||||
Return true (1) if file is being copied directly while reading, or false
|
||||
(0) if file is a gzip stream being decompressed.
|
||||
|
||||
If the input file is empty, gzdirect() will return true, since the input
|
||||
|
@ -1629,8 +1630,8 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
|||
|
||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
/*
|
||||
Flushes all pending output if necessary, closes the compressed file and
|
||||
deallocates the (de)compression state. Note that once file is closed, you
|
||||
Flush all pending output for file, if necessary, close file and
|
||||
deallocate the (de)compression state. Note that once file is closed, you
|
||||
cannot call gzerror with file, since its structures have been deallocated.
|
||||
gzclose must not be called more than once on the same file, just as free
|
||||
must not be called more than once on the same allocation.
|
||||
|
@ -1654,10 +1655,10 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
|
|||
|
||||
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
|
||||
/*
|
||||
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.
|
||||
Return the error message for the last error which occurred on 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.
|
||||
|
||||
The application must not modify the returned string. Future calls to
|
||||
this function may invalidate the previously returned string. If file is
|
||||
|
@ -1670,7 +1671,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
|
|||
|
||||
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||
/*
|
||||
Clears the error and end-of-file flags for file. This is analogous to the
|
||||
Clear the error and end-of-file flags for file. This is analogous to the
|
||||
clearerr() function in stdio. This is useful for continuing to read a gzip
|
||||
file that is being written concurrently.
|
||||
*/
|
||||
|
@ -1688,8 +1689,9 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
|||
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
return the updated checksum. If buf is Z_NULL, this function returns the
|
||||
required initial value for the checksum.
|
||||
return the updated checksum. An Adler-32 value is in the range of a 32-bit
|
||||
unsigned integer. If buf is Z_NULL, this function returns the required
|
||||
initial value for the checksum.
|
||||
|
||||
An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
|
||||
much faster.
|
||||
|
@ -1722,12 +1724,13 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
|||
negative, the result has no meaning or utility.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||
updated CRC-32. If buf is Z_NULL, this function returns the required
|
||||
initial value for the crc. Pre- and post-conditioning (one's complement) is
|
||||
performed within this function so it shouldn't be done by the application.
|
||||
updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer.
|
||||
If buf is Z_NULL, this function returns the required initial value for the
|
||||
crc. Pre- and post-conditioning (one's complement) is performed within this
|
||||
function so it shouldn't be done by the application.
|
||||
|
||||
Usage example:
|
||||
|
||||
|
@ -1739,7 +1742,7 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
|||
if (crc != original_crc) error();
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
|
||||
ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
|
||||
z_size_t len));
|
||||
/*
|
||||
Same as crc32(), but with a size_t length.
|
||||
|
@ -1755,6 +1758,20 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
|
|||
len2.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
|
||||
|
||||
Return the operator corresponding to length len2, to be used with
|
||||
crc32_combine_op().
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
|
||||
/*
|
||||
Give the same result as crc32_combine(), using op in place of len2. op is
|
||||
is generated from len2 by crc32_combine_gen(). This will be faster than
|
||||
crc32_combine() if the generated op is used more than once.
|
||||
*/
|
||||
|
||||
|
||||
/* various hacks, don't look :) */
|
||||
|
||||
|
@ -1842,6 +1859,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
|||
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
|
||||
#endif
|
||||
|
||||
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
|
||||
|
@ -1852,6 +1870,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
|||
# define z_gzoffset z_gzoffset64
|
||||
# define z_adler32_combine z_adler32_combine64
|
||||
# define z_crc32_combine z_crc32_combine64
|
||||
# define z_crc32_combine_gen z_crc32_combine_gen64
|
||||
# else
|
||||
# define gzopen gzopen64
|
||||
# define gzseek gzseek64
|
||||
|
@ -1859,6 +1878,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
|||
# define gzoffset gzoffset64
|
||||
# define adler32_combine adler32_combine64
|
||||
# define crc32_combine crc32_combine64
|
||||
# define crc32_combine_gen crc32_combine_gen64
|
||||
# endif
|
||||
# ifndef Z_LARGE64
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
|
@ -1867,6 +1887,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
|||
ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
|
||||
# endif
|
||||
#else
|
||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
|
||||
|
@ -1875,12 +1896,14 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
|||
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
|
||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
|
||||
#endif
|
||||
|
||||
#else /* Z_SOLO */
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
|
||||
|
||||
#endif /* !Z_SOLO */
|
||||
|
||||
|
@ -1890,10 +1913,10 @@ ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
|||
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||
ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
|
||||
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
|
||||
ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
|
||||
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
|
||||
const char *mode));
|
||||
#endif
|
||||
|
|
|
@ -92,3 +92,9 @@ ZLIB_1.2.9 {
|
|||
adler32_z;
|
||||
crc32_z;
|
||||
} ZLIB_1.2.7.1;
|
||||
|
||||
ZLIB_1.2.12 {
|
||||
crc32_combine_gen;
|
||||
crc32_combine_gen64;
|
||||
crc32_combine_op;
|
||||
} ZLIB_1.2.9;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
# TODO
|
||||
#
|
||||
# Asumes no function pointer parameters. unless they are typedefed.
|
||||
# Assumes no function pointer parameters. unless they are typedefed.
|
||||
# Assumes no literal strings that look like function definitions
|
||||
# Assumes functions start at the beginning of a line
|
||||
|
||||
|
@ -104,7 +104,7 @@ sub StripComments
|
|||
|
||||
no warnings;
|
||||
|
||||
# Strip C & C++ coments
|
||||
# Strip C & C++ comments
|
||||
# From the perlfaq
|
||||
$_[0] =~
|
||||
|
||||
|
|
20
zlib/zutil.c
20
zlib/zutil.c
|
@ -61,9 +61,11 @@ uLong ZEXPORT zlibCompileFlags()
|
|||
#ifdef ZLIB_DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
/*
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
*/
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
|
@ -119,7 +121,7 @@ uLong ZEXPORT zlibCompileFlags()
|
|||
# endif
|
||||
int ZLIB_INTERNAL z_verbose = verbose;
|
||||
|
||||
void ZLIB_INTERNAL z_error (m)
|
||||
void ZLIB_INTERNAL z_error(m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
|
@ -136,8 +138,8 @@ const char * ZEXPORT zError(err)
|
|||
return ERR_MSG(err);
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
|
||||
/* The older Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used.
|
||||
*/
|
||||
|
@ -214,7 +216,7 @@ local ptr_table table[MAX_PTR];
|
|||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf;
|
||||
ulg bsize = (ulg)items*size;
|
||||
|
@ -240,7 +242,7 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
|||
return buf;
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -277,13 +279,13 @@ void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
|||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
(void)opaque;
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
(void)opaque;
|
||||
_hfree(ptr);
|
||||
|
@ -302,7 +304,7 @@ extern voidp calloc OF((uInt items, uInt size));
|
|||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||
voidpf ZLIB_INTERNAL zcalloc(opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
|
@ -312,7 +314,7 @@ voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
|||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||
void ZLIB_INTERNAL zcfree(opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
|
|
22
zlib/zutil.h
22
zlib/zutil.h
|
@ -1,5 +1,5 @@
|
|||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
|
||||
* Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -29,10 +29,6 @@
|
|||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
|
@ -46,6 +42,17 @@ typedef unsigned short ush;
|
|||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC)
|
||||
# include <limits.h>
|
||||
# if (ULONG_MAX == 0xffffffffffffffff)
|
||||
# define Z_U8 unsigned long
|
||||
# elif (ULLONG_MAX == 0xffffffffffffffff)
|
||||
# define Z_U8 unsigned long long
|
||||
# elif (UINT_MAX == 0xffffffffffffffff)
|
||||
# define Z_U8 unsigned
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
|
@ -170,10 +177,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
|
@ -190,6 +193,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
|||
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
|
Loading…
Reference in a new issue