Import zlib 1.2.1 (trimmed)

This commit is contained in:
tjr 2004-06-30 23:43:39 +00:00
parent 0288c7557e
commit 439ed8d847
29 changed files with 5625 additions and 2200 deletions

View File

@ -1,5 +1,246 @@
ChangeLog file for zlib ChangeLog file for zlib
Changes in 1.2.1 (17 November 2003)
- Remove a tab in contrib/gzappend/gzappend.c
- Update some interfaces in contrib for new zlib functions
- Update zlib version number in some contrib entries
- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
- Support shared libraries on Hurd and KFreeBSD [Brown]
- Fix error in NO_DIVIDE option of adler32.c
Changes in 1.2.0.8 (4 November 2003)
- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
- Add experimental NO_DIVIDE #define in adler32.c
- Possibly faster on some processors (let me know if it is)
- Correct Z_BLOCK to not return on first inflate call if no wrap
- Fix strm->data_type on inflate() return to correctly indicate EOB
- Add deflatePrime() function for appending in the middle of a byte
- Add contrib/gzappend for an example of appending to a stream
- Update win32/DLL_FAQ.txt [Truta]
- Delete Turbo C comment in README [Truta]
- Improve some indentation in zconf.h [Truta]
- Fix infinite loop on bad input in configure script [Church]
- Fix gzeof() for concatenated gzip files [Johnson]
- Add example to contrib/visual-basic.txt [Michael B.]
- Add -p to mkdir's in Makefile.in [vda]
- Fix configure to properly detect presence or lack of printf functions
- Add AS400 support [Monnerat]
- Add a little Cygwin support [Wilson]
Changes in 1.2.0.7 (21 September 2003)
- Correct some debug formats in contrib/infback9
- Cast a type in a debug statement in trees.c
- Change search and replace delimiter in configure from % to # [Beebe]
- Update contrib/untgz to 0.2 with various fixes [Truta]
- Add build support for Amiga [Nikl]
- Remove some directories in old that have been updated to 1.2
- Add dylib building for Mac OS X in configure and Makefile.in
- Remove old distribution stuff from Makefile
- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
- Update links in README
Changes in 1.2.0.6 (13 September 2003)
- Minor FAQ updates
- Update contrib/minizip to 1.00 [Vollant]
- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
- Update POSTINC comment for 68060 [Nikl]
- Add contrib/infback9 with deflate64 decoding (unsupported)
- For MVS define NO_vsnprintf and undefine FAR [van Burik]
- Add pragma for fdopen on MVS [van Burik]
Changes in 1.2.0.5 (8 September 2003)
- Add OF to inflateBackEnd() declaration in zlib.h
- Remember start when using gzdopen in the middle of a file
- Use internal off_t counters in gz* functions to properly handle seeks
- Perform more rigorous check for distance-too-far in inffast.c
- Add Z_BLOCK flush option to return from inflate at block boundary
- Set strm->data_type on return from inflate
- Indicate bits unused, if at block boundary, and if in last block
- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
- Add condition so old NO_DEFLATE define still works for compatibility
- FAQ update regarding the Windows DLL [Truta]
- INDEX update: add qnx entry, remove aix entry [Truta]
- Install zlib.3 into mandir [Wilson]
- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
- Adapt the zlib interface to the new DLL convention guidelines [Truta]
- Introduce ZLIB_WINAPI macro to allow the export of functions using
the WINAPI calling convention, for Visual Basic [Vollant, Truta]
- Update msdos and win32 scripts and makefiles [Truta]
- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
- Add contrib/ada [Anisimkov]
- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
- Add contrib/masm686 [Truta]
- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
[Truta, Vollant]
- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
- Remove contrib/delphi2; add a new contrib/delphi [Truta]
- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
and fix some method prototypes [Truta]
- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
[Truta]
- Avoid the use of backslash (\) in contrib/minizip [Vollant]
- Fix file time handling in contrib/untgz; update makefiles [Truta]
- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
[Vollant]
- Remove contrib/vstudio/vc15_16 [Vollant]
- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
- Update README.contrib [Truta]
- Invert the assignment order of match_head and s->prev[...] in
INSERT_STRING [Truta]
- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
[Truta]
- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
- Fix prototype of syncsearch in inflate.c [Truta]
- Introduce ASMINF macro to be enabled when using an ASM implementation
of inflate_fast [Truta]
- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
- Modify test_gzio in example.c to take a single file name as a
parameter [Truta]
- Exit the example.c program if gzopen fails [Truta]
- Add type casts around strlen in example.c [Truta]
- Remove casting to sizeof in minigzip.c; give a proper type
to the variable compared with SUFFIX_LEN [Truta]
- Update definitions of STDC and STDC99 in zconf.h [Truta]
- Synchronize zconf.h with the new Windows DLL interface [Truta]
- Use SYS16BIT instead of __32BIT__ to distinguish between
16- and 32-bit platforms [Truta]
- Use far memory allocators in small 16-bit memory models for
Turbo C [Truta]
- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
zlibCompileFlags [Truta]
- Cygwin has vsnprintf [Wilson]
- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
Changes in 1.2.0.4 (10 August 2003)
- Minor FAQ updates
- Be more strict when checking inflateInit2's windowBits parameter
- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
- Add gzip wrapper option to deflateInit2 using windowBits
- Add updated QNX rule in configure and qnx directory [Bonnefoy]
- Make inflate distance-too-far checks more rigorous
- Clean up FAR usage in inflate
- Add casting to sizeof() in gzio.c and minigzip.c
Changes in 1.2.0.3 (19 July 2003)
- Fix silly error in gzungetc() implementation [Vollant]
- Update contrib/minizip and contrib/vstudio [Vollant]
- Fix printf format in example.c
- Correct cdecl support in zconf.in.h [Anisimkov]
- Minor FAQ updates
Changes in 1.2.0.2 (13 July 2003)
- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
- Attempt to avoid warnings in crc32.c for pointer-int conversion
- Add AIX to configure, remove aix directory [Bakker]
- Add some casts to minigzip.c
- Improve checking after insecure sprintf() or vsprintf() calls
- Remove #elif's from crc32.c
- Change leave label to inf_leave in inflate.c and infback.c to avoid
library conflicts
- Remove inflate gzip decoding by default--only enable gzip decoding by
special request for stricter backward compatibility
- Add zlibCompileFlags() function to return compilation information
- More typecasting in deflate.c to avoid warnings
- Remove leading underscore from _Capital #defines [Truta]
- Fix configure to link shared library when testing
- Add some Windows CE target adjustments [Mai]
- Remove #define ZLIB_DLL in zconf.h [Vollant]
- Add zlib.3 [Rodgers]
- Update RFC URL in deflate.c and algorithm.txt [Mai]
- Add zlib_dll_FAQ.txt to contrib [Truta]
- Add UL to some constants [Truta]
- Update minizip and vstudio [Vollant]
- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
- Expand use of NO_DUMMY_DECL to avoid all dummy structures
- Added iostream3 to contrib [Schwardt]
- Replace rewind() with fseek() for WinCE [Truta]
- Improve setting of zlib format compression level flags
- Report 0 for huffman and rle strategies and for level == 0 or 1
- Report 2 only for level == 6
- Only deal with 64K limit when necessary at compile time [Truta]
- Allow TOO_FAR check to be turned off at compile time [Truta]
- Add gzclearerr() function [Souza]
- Add gzungetc() function
Changes in 1.2.0.1 (17 March 2003)
- Add Z_RLE strategy for run-length encoding [Truta]
- When Z_RLE requested, restrict matches to distance one
- Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
- Correct FASTEST compilation to allow level == 0
- Clean up what gets compiled for FASTEST
- Incorporate changes to zconf.in.h [Vollant]
- Refine detection of Turbo C need for dummy returns
- Refine ZLIB_DLL compilation
- Include additional header file on VMS for off_t typedef
- Try to use _vsnprintf where it supplants vsprintf [Vollant]
- Add some casts in inffast.c
- Enchance comments in zlib.h on what happens if gzprintf() tries to
write more than 4095 bytes before compression
- Remove unused state from inflateBackEnd()
- Remove exit(0) from minigzip.c, example.c
- Get rid of all those darn tabs
- Add "check" target to Makefile.in that does the same thing as "test"
- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
- Update contrib/inflate86 [Anderson]
- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
- Add msdos and win32 directories with makefiles [Truta]
- More additions and improvements to the FAQ
Changes in 1.2.0 (9 March 2003)
- New and improved inflate code
- About 20% faster
- Does not allocate 32K window unless and until needed
- Automatically detects and decompresses gzip streams
- Raw inflate no longer needs an extra dummy byte at end
- Added inflateBack functions using a callback interface--even faster
than inflate, useful for file utilities (gzip, zip)
- Added inflateCopy() function to record state for random access on
externally generated deflate streams (e.g. in gzip files)
- More readable code (I hope)
- New and improved crc32()
- About 50% faster, thanks to suggestions from Rodney Brown
- Add deflateBound() and compressBound() functions
- Fix memory leak in deflateInit2()
- Permit setting dictionary for raw deflate (for parallel deflate)
- Fix const declaration for gzwrite()
- Check for some malloc() failures in gzio.c
- Fix bug in gzopen() on single-byte file 0x1f
- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
and next buffer doesn't start with 0x8b
- Fix uncompress() to return Z_DATA_ERROR on truncated input
- Free memory at end of example.c
- Remove MAX #define in trees.c (conflicted with some libraries)
- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
- Declare malloc() and free() in gzio.c if STDC not defined
- Use malloc() instead of calloc() in zutil.c if int big enough
- Define STDC for AIX
- Add aix/ with approach for compiling shared library on AIX
- Add HP-UX support for shared libraries in configure
- Add OpenUNIX support for shared libraries in configure
- Use $cc instead of gcc to build shared library
- Make prefix directory if needed when installing
- Correct Macintosh avoidance of typedef Byte in zconf.h
- Correct Turbo C memory allocation when under Linux
- Use libz.a instead of -lz in Makefile (assure use of compiled library)
- Update configure to check for snprintf or vsnprintf functions and their
return value, warn during make if using an insecure function
- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
is lost when library is used--resolution is to build new zconf.h
- Documentation improvements (in zlib.h):
- Document raw deflate and inflate
- Update RFCs URL
- Point out that zlib and gzip formats are different
- Note that Z_BUF_ERROR is not fatal
- Document string limit for gzprintf() and possible buffer overflow
- Note requirement on avail_out when flushing
- Note permitted values of flush parameter of inflate()
- Add some FAQs (and even answers) to the FAQ
- Add contrib/inflate86/ for x86 faster inflate
- Add contrib/blast/ for PKWare Data Compression Library decompression
- Add contrib/puff/ simple inflate for deflate format description
Changes in 1.1.4 (11 March 2002) 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.
@ -10,7 +251,7 @@ Changes in 1.1.4 (11 March 2002)
less than 32K. less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size - 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) Changes in 1.1.3 (9 July 1998)
- fix "an inflate input buffer bug that shows up on rare but persistent - fix "an inflate input buffer bug that shows up on rare but persistent
occasions" (Mark) occasions" (Mark)
@ -184,13 +425,13 @@ Changes in 1.0.6 (19 Jan 1998)
- added Makefile.nt (thanks to Stephen Williams) - added Makefile.nt (thanks to Stephen Williams)
- added the unsupported "contrib" directory: - added the unsupported "contrib" directory:
contrib/asm386/ by Gilles Vollant <info@winimage.com> 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> contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
A C++ I/O streams interface to the zlib gz* functions A C++ I/O streams interface to the zlib gz* functions
contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no> contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
Another C++ I/O streams interface Another C++ I/O streams interface
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es> contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
A very simple tar.gz file extractor using zlib A very simple tar.gz file extractor using zlib
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl> 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 - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
@ -217,7 +458,7 @@ Changes in 1.0.6 (19 Jan 1998)
- add NEED_DUMMY_RETURN for Borland - 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 - allow compilation with CC
- defined STDC for OS/2 (David Charlap) - defined STDC for OS/2 (David Charlap)
- limit external names to 8 chars for MVS (Thomas Lund) - limit external names to 8 chars for MVS (Thomas Lund)
- in minigzip.c, use static buffers only for 16-bit systems - in minigzip.c, use static buffers only for 16-bit systems
- fix suffix check for "minigzip -d foo.gz" - fix suffix check for "minigzip -d foo.gz"
@ -242,7 +483,7 @@ Changes in 1.0.5 (3 Jan 98)
- Eliminate memory leaks on error conditions in inflate - Eliminate memory leaks on error conditions in inflate
- Removed some vestigial code in inflate - Removed some vestigial code in inflate
- Update web address in README - Update web address in README
Changes in 1.0.4 (24 Jul 96) Changes in 1.0.4 (24 Jul 96)
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - 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 bit, so the decompressor could decompress all the correct data but went

View File

@ -1,8 +1,8 @@
Frequently Asked Questions about zlib Frequently Asked Questions about zlib
If your question is not there, please check the zlib home page If your question is not there, please check the zlib home page
http://www.zlib.org which may have more recent information. http://www.zlib.org which may have more recent information.
The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
@ -13,14 +13,15 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
2. Where can I get a Windows DLL version? 2. Where can I get a Windows DLL version?
The zlib sources can be compiled without change to produce a DLL. If you The zlib sources can be compiled without change to produce a DLL.
want a precompiled DLL, see http://www.winimage.com/zLibDll/ . Questions See the file win32/DLL_FAQ.txt in the zlib distribution.
about the zlib DLL should be sent to Gilles Vollant (info@winimage.com). Pointers to the precompiled DLL are found in the zlib web site at
http://www.zlib.org.
3. Where can I get a Visual Basic interface to zlib? 3. Where can I get a Visual Basic interface to zlib?
See See
* http://www.winimage.com/zLibDll/cmp-z-it.zip * http://www.winimage.com/zLibDll/
* http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
* contrib/visual-basic.txt in the zlib distribution * contrib/visual-basic.txt in the zlib distribution
@ -36,6 +37,11 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Before making the call, make sure that avail_in and avail_out are not Before making the call, make sure that avail_in and avail_out are not
zero. When setting the parameter flush equal to Z_FINISH, also make sure zero. When setting the parameter flush equal to Z_FINISH, also make sure
that avail_out is big enough to allow processing all pending input. that avail_out is big enough to allow processing all pending input.
Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
inflate() can be made with more input or output space. A Z_BUF_ERROR
may in fact be unavoidable depending on how the functions are used, since
it is not possible to tell whether or not there is more output pending
when strm.avail_out returns with zero.
6. Where's the zlib documentation (man pages, etc.)? 6. Where's the zlib documentation (man pages, etc.)?
@ -61,14 +67,13 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
If "make test" produces something like If "make test" produces something like
example.o(.text+0x154): undefined reference to `gzputc' example.o(.text+0x154): undefined reference to `gzputc'
check that you don't have old files libz.* in /usr/lib, /usr/local/lib or check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
/usr/X11R6/lib. Remove any old versions, then do "make install". /usr/X11R6/lib. Remove any old versions, then do "make install".
10. I need a Delphi interface to zlib. 10. I need a Delphi interface to zlib.
See the directories contrib/delphi and contrib/delphi2 in the zlib See the contrib/delphi directory in the zlib distribution.
distribution.
11. Can zlib handle .zip archives? 11. Can zlib handle .zip archives?
@ -85,16 +90,226 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
./configure -s ./configure -s
make make
14. Why does "make test" fail on Mac OS X? 14. How do I install a shared zlib library on Unix?
Mac OS X already includes zlib as a shared library, and so -lz links the make install
shared library instead of the one that the "make" compiled. For zlib
1.1.3, the two are incompatible due to different compile-time However, many flavors of Unix come with a shared zlib already installed.
options. Simply change the -lz in the Makefile to libz.a, and it will use Before going to the trouble of compiling a shared version of zlib and
the compiled library instead of the shared one and the "make test" will trying to install it, you may want to check if it's already there! If you
succeed. can #include <zlib.h>, it's there. The -lz option will probably link to it.
15. I have a question about OttoPDF 15. I have a question about OttoPDF
We are not the authors of OttoPDF. The real author is on the OttoPDF web We are not the authors of OttoPDF. The real author is on the OttoPDF web
site Joel Hainley jhainley@myndkryme.com. site Joel Hainley jhainley@myndkryme.com.
16. Why does gzip give an error on a file I make with compress/deflate?
The compress and deflate functions produce data in the zlib format, which
is different and incompatible with the gzip format. The gz* functions in
zlib on the other hand use the gzip format. Both the zlib and gzip
formats use the same compressed data format internally, but have different
headers and trailers around the compressed data.
17. Ok, so why are there two different formats?
The gzip format was designed to retain the directory information about
a single file, such as the name and last modification date. The zlib
format on the other hand was designed for in-memory and communication
channel applications, and has a much more compact header and trailer and
uses a faster integrity check than gzip.
18. Well that's nice, but how do I make a gzip file in memory?
You can request that deflate write the gzip format instead of the zlib
format using deflateInit2(). You can also request that inflate decode
the gzip format using inflateInit2(). Read zlib.h for more details.
Note that you cannot specify special gzip header contents (e.g. a file
name or modification date), nor will inflate tell you what was in the
gzip header. If you need to customize the header or see what's in it,
you can use the raw deflate and inflate operations and the crc32()
function and roll your own gzip encoding and decoding. Read the gzip
RFC 1952 for details of the header and trailer format.
19. Is zlib thread-safe?
Yes. However any library routines that zlib uses and any application-
provided memory allocation routines must also be thread-safe. zlib's gz*
functions use stdio library routines, and most of zlib's functions use the
library memory allocation routines by default. zlib's Init functions allow
for the application to provide custom memory allocation routines.
Of course, you should only operate on any given zlib or gzip stream from a
single thread at a time.
20. Can I use zlib in my commercial application?
Yes. Please read the license in zlib.h.
21. Is zlib under the GNU license?
No. Please read the license in zlib.h.
22. The license says that altered source versions must be "plainly marked". So
what exactly do I need to do to meet that requirement?
You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
particular, the final version number needs to be changed to "f", and an
identification string should be appended to ZLIB_VERSION. Version numbers
x.x.x.f are reserved for modifications to zlib by others than the zlib
maintainers. For example, if the version of the base zlib you are altering
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
update the version strings in deflate.c and inftrees.c.
For altered source distributions, you should also note the origin and
nature of the changes in zlib.h, as well as in ChangeLog and README, along
with the dates of the alterations. The origin should include at least your
name (or your company's name), and an email address to contact for help or
issues with the library.
Note that distributing a compiled zlib library along with zlib.h and
zconf.h is also a source distribution, and so you should change
ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
in zlib.h as you would for a full source distribution.
23. Will zlib work on a big-endian or little-endian architecture, and can I
exchange compressed data between them?
Yes and yes.
24. Will zlib work on a 64-bit machine?
It should. It has been tested on 64-bit machines, and has no dependence
on any data types being limited to 32-bits in length. If you have any
difficulties, please provide a complete problem report to zlib@gzip.org
25. Will zlib decompress data from the PKWare Data Compression Library?
No. The PKWare DCL uses a completely different compressed data format
than does PKZIP and zlib. However, you can look in zlib's contrib/blast
directory for a possible solution to your problem.
26. Can I access data randomly in a compressed stream?
No, not without some preparation. If when compressing you periodically
use Z_FULL_FLUSH, carefully write all the pending data at those points,
and keep an index of those locations, then you can start decompression
at those points. You have to be careful to not use Z_FULL_FLUSH too
often, since it can significantly degrade compression.
27. Does zlib work on MVS, OS/390, CICS, etc.?
We don't know for sure. We have heard occasional reports of success on
these systems. If you do use it on one of these, please provide us with
a report, instructions, and patches that we can reference when we get
these questions. Thanks.
28. Is there some simpler, easier to read version of inflate I can look at
to understand the deflate format?
First off, you should read RFC 1951. Second, yes. Look in zlib's
contrib/puff directory.
29. Does zlib infringe on any patents?
As far as we know, no. In fact, that was originally the whole point behind
zlib. Look here for some more information:
http://www.gzip.org/#faq11
30. Can zlib work with greater than 4 GB of data?
Yes. inflate() and deflate() will process any amount of data correctly.
Each call of inflate() or deflate() is limited to input and output chunks
of the maximum value that can be stored in the compiler's "unsigned int"
type, but there is no limit to the number of chunks. Note however that the
strm.total_in and strm_total_out counters may be limited to 4 GB. These
counters are provided as a convenience and are not used internally by
inflate() or deflate(). The application can easily set up its own counters
updated after each call of inflate() or deflate() to count beyond 4 GB.
compress() and uncompress() may be limited to 4 GB, since they operate in a
single call. gzseek() and gztell() may be limited to 4 GB depending on how
zlib is compiled. See the zlibCompileFlags() function in zlib.h.
The word "may" appears several times above since there is a 4 GB limit
only if the compiler's "long" type is 32 bits. If the compiler's "long"
type is 64 bits, then the limit is 16 exabytes.
31. Does zlib have any security vulnerabilities?
The only one that we are aware of is potentially in gzprintf(). If zlib
is compiled to use sprintf() or vsprintf(), then there is no protection
against a buffer overflow of a 4K string space, other than the caller of
gzprintf() assuring that the output will not exceed 4K. On the other
hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
normally be the case, then there is no vulnerability. The ./configure
script will display warnings if an insecure variation of sprintf() will
be used by gzprintf(). Also the zlibCompileFlags() function will return
information on what variant of sprintf() is used by gzprintf().
If you don't have snprintf() or vsnprintf() and would like one, you can
find a portable implementation here:
http://www.ijs.si/software/snprintf/
Note that you should be using the most recent version of zlib. Versions
1.1.3 and before were subject to a double-free vulnerability.
32. Is there a Java version of zlib?
Probably what you want is to use zlib in Java. zlib is already included
as part of the Java SDK in the java.util.zip package. If you really want
a version of zlib written in the Java language, look on the zlib home
page for links: http://www.zlib.org/
33. I get this or that compiler or source-code scanner warning when I crank it
up to maximally-pendantic. Can't you guys write proper code?
Many years ago, we gave up attempting to avoid warnings on every compiler
in the universe. It just got to be a waste of time, and some compilers
were downright silly. So now, we simply make sure that the code always
works.
34. Will zlib read the (insert any ancient or arcane format here) compressed
data format?
Probably not. Look in the comp.compression FAQ for pointers to various
formats and associated software.
35. How can I encrypt/decrypt zip files with zlib?
zlib doesn't support encryption. The original PKZIP encryption is very weak
and can be broken with freely available programs. To get strong encryption,
use gpg ( http://www.gnupg.org/ ) which already includes zlib compression.
For PKZIP compatible "encryption", look at http://www.info-zip.org/
36. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
"gzip" is the gzip format, and "deflate" is the zlib format. They should
probably have called the second one "zlib" instead to avoid confusion
with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
correctly points to the zlib specification in RFC 1950 for the "deflate"
transfer encoding, there have been reports of servers and browsers that
incorrectly produce or expect raw deflate data per the deflate
specficiation in RFC 1951, most notably Microsoft. So even though the
"deflate" transfer encoding using the zlib format would be the more
efficient approach (and in fact exactly what the zlib format was designed
for), using the "gzip" transfer encoding is probably more reliable due to
an unfortunate choice of name on the part of the HTTP 1.1 authors.
Bottom line: use the gzip format for HTTP 1.1 encoding.
37. Does zlib support the new "Deflate64" format introduced by PKWare?
No. PKWare has apparently decided to keep that format proprietary, since
they have not documented it as they have previous compression formats.
In any case, the compression improvements are so modest compared to other
more modern approaches, that it's not worth the effort to implement.
38. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product?
No. Go away. Shoo.

View File

@ -1,86 +1,48 @@
ChangeLog history of changes ChangeLog history of changes
INDEX this file FAQ Frequently Asked Questions about zlib
FAQ Frequently Asked Questions about zlib INDEX this file
Make_vms.com script for Vax/VMS Makefile makefile for Unix (generated by configure)
Makefile makefile for Unix (generated by configure) Makefile.in makefile for Unix (template for configure)
Makefile.in makefile for Unix (template for configure) README guess what
Makefile.riscos makefile for RISCOS algorithm.txt description of the (de)compression algorithm
README guess what configure configure script for Unix
algorithm.txt description of the (de)compression algorithm zconf.in.h template for zconf.h (used by configure)
configure configure script for Unix
descrip.mms makefile for Vax/VMS
zlib.3 mini man page for zlib (volunteers to write full
man pages from zlib.h welcome. write to jloup@gzip.org)
amiga/Makefile.sas makefile for Amiga SAS/C msdos/ makefiles for MSDOS
amiga/Makefile.pup makefile for Amiga powerUP SAS/C PPC old/ makefiles for various architectures and zlib documentation
files that have not yet been updated for zlib 1.2.x
qnx/ makefiles for QNX
win32/ makefiles for Windows
msdos/Makefile.w32 makefile for Microsoft Visual C++ 32-bit zlib public header files (must be kept):
msdos/Makefile.b32 makefile for Borland C++ 32-bit
msdos/Makefile.bor makefile for Borland C/C++ 16-bit
msdos/Makefile.dj2 makefile for DJGPP 2.x
msdos/Makefile.emx makefile for EMX 0.9c (32-bit DOS/OS2)
msdos/Makefile.msc makefile for Microsoft C 16-bit
msdos/Makefile.tc makefile for Turbo C
msdos/Makefile.wat makefile for Watcom C
msdos/zlib.def definition file for Windows DLL
msdos/zlib.rc definition file for Windows DLL
nt/Makefile.nt makefile for Windows NT
nt/zlib.dnt definition file for Windows NT DLL
nt/Makefile.emx makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel)
nt/Makefile.gcc makefile for Windows NT using GCC (mingw32)
zlib public header files (must be kept):
zconf.h zconf.h
zlib.h zlib.h
private source files used to build the zlib library: private source files used to build the zlib library:
adler32.c adler32.c
compress.c compress.c
crc32.c crc32.c
crc32.h
deflate.c deflate.c
deflate.h deflate.h
gzio.c gzio.c
infblock.c infback.c
infblock.h
infcodes.c
infcodes.h
inffast.c inffast.c
inffast.h inffast.h
inffixed.h
inflate.c inflate.c
inflate.h
inftrees.c inftrees.c
inftrees.h inftrees.h
infutil.c
infutil.h
maketree.c
trees.c trees.c
trees.h
uncompr.c uncompr.c
zutil.c zutil.c
zutil.h zutil.h
source files for sample programs: source files for sample programs:
example.c example.c
minigzip.c minigzip.c
unsupported contribution by third parties unsupported contribution by third parties
See contrib/README.contrib
contrib/asm386/ by Gilles Vollant <info@winimage.com>
386 asm code replacing longest_match().
contrib/minizip/ by Gilles Vollant <info@winimage.com>
Mini zip and unzip based on zlib
See http://www.winimage.com/zLibDll/unzip.html
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>
Another C++ I/O streams interface
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
A very simple tar.gz 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.

View File

@ -1,110 +1,87 @@
zlib 1.1.4 is a general purpose data compression library. All the code ZLIB DATA COMPRESSION LIBRARY
is thread safe. The data format used by the zlib library
is described by RFCs (Request for Comments) 1950 to 1952 in the files zlib 1.2.1 is a general purpose data compression library. All the code is
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate thread safe. The data format used by the zlib library is described by RFCs
format) and rfc1952.txt (gzip format). These documents are also available in (Request for Comments) 1950 to 1952 in the files
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
and rfc1952.txt (gzip format). These documents are also available in other
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
All functions of the compression library are documented in the file zlib.h All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
example of the library is given in the file example.c which also tests that of the library is given in the file example.c which also tests that the library
the library is working correctly. Another example is given in the file is working correctly. Another example is given in the file minigzip.c. The
minigzip.c. The compression library itself is composed of all source files compression library itself is composed of all source files except example.c and
except example.c and minigzip.c. minigzip.c.
To compile all files and run the test program, follow the instructions To compile all files and run the test program, follow the instructions given at
given at the top of Makefile. In short "make test; make install" the top of Makefile. In short "make test; make install" should work for most
should work for most machines. For Unix: "./configure; make test; make install" machines. For Unix: "./configure; make test; make install" For MSDOS, use one
For MSDOS, use one of the special makefiles such as Makefile.msc. of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
For VMS, use Make_vms.com or descrip.mms. descrip.mms.
Questions about zlib should be sent to <zlib@gzip.org>, or to Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
Gilles Vollant <info@winimage.com> for the Windows DLL version. <info@winimage.com> for the Windows DLL version. The zlib home page is
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
Before reporting a problem, please check this site to verify that please check this site to verify that you have the latest version of zlib;
you have the latest version of zlib; otherwise get the latest version and otherwise get the latest version and check whether the problem still exists or
check whether the problem still exists or not. not.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
before asking for help. for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 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 in issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.1.4 are documented in the file ChangeLog. The changes made in version 1.2.1 are documented in the file ChangeLog.
The only changes made since 1.1.3 are bug corrections:
- ZFREE was repeated on same allocation on some error conditions.
This creates a security problem described in
http://www.zlib.org/advisory-2002-03-11.txt
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
- Avoid accesses before window for invalid distances with inflate window
less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5).
The beta version 1.1.5beta includes many more changes. A new official
version 1.1.5 will be released as soon as extensive testing has been
completed on it.
Unsupported third party contributions are provided in directory "contrib". Unsupported third party contributions are provided in directory "contrib".
A Java implementation of zlib is available in the Java Development Kit A Java implementation of zlib is available in the Java Development Kit
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
See the zlib home page http://www.zlib.org for details. See the zlib home page http://www.zlib.org for details.
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk> A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
is in the CPAN (Comprehensive Perl Archive Network) sites CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/ http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> is
is available in Python 1.5 and later versions, see available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html http://www.python.org/doc/lib/module-zlib.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
An experimental package to read and write files in .zip format, An experimental package to read and write files in .zip format, written on top
written on top of zlib by Gilles Vollant <info@winimage.com>, is of zlib by Gilles Vollant <info@winimage.com>, is available in the
available at http://www.winimage.com/zLibDll/unzip.html contrib/minizip directory of zlib.
and also in the contrib/minizip directory of zlib.
Notes for some targets: Notes for some targets:
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc - For Windows DLL versions, please see win32/DLL_FAQ.txt
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
The zlib DLL support was initially done by Alessandro Iacopetti and is
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
home page at http://www.winimage.com/zLibDll
From Visual Basic, you can call the DLL functions which do not take - For 64-bit Irix, deflate.c must be compiled without any optimization. With
a structure as argument: compress, uncompress and all gz* functions. -O, one libpng test fails. The test works in 32 bit mode (with the -n32
See contrib/visual-basic.txt for more information, or get compiler flag). The compiler bug has been reported to SGI.
http://www.tcfb.com/dowseware/cmp-z-it.zip
- For 64-bit Irix, deflate.c must be compiled without any optimization. - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
With -O, one libpng test fails. The test works in 32 bit mode (with when compiled with cc.
the -n32 compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 - On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
it works when compiled with cc. necessary to get gzprintf working correctly. This is done by configure.
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
is necessary to get gzprintf working correctly. This is done by configure. other compilers. Use "make test" to check your compiler.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
with other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. - gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
- For Turbo C the small model is supported only with reduced performance to - For PalmOs, see http://palmzlib.sourceforge.net/
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html - When building a shared, i.e. dynamic library on Mac OS X, the library must be
Per Harald Myrvang <perm@stud.cs.uit.no> installed before testing (do "make install" before "make test"), since the
library location is specified in the library.
Acknowledgments: Acknowledgments:
@ -116,7 +93,7 @@ Acknowledgments:
Copyright notice: Copyright notice:
(C) 1995-2002 Jean-loup Gailly and Mark Adler (C) 1995-2003 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -144,4 +121,6 @@ entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code. include third-party code.
If you redistribute modified sources, we would appreciate that you include If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes. in the file ChangeLog history information documenting your changes. Please
read the FAQ for more information on the distribution of modified source
versions.

View File

@ -1,13 +1,14 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream /* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
#define BASE 65521L /* largest prime smaller than 65536 */ #define BASE 65521UL /* largest prime smaller than 65536 */
#define NMAX 5552 #define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
@ -17,6 +18,31 @@
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8); #define DO16(buf) DO8(buf,0); DO8(buf,8);
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
if (a >= (BASE << 16)) a -= (BASE << 16); \
if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
#endif
/* ========================================================================= */ /* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len) uLong ZEXPORT adler32(adler, buf, len)
uLong adler; uLong adler;
@ -30,19 +56,19 @@ uLong ZEXPORT adler32(adler, buf, len)
if (buf == Z_NULL) return 1L; if (buf == Z_NULL) return 1L;
while (len > 0) { while (len > 0) {
k = len < NMAX ? len : NMAX; k = len < NMAX ? (int)len : NMAX;
len -= k; len -= k;
while (k >= 16) { while (k >= 16) {
DO16(buf); DO16(buf);
buf += 16; buf += 16;
k -= 16; k -= 16;
} }
if (k != 0) do { if (k != 0) do {
s1 += *buf++; s1 += *buf++;
s2 += s1; s2 += s1;
} while (--k); } while (--k);
s1 %= BASE; MOD(s1);
s2 %= BASE; MOD(s2);
} }
return (s2 << 16) | s1; return (s2 << 16) | s1;
} }

View File

@ -59,10 +59,10 @@ but saves time since there are both fewer insertions and fewer searches.
2.1 Introduction 2.1 Introduction
The real question is, given a Huffman tree, how to decode fast. The most The key question is how to represent a Huffman code (or any prefix code) so
important realization is that shorter codes are much more common than that you can decode fast. The most important characteristic is that shorter
longer codes, so pay attention to decoding the short codes fast, and let codes are much more common than longer codes, so pay attention to decoding the
the long codes take longer to decode. short codes fast, and let the long codes take longer to decode.
inflate() sets up a first level table that covers some number of bits of inflate() sets up a first level table that covers some number of bits of
input less than the length of longest code. It gets that many bits from the input less than the length of longest code. It gets that many bits from the
@ -77,58 +77,54 @@ table took no time (and if you had infinite memory), then there would only
be a first level table to cover all the way to the longest code. However, be a first level table to cover all the way to the longest code. However,
building the table ends up taking a lot longer for more bits since short building the table ends up taking a lot longer for more bits since short
codes are replicated many times in such a table. What inflate() does is codes are replicated many times in such a table. What inflate() does is
simply to make the number of bits in the first table a variable, and set it simply to make the number of bits in the first table a variable, and then
for the maximum speed. to set that variable for the maximum speed.
inflate() sends new trees relatively often, so it is possibly set for a For inflate, which has 286 possible codes for the literal/length tree, the size
smaller first level table than an application that has only one tree for of the first table is nine bits. Also the distance trees have 30 possible
all the data. For inflate, which has 286 possible codes for the values, and the size of the first table is six bits. Note that for each of
literal/length tree, the size of the first table is nine bits. Also the those cases, the table ended up one bit longer than the ``average'' code
distance trees have 30 possible values, and the size of the first table is length, i.e. the code length of an approximately flat code which would be a
six bits. Note that for each of those cases, the table ended up one bit little more than eight bits for 286 symbols and a little less than five bits
longer than the ``average'' code length, i.e. the code length of an for 30 symbols.
approximately flat code which would be a little more than eight bits for
286 symbols and a little less than five bits for 30 symbols. It would be
interesting to see if optimizing the first level table for other
applications gave values within a bit or two of the flat code size.
2.2 More details on the inflate table lookup 2.2 More details on the inflate table lookup
Ok, you want to know what this cleverly obfuscated inflate tree actually Ok, you want to know what this cleverly obfuscated inflate tree actually
looks like. You are correct that it's not a Huffman tree. It is simply a looks like. You are correct that it's not a Huffman tree. It is simply a
lookup table for the first, let's say, nine bits of a Huffman symbol. The lookup table for the first, let's say, nine bits of a Huffman symbol. The
symbol could be as short as one bit or as long as 15 bits. If a particular symbol could be as short as one bit or as long as 15 bits. If a particular
symbol is shorter than nine bits, then that symbol's translation is duplicated symbol is shorter than nine bits, then that symbol's translation is duplicated
in all those entries that start with that symbol's bits. For example, if the in all those entries that start with that symbol's bits. For example, if the
symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
symbol is nine bits long, it appears in the table once. symbol is nine bits long, it appears in the table once.
If the symbol is longer than nine bits, then that entry in the table points If the symbol is longer than nine bits, then that entry in the table points
to another similar table for the remaining bits. Again, there are duplicated to another similar table for the remaining bits. Again, there are duplicated
entries as needed. The idea is that most of the time the symbol will be short entries as needed. The idea is that most of the time the symbol will be short
and there will only be one table look up. (That's whole idea behind data and there will only be one table look up. (That's whole idea behind data
compression in the first place.) For the less frequent long symbols, there compression in the first place.) For the less frequent long symbols, there
will be two lookups. If you had a compression method with really long will be two lookups. If you had a compression method with really long
symbols, you could have as many levels of lookups as is efficient. For symbols, you could have as many levels of lookups as is efficient. For
inflate, two is enough. inflate, two is enough.
So a table entry either points to another table (in which case nine bits in So a table entry either points to another table (in which case nine bits in
the above example are gobbled), or it contains the translation for the symbol the above example are gobbled), or it contains the translation for the symbol
and the number of bits to gobble. Then you start again with the next and the number of bits to gobble. Then you start again with the next
ungobbled bit. ungobbled bit.
You may wonder: why not just have one lookup table for how ever many bits the You may wonder: why not just have one lookup table for how ever many bits the
longest symbol is? The reason is that if you do that, you end up spending longest symbol is? The reason is that if you do that, you end up spending
more time filling in duplicate symbol entries than you do actually decoding. more time filling in duplicate symbol entries than you do actually decoding.
At least for deflate's output that generates new trees every several 10's of At least for deflate's output that generates new trees every several 10's of
kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
would take too long if you're only decoding several thousand symbols. At the would take too long if you're only decoding several thousand symbols. At the
other extreme, you could make a new table for every bit in the code. In fact, other extreme, you could make a new table for every bit in the code. In fact,
that's essentially a Huffman tree. But then you spend two much time that's essentially a Huffman tree. But then you spend two much time
traversing the tree while decoding, even for short symbols. traversing the tree while decoding, even for short symbols.
So the number of bits for the first lookup table is a trade of the time to So the number of bits for the first lookup table is a trade of the time to
fill out the table vs. the time spent looking at the second level and above of fill out the table vs. the time spent looking at the second level and above of
the table. the table.
@ -158,7 +154,7 @@ Let's make the first table three bits long (eight entries):
110: -> table X (gobble 3 bits) 110: -> table X (gobble 3 bits)
111: -> table Y (gobble 3 bits) 111: -> table Y (gobble 3 bits)
Each entry is what the bits decode to and how many bits that is, i.e. how Each entry is what the bits decode as and how many bits that is, i.e. how
many bits to gobble. Or the entry points to another table, with the number of many bits to gobble. Or the entry points to another table, with the number of
bits to gobble implicit in the size of the table. bits to gobble implicit in the size of the table.
@ -170,7 +166,7 @@ long:
10: D,2 10: D,2
11: E,2 11: E,2
Table Y is three bits long since the longest code starting with 111 is six Table Y is three bits long since the longest code starting with 111 is six
bits long: bits long:
000: F,2 000: F,2
@ -182,20 +178,20 @@ bits long:
110: I,3 110: I,3
111: J,3 111: J,3
So what we have here are three tables with a total of 20 entries that had to So what we have here are three tables with a total of 20 entries that had to
be constructed. That's compared to 64 entries for a single table. Or be constructed. That's compared to 64 entries for a single table. Or
compared to 16 entries for a Huffman tree (six two entry tables and one four compared to 16 entries for a Huffman tree (six two entry tables and one four
entry table). Assuming that the code ideally represents the probability of entry table). Assuming that the code ideally represents the probability of
the symbols, it takes on the average 1.25 lookups per symbol. That's compared the symbols, it takes on the average 1.25 lookups per symbol. That's compared
to one lookup for the single table, or 1.66 lookups per symbol for the to one lookup for the single table, or 1.66 lookups per symbol for the
Huffman tree. Huffman tree.
There, I think that gives you a picture of what's going on. For inflate, the There, I think that gives you a picture of what's going on. For inflate, the
meaning of a particular symbol is often more than just a letter. It can be a meaning of a particular symbol is often more than just a letter. It can be a
byte (a "literal"), or it can be either a length or a distance which byte (a "literal"), or it can be either a length or a distance which
indicates a base value and a number of bits to fetch after the code that is indicates a base value and a number of bits to fetch after the code that is
added to the base value. Or it might be the special end-of-block code. The added to the base value. Or it might be the special end-of-block code. The
data structures created in inftrees.c try to encode all that information data structures created in inftrees.c try to encode all that information
compactly in the tables. compactly in the tables.
@ -210,4 +206,4 @@ Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
pp. 337-343. pp. 337-343.
``DEFLATE Compressed Data Format Specification'' available in ``DEFLATE Compressed Data Format Specification'' available in
ftp://ds.internic.net/rfc/rfc1951.txt http://www.ietf.org/rfc/rfc1951.txt

View File

@ -1,10 +1,11 @@
/* compress.c -- compress a memory buffer /* compress.c -- compress a memory buffer
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
/* =========================================================================== /* ===========================================================================
@ -66,3 +67,13 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
{ {
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
} }
/* ===========================================================================
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
{
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
}

View File

@ -1,22 +1,72 @@
/* crc32.c -- compute the CRC-32 of a data stream /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results about a factor
* of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#include "zlib.h" #ifdef MAKECRCH
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
# define DYNAMIC_CRC_TABLE
# endif /* !DYNAMIC_CRC_TABLE */
#endif /* MAKECRCH */
#include "zutil.h" /* for STDC and FAR definitions */
#define local static #define local static
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
# ifdef STDC /* need ANSI C limits.h to determine sizes */
# include <limits.h>
# define BYFOUR
# if (UINT_MAX == 0xffffffffUL)
typedef unsigned int u4;
# else
# if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long u4;
# else
# if (USHRT_MAX == 0xffffffffUL)
typedef unsigned short u4;
# else
# undef BYFOUR /* can't find a four-byte integer type! */
# endif
# endif
# endif
# endif /* STDC */
#endif /* !NOBYFOUR */
/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long,
const unsigned char FAR *, unsigned));
# define TBLS 8
#else
# define TBLS 1
#endif /* BYFOUR */
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
local int crc_table_empty = 1; local int crc_table_empty = 1;
local uLongf crc_table[256]; local unsigned long FAR crc_table[TBLS][256];
local void make_crc_table OF((void)); local void make_crc_table OF((void));
#ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
/* /*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient, Polynomials over GF(2) are represented in binary, one bit per coefficient,
@ -35,128 +85,227 @@ local void make_crc_table OF((void));
out is a one). We start with the highest power (least significant bit) of out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q. q and repeat for all eight bits of q.
The table is simply the CRC of all possible eight bit values. This is all The first table is simply the CRC of all possible eight bit values. This is
the information needed to generate CRC's on data a byte at a time for all all the information needed to generate CRCs on data a byte at a time for all
combinations of CRC register values and incoming bytes. combinations of CRC register values and incoming bytes. The remaining tables
allow for word-at-a-time CRC calculation for both big-endian and little-
endian machines, where a word is four bytes.
*/ */
local void make_crc_table() local void make_crc_table()
{ {
uLong c; unsigned long c;
int n, k; int n, k;
uLong poly; /* polynomial exclusive-or pattern */ unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */ /* terms of polynomial defining this crc (except x^32): */
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL;
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
poly |= 1UL << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
c = (unsigned long)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
}
#ifdef BYFOUR
/* generate crc for each value followed by one, two, and three zeros, and
then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = REV(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = REV(c);
}
}
#endif /* BYFOUR */
/* make exclusive-or pattern from polynomial (0xedb88320L) */
poly = 0L;
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
poly |= 1L << (31 - p[n]);
for (n = 0; n < 256; n++)
{
c = (uLong)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[n] = c;
}
crc_table_empty = 0; crc_table_empty = 0;
#ifdef MAKECRCH
/* write out CRC tables to crc32.h */
{
FILE *out;
out = fopen("crc32.h", "w");
if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
fprintf(out, "local const unsigned long FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]);
# ifdef BYFOUR
fprintf(out, "#ifdef BYFOUR\n");
for (k = 1; k < 8; k++) {
fprintf(out, " },\n {\n");
write_table(out, crc_table[k]);
}
fprintf(out, "#endif\n");
# endif /* BYFOUR */
fprintf(out, " }\n};\n");
fclose(out);
}
#endif /* MAKECRCH */
} }
#else
#ifdef MAKECRCH
local void write_table(out, table)
FILE *out;
const unsigned long FAR *table;
{
int n;
for (n = 0; n < 256; n++)
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */
#else /* !DYNAMIC_CRC_TABLE */
/* ======================================================================== /* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table) * Tables of CRC-32s of all single-byte values, made by make_crc_table().
*/ */
local const uLongf crc_table[256] = { #include "crc32.h"
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, #endif /* DYNAMIC_CRC_TABLE */
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#endif
/* ========================================================================= /* =========================================================================
* This function can be used by asm versions of crc32() * This function can be used by asm versions of crc32()
*/ */
const uLongf * ZEXPORT get_crc_table() const unsigned long FAR * ZEXPORT get_crc_table()
{ {
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table(); if (crc_table_empty) make_crc_table();
#endif #endif /* DYNAMIC_CRC_TABLE */
return (const uLongf *)crc_table; return (const unsigned long FAR *)crc_table;
} }
/* ========================================================================= */ /* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
#define DO2(buf) DO1(buf); DO1(buf); #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */ /* ========================================================================= */
uLong ZEXPORT crc32(crc, buf, len) unsigned long ZEXPORT crc32(crc, buf, len)
uLong crc; unsigned long crc;
const Bytef *buf; const unsigned char FAR *buf;
uInt len; unsigned len;
{ {
if (buf == Z_NULL) return 0L; if (buf == Z_NULL) return 0UL;
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) if (crc_table_empty)
make_crc_table(); make_crc_table();
#endif #endif /* DYNAMIC_CRC_TABLE */
crc = crc ^ 0xffffffffL;
while (len >= 8) #ifdef BYFOUR
{ if (sizeof(void *) == sizeof(ptrdiff_t)) {
DO8(buf); u4 endian;
len -= 8;
endian = 1;
if (*((unsigned char *)(&endian)))
return crc32_little(crc, buf, len);
else
return crc32_big(crc, buf, len);
}
#endif /* BYFOUR */
crc = crc ^ 0xffffffffUL;
while (len >= 8) {
DO8;
len -= 8;
} }
if (len) do { if (len) do {
DO1(buf); DO1;
} while (--len); } while (--len);
return crc ^ 0xffffffffL; return crc ^ 0xffffffffUL;
} }
#ifdef BYFOUR
/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
local unsigned long crc32_little(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = (u4)crc;
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--;
}
buf4 = (const u4 FAR *)buf;
while (len >= 32) {
DOLIT32;
len -= 32;
}
while (len >= 4) {
DOLIT4;
len -= 4;
}
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
} while (--len);
c = ~c;
return (unsigned long)c;
}
/* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
local unsigned long crc32_big(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
unsigned len;
{
register u4 c;
register const u4 FAR *buf4;
c = REV((u4)crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--;
}
buf4 = (const u4 FAR *)buf;
buf4--;
while (len >= 32) {
DOBIG32;
len -= 32;
}
while (len >= 4) {
DOBIG4;
len -= 4;
}
buf4++;
buf = (const unsigned char FAR *)buf4;
if (len) do {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len);
c = ~c;
return (unsigned long)(REV(c));
}
#endif /* BYFOUR */

441
lib/libz/crc32.h Normal file
View File

@ -0,0 +1,441 @@
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
*/
local const unsigned long FAR crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
0x9324fd72UL
},
{
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
0xbe9834edUL
},
{
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
0xde0506f1UL
},
{
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
0x8def022dUL
},
{
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
0x72fd2493UL
},
{
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
0xed3498beUL
},
{
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};

View File

@ -1,6 +1,6 @@
/* deflate.c -- compress data using the deflation algorithm /* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* /*
@ -37,7 +37,7 @@
* REFERENCES * REFERENCES
* *
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
* Available in ftp://ds.internic.net/rfc/rfc1951.txt * Available in http://www.ietf.org/rfc/rfc1951.txt
* *
* A description of the Rabin and Karp algorithm is given in the book * A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
@ -52,7 +52,7 @@
#include "deflate.h" #include "deflate.h"
const char deflate_copyright[] = const char deflate_copyright[] =
" deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; " deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome 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 in the documentation of your product. If for some reason you cannot
@ -76,17 +76,22 @@ typedef block_state (*compress_func) OF((deflate_state *s, int flush));
local void fill_window OF((deflate_state *s)); local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
local block_state deflate_slow OF((deflate_state *s, int flush)); local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
local void lm_init OF((deflate_state *s)); local void lm_init OF((deflate_state *s));
local void putShortMSB OF((deflate_state *s, uInt b)); local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm)); local void flush_pending OF((z_streamp strm));
local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
#ifndef FASTEST
#ifdef ASMV #ifdef ASMV
void match_init OF((void)); /* asm code initialization */ void match_init OF((void)); /* asm code initialization */
uInt longest_match OF((deflate_state *s, IPos cur_match)); uInt longest_match OF((deflate_state *s, IPos cur_match));
#else #else
local uInt longest_match OF((deflate_state *s, IPos cur_match)); local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif #endif
#endif
local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
#ifdef DEBUG #ifdef DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match, local void check_match OF((deflate_state *s, IPos start, IPos match,
@ -123,10 +128,16 @@ typedef struct config_s {
compress_func func; compress_func func;
} config; } config;
#ifdef FASTEST
local const config configuration_table[2] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
#else
local const config configuration_table[10] = { local const config configuration_table[10] = {
/* good lazy nice chain */ /* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
/* 2 */ {4, 5, 16, 8, deflate_fast}, /* 2 */ {4, 5, 16, 8, deflate_fast},
/* 3 */ {4, 6, 32, 32, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast},
@ -135,7 +146,8 @@ local const config configuration_table[10] = {
/* 6 */ {8, 16, 128, 128, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow},
/* 7 */ {8, 32, 128, 256, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow},
/* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow},
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
#endif
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
@ -145,7 +157,9 @@ local const config configuration_table[10] = {
#define EQUAL 0 #define EQUAL 0
/* result of memcmp for equal strings */ /* result of memcmp for equal strings */
#ifndef NO_DUMMY_DECL
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
#endif
/* =========================================================================== /* ===========================================================================
* Update a hash value with the given input byte * Update a hash value with the given input byte
@ -174,7 +188,7 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
#else #else
#define INSERT_STRING(s, str, match_head) \ #define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
s->head[s->ins_h] = (Pos)(str)) s->head[s->ins_h] = (Pos)(str))
#endif #endif
@ -194,13 +208,13 @@ int ZEXPORT deflateInit_(strm, level, version, stream_size)
int stream_size; int stream_size;
{ {
return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY, version, stream_size); Z_DEFAULT_STRATEGY, version, stream_size);
/* To do: ignore strm->next_in if we use it as window */ /* To do: ignore strm->next_in if we use it as window */
} }
/* ========================================================================= */ /* ========================================================================= */
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
version, stream_size) version, stream_size)
z_streamp strm; z_streamp strm;
int level; int level;
int method; int method;
@ -211,8 +225,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
int stream_size; int stream_size;
{ {
deflate_state *s; deflate_state *s;
int noheader = 0; int wrap = 1;
static const char* my_version = ZLIB_VERSION; static const char my_version[] = ZLIB_VERSION;
ushf *overlay; ushf *overlay;
/* We overlay pending_buf and d_buf+l_buf. This works since the average /* We overlay pending_buf and d_buf+l_buf. This works since the average
@ -221,37 +235,45 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (version == Z_NULL || version[0] != my_version[0] || if (version == Z_NULL || version[0] != my_version[0] ||
stream_size != sizeof(z_stream)) { stream_size != sizeof(z_stream)) {
return Z_VERSION_ERROR; return Z_VERSION_ERROR;
} }
if (strm == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; strm->msg = Z_NULL;
if (strm->zalloc == Z_NULL) { if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc; strm->zalloc = zcalloc;
strm->opaque = (voidpf)0; strm->opaque = (voidpf)0;
} }
if (strm->zfree == Z_NULL) strm->zfree = zcfree; if (strm->zfree == (free_func)0) strm->zfree = zcfree;
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#ifdef FASTEST #ifdef FASTEST
level = 1; if (level != 0) level = 1;
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif #endif
if (windowBits < 0) { /* undocumented feature: suppress zlib header */ if (windowBits < 0) { /* suppress zlib wrapper */
noheader = 1; wrap = 0;
windowBits = -windowBits; windowBits = -windowBits;
} }
#ifdef GZIP
else if (windowBits > 15) {
wrap = 2; /* write gzip wrapper instead */
windowBits -= 16;
}
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_HUFFMAN_ONLY) { strategy < 0 || strategy > Z_RLE) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
if (s == Z_NULL) return Z_MEM_ERROR; if (s == Z_NULL) return Z_MEM_ERROR;
strm->state = (struct internal_state FAR *)s; strm->state = (struct internal_state FAR *)s;
s->strm = strm; s->strm = strm;
s->noheader = noheader; s->wrap = wrap;
s->w_bits = windowBits; s->w_bits = windowBits;
s->w_size = 1 << s->w_bits; s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1; s->w_mask = s->w_size - 1;
@ -273,6 +295,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) { s->pending_buf == Z_NULL) {
s->status = FINISH_STATE;
strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm); deflateEnd (strm);
return Z_MEM_ERROR; return Z_MEM_ERROR;
@ -299,16 +322,19 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
IPos hash_head = 0; IPos hash_head = 0;
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
strm->state->status != INIT_STATE) return Z_STREAM_ERROR; strm->state->wrap == 2 ||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
strm->adler = adler32(strm->adler, dictionary, dictLength); if (s->wrap)
strm->adler = adler32(strm->adler, dictionary, dictLength);
if (length < MIN_MATCH) return Z_OK; if (length < MIN_MATCH) return Z_OK;
if (length > MAX_DIST(s)) { if (length > MAX_DIST(s)) {
length = MAX_DIST(s); length = MAX_DIST(s);
#ifndef USE_DICT_HEAD #ifndef USE_DICT_HEAD
dictionary += dictLength - length; /* use the tail of the dictionary */ dictionary += dictLength - length; /* use the tail of the dictionary */
#endif #endif
} }
zmemcpy(s->window, dictionary, length); zmemcpy(s->window, dictionary, length);
@ -322,7 +348,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
s->ins_h = s->window[0]; s->ins_h = s->window[0];
UPDATE_HASH(s, s->ins_h, s->window[1]); UPDATE_HASH(s, s->ins_h, s->window[1]);
for (n = 0; n <= length - MIN_MATCH; n++) { for (n = 0; n <= length - MIN_MATCH; n++) {
INSERT_STRING(s, n, hash_head); INSERT_STRING(s, n, hash_head);
} }
if (hash_head) hash_head = 0; /* to make compiler happy */ if (hash_head) hash_head = 0; /* to make compiler happy */
return Z_OK; return Z_OK;
@ -333,9 +359,11 @@ int ZEXPORT deflateReset (strm)
z_streamp strm; z_streamp strm;
{ {
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL || if (strm == Z_NULL || strm->state == Z_NULL ||
strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
return Z_STREAM_ERROR;
}
strm->total_in = strm->total_out = 0; strm->total_in = strm->total_out = 0;
strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
@ -345,11 +373,15 @@ int ZEXPORT deflateReset (strm)
s->pending = 0; s->pending = 0;
s->pending_out = s->pending_buf; s->pending_out = s->pending_buf;
if (s->noheader < 0) { if (s->wrap < 0) {
s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
} }
s->status = s->noheader ? BUSY_STATE : INIT_STATE; s->status = s->wrap ? INIT_STATE : BUSY_STATE;
strm->adler = 1; 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 = Z_NO_FLUSH;
_tr_init(s); _tr_init(s);
@ -358,6 +390,18 @@ int ZEXPORT deflateReset (strm)
return Z_OK; return Z_OK;
} }
/* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm;
int bits;
int value;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
strm->state->bi_valid = bits;
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
return Z_OK;
}
/* ========================================================================= */ /* ========================================================================= */
int ZEXPORT deflateParams(strm, level, strategy) int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm; z_streamp strm;
@ -371,29 +415,72 @@ int ZEXPORT deflateParams(strm, level, strategy)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
if (level == Z_DEFAULT_COMPRESSION) { #ifdef FASTEST
level = 6; if (level != 0) level = 1;
} #else
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { if (level == Z_DEFAULT_COMPRESSION) level = 6;
return Z_STREAM_ERROR; #endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
return Z_STREAM_ERROR;
} }
func = configuration_table[s->level].func; func = configuration_table[s->level].func;
if (func != configuration_table[level].func && strm->total_in != 0) { if (func != configuration_table[level].func && strm->total_in != 0) {
/* Flush the last buffer: */ /* Flush the last buffer: */
err = deflate(strm, Z_PARTIAL_FLUSH); err = deflate(strm, Z_PARTIAL_FLUSH);
} }
if (s->level != level) { if (s->level != level) {
s->level = level; s->level = level;
s->max_lazy_match = configuration_table[level].max_lazy; s->max_lazy_match = configuration_table[level].max_lazy;
s->good_match = configuration_table[level].good_length; s->good_match = configuration_table[level].good_length;
s->nice_match = configuration_table[level].nice_length; s->nice_match = configuration_table[level].nice_length;
s->max_chain_length = configuration_table[level].max_chain; s->max_chain_length = configuration_table[level].max_chain;
} }
s->strategy = strategy; s->strategy = strategy;
return err; return err;
} }
/* =========================================================================
* 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 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.
*
* This function could be more sophisticated to provide closer upper bounds
* for every combination of windowBits and memLevel, as well as wrap.
* But even the conservative upper bound of about 14% expansion does not
* seem onerous for output buffer allocation.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
deflate_state *s;
uLong destLen;
/* conservative upper bound */
destLen = sourceLen +
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
/* if can't get parameters, return conservative bound */
if (strm == Z_NULL || strm->state == Z_NULL)
return destLen;
/* if not default parameters, return conservative bound */
s = strm->state;
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return destLen;
/* default settings: return tight bound for that case */
return compressBound(sourceLen);
}
/* ========================================================================= /* =========================================================================
* Put a short in the pending buffer. The 16-bit value is put in MSB order. * Put a short in the pending buffer. The 16-bit value is put in MSB order.
* IN assertion: the stream state is correct and there is enough room in * IN assertion: the stream state is correct and there is enough room in
@ -405,7 +492,7 @@ local void putShortMSB (s, b)
{ {
put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b >> 8));
put_byte(s, (Byte)(b & 0xff)); put_byte(s, (Byte)(b & 0xff));
} }
/* ========================================================================= /* =========================================================================
* Flush as much pending output as possible. All deflate() output goes * Flush as much pending output as possible. All deflate() output goes
@ -441,14 +528,14 @@ int ZEXPORT deflate (strm, flush)
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL || if (strm == Z_NULL || strm->state == Z_NULL ||
flush > Z_FINISH || flush < 0) { flush > Z_FINISH || flush < 0) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
s = strm->state; s = strm->state;
if (strm->next_out == Z_NULL || if (strm->next_out == Z_NULL ||
(strm->next_in == Z_NULL && strm->avail_in != 0) || (strm->next_in == Z_NULL && strm->avail_in != 0) ||
(s->status == FINISH_STATE && flush != Z_FINISH)) { (s->status == FINISH_STATE && flush != Z_FINISH)) {
ERR_RETURN(strm, Z_STREAM_ERROR); ERR_RETURN(strm, Z_STREAM_ERROR);
} }
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
@ -457,48 +544,75 @@ int ZEXPORT deflate (strm, flush)
old_flush = s->last_flush; old_flush = s->last_flush;
s->last_flush = flush; s->last_flush = flush;
/* Write the zlib header */ /* Write the header */
if (s->status == INIT_STATE) { if (s->status == INIT_STATE) {
#ifdef GZIP
if (s->wrap == 2) {
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, 0);
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, 255);
s->status = BUSY_STATE;
strm->adler = crc32(0L, Z_NULL, 0);
}
else
#endif
{
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
uInt level_flags;
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
uInt level_flags = (s->level-1) >> 1; level_flags = 0;
else if (s->level < 6)
level_flags = 1;
else if (s->level == 6)
level_flags = 2;
else
level_flags = 3;
header |= (level_flags << 6);
if (s->strstart != 0) header |= PRESET_DICT;
header += 31 - (header % 31);
if (level_flags > 3) level_flags = 3; s->status = BUSY_STATE;
header |= (level_flags << 6); putShortMSB(s, header);
if (s->strstart != 0) header |= PRESET_DICT;
header += 31 - (header % 31);
s->status = BUSY_STATE; /* Save the adler32 of the preset dictionary: */
putShortMSB(s, header); if (s->strstart != 0) {
putShortMSB(s, (uInt)(strm->adler >> 16));
/* Save the adler32 of the preset dictionary: */ putShortMSB(s, (uInt)(strm->adler & 0xffff));
if (s->strstart != 0) { }
putShortMSB(s, (uInt)(strm->adler >> 16)); strm->adler = adler32(0L, Z_NULL, 0);
putShortMSB(s, (uInt)(strm->adler & 0xffff)); }
}
strm->adler = 1L;
} }
/* Flush as much pending output as possible */ /* Flush as much pending output as possible */
if (s->pending != 0) { if (s->pending != 0) {
flush_pending(strm); flush_pending(strm);
if (strm->avail_out == 0) { if (strm->avail_out == 0) {
/* Since avail_out is 0, deflate will be called again with /* Since avail_out is 0, deflate will be called again with
* more output space, but possibly with both pending and * more output space, but possibly with both pending and
* avail_in equal to zero. There won't be anything to do, * avail_in equal to zero. There won't be anything to do,
* but this is not an error situation so make sure we * but this is not an error situation so make sure we
* return OK instead of BUF_ERROR at next call of deflate: * return OK instead of BUF_ERROR at next call of deflate:
*/ */
s->last_flush = -1; s->last_flush = -1;
return Z_OK; return Z_OK;
} }
/* Make sure there is something to do and avoid duplicate consecutive /* Make sure there is something to do and avoid duplicate consecutive
* flushes. For repeated and useless calls with Z_FINISH, we keep * flushes. For repeated and useless calls with Z_FINISH, we keep
* returning Z_STREAM_END instead of Z_BUFF_ERROR. * returning Z_STREAM_END instead of Z_BUF_ERROR.
*/ */
} else if (strm->avail_in == 0 && flush <= old_flush && } else if (strm->avail_in == 0 && flush <= old_flush &&
flush != Z_FINISH) { flush != Z_FINISH) {
ERR_RETURN(strm, Z_BUF_ERROR); ERR_RETURN(strm, Z_BUF_ERROR);
} }
@ -513,24 +627,24 @@ int ZEXPORT deflate (strm, flush)
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate; block_state bstate;
bstate = (*(configuration_table[s->level].func))(s, flush); bstate = (*(configuration_table[s->level].func))(s, flush);
if (bstate == finish_started || bstate == finish_done) { if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE; s->status = FINISH_STATE;
} }
if (bstate == need_more || bstate == finish_started) { if (bstate == need_more || bstate == finish_started) {
if (strm->avail_out == 0) { if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
} }
return Z_OK; return Z_OK;
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
* of deflate should use the same flush parameter to make sure * of deflate should use the same flush parameter to make sure
* that the flush is complete. So we don't have to output an * that the flush is complete. So we don't have to output an
* empty block here, this will be done at next call. This also * empty block here, this will be done at next call. This also
* ensures that for a very small output buffer, we emit at most * ensures that for a very small output buffer, we emit at most
* one empty block. * one empty block.
*/ */
} }
if (bstate == block_done) { if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) { if (flush == Z_PARTIAL_FLUSH) {
_tr_align(s); _tr_align(s);
@ -544,25 +658,40 @@ int ZEXPORT deflate (strm, flush)
} }
} }
flush_pending(strm); flush_pending(strm);
if (strm->avail_out == 0) { if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
return Z_OK; return Z_OK;
} }
} }
} }
Assert(strm->avail_out > 0, "bug2"); Assert(strm->avail_out > 0, "bug2");
if (flush != Z_FINISH) return Z_OK; if (flush != Z_FINISH) return Z_OK;
if (s->noheader) return Z_STREAM_END; if (s->wrap <= 0) return Z_STREAM_END;
/* Write the zlib trailer (adler32) */ /* Write the trailer */
putShortMSB(s, (uInt)(strm->adler >> 16)); #ifdef GZIP
putShortMSB(s, (uInt)(strm->adler & 0xffff)); if (s->wrap == 2) {
put_byte(s, (Byte)(strm->adler & 0xff));
put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
put_byte(s, (Byte)(strm->total_in & 0xff));
put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
}
else
#endif
{
putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff));
}
flush_pending(strm); flush_pending(strm);
/* If avail_out is zero, the application will call deflate again /* If avail_out is zero, the application will call deflate again
* to flush the rest. * to flush the rest.
*/ */
s->noheader = -1; /* write the trailer only once! */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
return s->pending != 0 ? Z_OK : Z_STREAM_END; return s->pending != 0 ? Z_OK : Z_STREAM_END;
} }
@ -576,7 +705,7 @@ int ZEXPORT deflateEnd (strm)
status = strm->state->status; status = strm->state->status;
if (status != INIT_STATE && status != BUSY_STATE && if (status != INIT_STATE && status != BUSY_STATE &&
status != FINISH_STATE) { status != FINISH_STATE) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
@ -649,7 +778,7 @@ int ZEXPORT deflateCopy (dest, source)
ds->bl_desc.dyn_tree = ds->bl_tree; ds->bl_desc.dyn_tree = ds->bl_tree;
return Z_OK; return Z_OK;
#endif #endif /* MAXSEG_64K */
} }
/* =========================================================================== /* ===========================================================================
@ -671,9 +800,14 @@ local int read_buf(strm, buf, size)
strm->avail_in -= len; strm->avail_in -= len;
if (!strm->state->noheader) { if (strm->state->wrap == 1) {
strm->adler = adler32(strm->adler, strm->next_in, len); strm->adler = adler32(strm->adler, strm->next_in, len);
} }
#ifdef GZIP
else if (strm->state->wrap == 2) {
strm->adler = crc32(strm->adler, strm->next_in, len);
}
#endif
zmemcpy(buf, strm->next_in, len); zmemcpy(buf, strm->next_in, len);
strm->next_in += len; strm->next_in += len;
strm->total_in += len; strm->total_in += len;
@ -709,6 +843,7 @@ local void lm_init (s)
#endif #endif
} }
#ifndef FASTEST
/* =========================================================================== /* ===========================================================================
* Set match_start to the longest match starting at the given string and * Set match_start to the longest match starting at the given string and
* return its length. Matches shorter or equal to prev_length are discarded, * return its length. Matches shorter or equal to prev_length are discarded,
@ -722,7 +857,6 @@ local void lm_init (s)
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent. * match.S. The code will be functionally equivalent.
*/ */
#ifndef FASTEST
local uInt longest_match(s, cur_match) local uInt longest_match(s, cur_match)
deflate_state *s; deflate_state *s;
IPos cur_match; /* current match */ IPos cur_match; /* current match */
@ -860,12 +994,13 @@ local uInt longest_match(s, cur_match)
if ((uInt)best_len <= s->lookahead) return (uInt)best_len; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead; return s->lookahead;
} }
#endif /* ASMV */
#endif /* FASTEST */
#else /* FASTEST */
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Optimized version for level == 1 only * Optimized version for level == 1 or strategy == Z_RLE only
*/ */
local uInt longest_match(s, cur_match) local uInt longest_match_fast(s, cur_match)
deflate_state *s; deflate_state *s;
IPos cur_match; /* current match */ IPos cur_match; /* current match */
{ {
@ -903,10 +1038,10 @@ local uInt longest_match(s, cur_match)
*/ */
do { do {
} while (*++scan == *++match && *++scan == *++match && } while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match &&
scan < strend); scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
@ -915,10 +1050,8 @@ local uInt longest_match(s, cur_match)
if (len < MIN_MATCH) return MIN_MATCH - 1; if (len < MIN_MATCH) return MIN_MATCH - 1;
s->match_start = cur_match; s->match_start = cur_match;
return len <= s->lookahead ? len : s->lookahead; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
} }
#endif /* FASTEST */
#endif /* ASMV */
#ifdef DEBUG #ifdef DEBUG
/* =========================================================================== /* ===========================================================================
@ -933,10 +1066,10 @@ local void check_match(s, start, match, length)
if (zmemcmp(s->window + match, if (zmemcmp(s->window + match,
s->window + start, length) != EQUAL) { s->window + start, length) != EQUAL) {
fprintf(stderr, " start %u, match %u, length %d\n", fprintf(stderr, " start %u, match %u, length %d\n",
start, match, length); start, match, length);
do { do {
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
} while (--length != 0); } while (--length != 0);
z_error("invalid match"); z_error("invalid match");
} }
if (z_verbose > 1) { if (z_verbose > 1) {
@ -946,7 +1079,7 @@ local void check_match(s, start, match, length)
} }
#else #else
# define check_match(s, start, match, length) # define check_match(s, start, match, length)
#endif #endif /* DEBUG */
/* =========================================================================== /* ===========================================================================
* Fill the window when the lookahead becomes insufficient. * Fill the window when the lookahead becomes insufficient.
@ -970,19 +1103,22 @@ local void fill_window(s)
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
/* Deal with !@#$% 64K limit: */ /* Deal with !@#$% 64K limit: */
if (more == 0 && s->strstart == 0 && s->lookahead == 0) { if (sizeof(int) <= 2) {
more = wsize; if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
more = wsize;
} else if (more == (unsigned)(-1)) { } else if (more == (unsigned)(-1)) {
/* Very unlikely, but possible on 16 bit machine if strstart == 0 /* Very unlikely, but possible on 16 bit machine if
* and lookahead == 1 (input done one byte at time) * strstart == 0 && lookahead == 1 (input done a byte at time)
*/ */
more--; more--;
}
}
/* If the window is almost full and there is insufficient lookahead, /* 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. * move the upper half to the lower one to make room in the upper half.
*/ */
} else if (s->strstart >= wsize+MAX_DIST(s)) { if (s->strstart >= wsize+MAX_DIST(s)) {
zmemcpy(s->window, s->window+wsize, (unsigned)wsize); zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
s->match_start -= wsize; s->match_start -= wsize;
@ -995,23 +1131,23 @@ local void fill_window(s)
later. (Using level 0 permanently is not an optimal usage of later. (Using level 0 permanently is not an optimal usage of
zlib, so we don't care about this pathological case.) zlib, so we don't care about this pathological case.)
*/ */
n = s->hash_size; n = s->hash_size;
p = &s->head[n]; p = &s->head[n];
do { do {
m = *--p; m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL); *p = (Pos)(m >= wsize ? m-wsize : NIL);
} while (--n); } while (--n);
n = wsize; n = wsize;
#ifndef FASTEST #ifndef FASTEST
p = &s->prev[n]; p = &s->prev[n];
do { do {
m = *--p; m = *--p;
*p = (Pos)(m >= wsize ? m-wsize : NIL); *p = (Pos)(m >= wsize ? m-wsize : NIL);
/* If n is not on any hash chain, prev[n] is garbage but /* If n is not on any hash chain, prev[n] is garbage but
* its value will never be used. * its value will never be used.
*/ */
} while (--n); } while (--n);
#endif #endif
more += wsize; more += wsize;
} }
@ -1056,8 +1192,8 @@ local void fill_window(s)
_tr_flush_block(s, (s->block_start >= 0L ? \ _tr_flush_block(s, (s->block_start >= 0L ? \
(charf *)&s->window[(unsigned)s->block_start] : \ (charf *)&s->window[(unsigned)s->block_start] : \
(charf *)Z_NULL), \ (charf *)Z_NULL), \
(ulg)((long)s->strstart - s->block_start), \ (ulg)((long)s->strstart - s->block_start), \
(eof)); \ (eof)); \
s->block_start = s->strstart; \ s->block_start = s->strstart; \
flush_pending(s->strm); \ flush_pending(s->strm); \
Tracev((stderr,"[FLUSH]")); \ Tracev((stderr,"[FLUSH]")); \
@ -1098,32 +1234,32 @@ local block_state deflate_stored(s, flush)
if (s->lookahead <= 1) { if (s->lookahead <= 1) {
Assert(s->strstart < s->w_size+MAX_DIST(s) || Assert(s->strstart < s->w_size+MAX_DIST(s) ||
s->block_start >= (long)s->w_size, "slide too late"); s->block_start >= (long)s->w_size, "slide too late");
fill_window(s); fill_window(s);
if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
if (s->lookahead == 0) break; /* flush the current block */ if (s->lookahead == 0) break; /* flush the current block */
} }
Assert(s->block_start >= 0L, "block gone"); Assert(s->block_start >= 0L, "block gone");
s->strstart += s->lookahead; s->strstart += s->lookahead;
s->lookahead = 0; s->lookahead = 0;
/* Emit a stored block if pending_buf will be full: */ /* Emit a stored block if pending_buf will be full: */
max_start = s->block_start + max_block_size; max_start = s->block_start + max_block_size;
if (s->strstart == 0 || (ulg)s->strstart >= max_start) { if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
/* strstart == 0 is possible when wraparound on 16-bit machine */ /* strstart == 0 is possible when wraparound on 16-bit machine */
s->lookahead = (uInt)(s->strstart - max_start); s->lookahead = (uInt)(s->strstart - max_start);
s->strstart = (uInt)max_start; s->strstart = (uInt)max_start;
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
} }
/* Flush if we may have to slide, otherwise block_start may become /* Flush if we may have to slide, otherwise block_start may become
* negative and the data will be gone: * negative and the data will be gone:
*/ */
if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
FLUSH_BLOCK(s, 0); FLUSH_BLOCK(s, 0);
} }
} }
FLUSH_BLOCK(s, flush == Z_FINISH); FLUSH_BLOCK(s, flush == Z_FINISH);
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
@ -1152,8 +1288,8 @@ local block_state deflate_fast(s, flush)
if (s->lookahead < MIN_LOOKAHEAD) { if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s); fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more; return need_more;
} }
if (s->lookahead == 0) break; /* flush the current block */ if (s->lookahead == 0) break; /* flush the current block */
} }
@ -1172,10 +1308,19 @@ local block_state deflate_fast(s, flush)
* of window index 0 (in particular we have to avoid a match * of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
if (s->strategy != Z_HUFFMAN_ONLY) { #ifdef FASTEST
s->match_length = longest_match (s, hash_head); if ((s->strategy < Z_HUFFMAN_ONLY) ||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
s->match_length = longest_match_fast (s, hash_head);
} }
/* longest_match() sets match_start */ #else
if (s->strategy < Z_HUFFMAN_ONLY) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
}
#endif
/* longest_match() or longest_match_fast() sets match_start */
} }
if (s->match_length >= MIN_MATCH) { if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length); check_match(s, s->strstart, s->match_start, s->match_length);
@ -1191,7 +1336,7 @@ local block_state deflate_fast(s, flush)
#ifndef FASTEST #ifndef FASTEST
if (s->match_length <= s->max_insert_length && if (s->match_length <= s->max_insert_length &&
s->lookahead >= MIN_MATCH) { s->lookahead >= MIN_MATCH) {
s->match_length--; /* string at strstart already in hash table */ s->match_length--; /* string at strstart already in table */
do { do {
s->strstart++; s->strstart++;
INSERT_STRING(s, s->strstart, hash_head); INSERT_STRING(s, s->strstart, hash_head);
@ -1199,10 +1344,10 @@ local block_state deflate_fast(s, flush)
* always MIN_MATCH bytes ahead. * always MIN_MATCH bytes ahead.
*/ */
} while (--s->match_length != 0); } while (--s->match_length != 0);
s->strstart++; s->strstart++;
} else } else
#endif #endif
{ {
s->strstart += s->match_length; s->strstart += s->match_length;
s->match_length = 0; s->match_length = 0;
s->ins_h = s->window[s->strstart]; s->ins_h = s->window[s->strstart];
@ -1219,7 +1364,7 @@ local block_state deflate_fast(s, flush)
Tracevv((stderr,"%c", s->window[s->strstart])); 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->lookahead--;
s->strstart++; s->strstart++;
} }
if (bflush) FLUSH_BLOCK(s, 0); if (bflush) FLUSH_BLOCK(s, 0);
} }
@ -1227,6 +1372,7 @@ local block_state deflate_fast(s, flush)
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
} }
#ifndef FASTEST
/* =========================================================================== /* ===========================================================================
* Same as above, but achieves better compression. We use a lazy * Same as above, but achieves better compression. We use a lazy
* evaluation for matches: a match is finally adopted only if there is * evaluation for matches: a match is finally adopted only if there is
@ -1249,8 +1395,8 @@ local block_state deflate_slow(s, flush)
if (s->lookahead < MIN_LOOKAHEAD) { if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s); fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more; return need_more;
} }
if (s->lookahead == 0) break; /* flush the current block */ if (s->lookahead == 0) break; /* flush the current block */
} }
@ -1272,14 +1418,19 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match * of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
if (s->strategy != Z_HUFFMAN_ONLY) { if (s->strategy < Z_HUFFMAN_ONLY) {
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
} }
/* longest_match() sets match_start */ /* longest_match() or longest_match_fast() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED || if (s->match_length <= 5 && (s->strategy == Z_FILTERED
(s->match_length == MIN_MATCH && #if TOO_FAR <= 32767
s->strstart - s->match_start > TOO_FAR))) { || (s->match_length == MIN_MATCH &&
s->strstart - s->match_start > TOO_FAR)
#endif
)) {
/* If prev_match is also MIN_MATCH, match_start is garbage /* If prev_match is also MIN_MATCH, match_start is garbage
* but we will ignore the current match anyway. * but we will ignore the current match anyway.
@ -1297,7 +1448,7 @@ local block_state deflate_slow(s, flush)
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); s->prev_length - MIN_MATCH, bflush);
/* Insert in hash table all strings up to the end of the match. /* 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
@ -1323,8 +1474,8 @@ local block_state deflate_slow(s, flush)
* is longer, truncate the previous match to a single literal. * is longer, truncate the previous match to a single literal.
*/ */
Tracevv((stderr,"%c", s->window[s->strstart-1])); Tracevv((stderr,"%c", s->window[s->strstart-1]));
_tr_tally_lit(s, s->window[s->strstart-1], bflush); _tr_tally_lit(s, s->window[s->strstart-1], bflush);
if (bflush) { if (bflush) {
FLUSH_BLOCK_ONLY(s, 0); FLUSH_BLOCK_ONLY(s, 0);
} }
s->strstart++; s->strstart++;
@ -1348,3 +1499,4 @@ local block_state deflate_slow(s, flush)
FLUSH_BLOCK(s, flush == Z_FINISH); FLUSH_BLOCK(s, flush == Z_FINISH);
return flush == Z_FINISH ? finish_done : block_done; return flush == Z_FINISH ? finish_done : block_done;
} }
#endif /* FASTEST */

View File

@ -1,6 +1,6 @@
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995-2002 Jean-loup Gailly * Copyright (C) 1995-2002 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* WARNING: this file should *not* be used by applications. It is /* WARNING: this file should *not* be used by applications. It is
@ -10,11 +10,19 @@
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _DEFLATE_H #ifndef DEFLATE_H
#define _DEFLATE_H #define DEFLATE_H
#include "zutil.h" #include "zutil.h"
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip encoding
should be left enabled. */
#ifndef NO_GZIP
# define GZIP
#endif
/* =========================================================================== /* ===========================================================================
* Internal compression state. * Internal compression state.
*/ */
@ -86,7 +94,7 @@ typedef struct internal_state {
ulg pending_buf_size; /* size of pending_buf */ ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */ Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */ int pending; /* nb of bytes in the pending buffer */
int noheader; /* suppress zlib header and adler32 */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte data_type; /* UNKNOWN, BINARY or ASCII */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */ int last_flush; /* value of flush param for previous deflate call */
@ -269,7 +277,7 @@ typedef struct internal_state {
void _tr_init OF((deflate_state *s)); void _tr_init OF((deflate_state *s));
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof)); int eof));
void _tr_align OF((deflate_state *s)); void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof)); int eof));
@ -312,7 +320,7 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
#else #else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \ # define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length) flush = _tr_tally(s, distance, length)
#endif #endif
#endif #endif /* DEFLATE_H */

View File

@ -1,6 +1,6 @@
/* example.c -- usage example of the zlib compression library /* example.c -- usage example of the zlib compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
@ -37,22 +37,22 @@ const char dictionary[] = "hello";
uLong dictId; /* Adler32 value of the dictionary */ uLong dictId; /* Adler32 value of the dictionary */
void test_compress OF((Byte *compr, uLong comprLen, void test_compress OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_gzio OF((const char *out, const char *in, void test_gzio OF((const char *fname,
Byte *uncompr, int uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_deflate OF((Byte *compr, uLong comprLen)); void test_deflate OF((Byte *compr, uLong comprLen));
void test_inflate OF((Byte *compr, uLong comprLen, void test_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_large_deflate OF((Byte *compr, uLong comprLen, void test_large_deflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_large_inflate OF((Byte *compr, uLong comprLen, void test_large_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_flush OF((Byte *compr, uLong *comprLen)); void test_flush OF((Byte *compr, uLong *comprLen));
void test_sync OF((Byte *compr, uLong comprLen, void test_sync OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
void test_dict_deflate OF((Byte *compr, uLong comprLen)); void test_dict_deflate OF((Byte *compr, uLong comprLen));
void test_dict_inflate OF((Byte *compr, uLong comprLen, void test_dict_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen)); Byte *uncompr, uLong uncomprLen));
int main OF((int argc, char *argv[])); int main OF((int argc, char *argv[]));
/* =========================================================================== /* ===========================================================================
@ -63,7 +63,7 @@ void test_compress(compr, comprLen, uncompr, uncomprLen)
uLong comprLen, uncomprLen; uLong comprLen, uncomprLen;
{ {
int err; int err;
uLong len = strlen(hello)+1; uLong len = (uLong)strlen(hello)+1;
err = compress(compr, &comprLen, (const Bytef*)hello, len); err = compress(compr, &comprLen, (const Bytef*)hello, len);
CHECK_ERR(err, "compress"); CHECK_ERR(err, "compress");
@ -75,7 +75,7 @@ void test_compress(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) { if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad uncompress\n"); fprintf(stderr, "bad uncompress\n");
exit(1); exit(1);
} else { } else {
printf("uncompress(): %s\n", (char *)uncompr); printf("uncompress(): %s\n", (char *)uncompr);
} }
@ -84,18 +84,20 @@ void test_compress(compr, comprLen, uncompr, uncomprLen)
/* =========================================================================== /* ===========================================================================
* Test read/write of .gz files * Test read/write of .gz files
*/ */
void test_gzio(out, in, uncompr, uncomprLen) void test_gzio(fname, uncompr, uncomprLen)
const char *out; /* compressed output file */ const char *fname; /* compressed file name */
const char *in; /* compressed input file */
Byte *uncompr; Byte *uncompr;
int uncomprLen; uLong uncomprLen;
{ {
#ifdef NO_GZCOMPRESS
fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
#else
int err; int err;
int len = strlen(hello)+1; int len = (int)strlen(hello)+1;
gzFile file; gzFile file;
z_off_t pos; z_off_t pos;
file = gzopen(out, "wb"); file = gzopen(fname, "wb");
if (file == NULL) { if (file == NULL) {
fprintf(stderr, "gzopen error\n"); fprintf(stderr, "gzopen error\n");
exit(1); exit(1);
@ -103,59 +105,64 @@ void test_gzio(out, in, uncompr, uncomprLen)
gzputc(file, 'h'); gzputc(file, 'h');
if (gzputs(file, "ello") != 4) { if (gzputs(file, "ello") != 4) {
fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
exit(1); exit(1);
} }
if (gzprintf(file, ", %s!", "hello") != 8) { if (gzprintf(file, ", %s!", "hello") != 8) {
fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
exit(1); exit(1);
} }
gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
gzclose(file); gzclose(file);
file = gzopen(in, "rb"); file = gzopen(fname, "rb");
if (file == NULL) { if (file == NULL) {
fprintf(stderr, "gzopen error\n"); fprintf(stderr, "gzopen error\n");
exit(1);
} }
strcpy((char*)uncompr, "garbage"); strcpy((char*)uncompr, "garbage");
uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen); if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
if (uncomprLen != len) {
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
exit(1); exit(1);
} }
if (strcmp((char*)uncompr, hello)) { if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
exit(1); exit(1);
} else { } else {
printf("gzread(): %s\n", (char *)uncompr); printf("gzread(): %s\n", (char*)uncompr);
} }
pos = gzseek(file, -8L, SEEK_CUR); pos = gzseek(file, -8L, SEEK_CUR);
if (pos != 6 || gztell(file) != pos) { if (pos != 6 || gztell(file) != pos) {
fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
(long)pos, (long)gztell(file)); (long)pos, (long)gztell(file));
exit(1); exit(1);
} }
if (gzgetc(file) != ' ') { if (gzgetc(file) != ' ') {
fprintf(stderr, "gzgetc error\n"); fprintf(stderr, "gzgetc error\n");
exit(1); exit(1);
} }
gzgets(file, (char*)uncompr, uncomprLen); if (gzungetc(' ', file) != ' ') {
uncomprLen = strlen((char*)uncompr); fprintf(stderr, "gzungetc error\n");
if (uncomprLen != 6) { /* "hello!" */ exit(1);
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
exit(1);
} }
if (strcmp((char*)uncompr, hello+7)) {
gzgets(file, (char*)uncompr, (int)uncomprLen);
if (strlen((char*)uncompr) != 7) { /* " hello!" */
fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
exit(1);
}
if (strcmp((char*)uncompr, hello + 6)) {
fprintf(stderr, "bad gzgets after gzseek\n"); fprintf(stderr, "bad gzgets after gzseek\n");
exit(1); exit(1);
} else { } else {
printf("gzgets() after gzseek: %s\n", (char *)uncompr); printf("gzgets() after gzseek: %s\n", (char*)uncompr);
} }
gzclose(file); gzclose(file);
#endif
} }
/* =========================================================================== /* ===========================================================================
@ -167,7 +174,7 @@ void test_deflate(compr, comprLen)
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
int len = strlen(hello)+1; uLong len = (uLong)strlen(hello)+1;
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
@ -179,7 +186,7 @@ void test_deflate(compr, comprLen)
c_stream.next_in = (Bytef*)hello; c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr; c_stream.next_out = compr;
while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) { while (c_stream.total_in != len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH); err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
@ -231,7 +238,7 @@ void test_inflate(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) { if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate\n"); fprintf(stderr, "bad inflate\n");
exit(1); exit(1);
} else { } else {
printf("inflate(): %s\n", (char *)uncompr); printf("inflate(): %s\n", (char *)uncompr);
} }
@ -266,7 +273,7 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
if (c_stream.avail_in != 0) { if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n"); fprintf(stderr, "deflate not greedy\n");
exit(1); exit(1);
} }
/* Feed in already compressed data and switch to no compression: */ /* Feed in already compressed data and switch to no compression: */
@ -286,7 +293,7 @@ void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
err = deflate(&c_stream, Z_FINISH); err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) { if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n"); fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1); exit(1);
} }
err = deflateEnd(&c_stream); err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd"); CHECK_ERR(err, "deflateEnd");
@ -316,7 +323,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
for (;;) { for (;;) {
d_stream.next_out = uncompr; /* discard the output */ d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (uInt)uncomprLen; d_stream.avail_out = (uInt)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break; if (err == Z_STREAM_END) break;
CHECK_ERR(err, "large inflate"); CHECK_ERR(err, "large inflate");
@ -327,7 +334,7 @@ void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
if (d_stream.total_out != 2*uncomprLen + comprLen/2) { if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
exit(1); exit(1);
} else { } else {
printf("large_inflate(): OK\n"); printf("large_inflate(): OK\n");
} }
@ -342,7 +349,7 @@ void test_flush(compr, comprLen)
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
int len = strlen(hello)+1; uInt len = (uInt)strlen(hello)+1;
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
@ -407,7 +414,7 @@ void test_sync(compr, comprLen, uncompr, uncomprLen)
if (err != Z_DATA_ERROR) { if (err != Z_DATA_ERROR) {
fprintf(stderr, "inflate should report DATA_ERROR\n"); fprintf(stderr, "inflate should report DATA_ERROR\n");
/* Because of incorrect adler32 */ /* Because of incorrect adler32 */
exit(1); exit(1);
} }
err = inflateEnd(&d_stream); err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd"); CHECK_ERR(err, "inflateEnd");
@ -433,7 +440,7 @@ void test_dict_deflate(compr, comprLen)
CHECK_ERR(err, "deflateInit"); CHECK_ERR(err, "deflateInit");
err = deflateSetDictionary(&c_stream, err = deflateSetDictionary(&c_stream,
(const Bytef*)dictionary, sizeof(dictionary)); (const Bytef*)dictionary, sizeof(dictionary));
CHECK_ERR(err, "deflateSetDictionary"); CHECK_ERR(err, "deflateSetDictionary");
dictId = c_stream.adler; dictId = c_stream.adler;
@ -446,7 +453,7 @@ void test_dict_deflate(compr, comprLen)
err = deflate(&c_stream, Z_FINISH); err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) { if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n"); fprintf(stderr, "deflate should report Z_STREAM_END\n");
exit(1); exit(1);
} }
err = deflateEnd(&c_stream); err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd"); CHECK_ERR(err, "deflateEnd");
@ -480,14 +487,14 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
for (;;) { for (;;) {
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break; if (err == Z_STREAM_END) break;
if (err == Z_NEED_DICT) { if (err == Z_NEED_DICT) {
if (d_stream.adler != dictId) { if (d_stream.adler != dictId) {
fprintf(stderr, "unexpected dictionary"); fprintf(stderr, "unexpected dictionary");
exit(1); exit(1);
} }
err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
sizeof(dictionary)); sizeof(dictionary));
} }
CHECK_ERR(err, "inflate with dict"); CHECK_ERR(err, "inflate with dict");
} }
@ -496,7 +503,7 @@ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
if (strcmp((char*)uncompr, hello)) { if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate with dict\n"); fprintf(stderr, "bad inflate with dict\n");
exit(1); exit(1);
} else { } else {
printf("inflate with dictionary: %s\n", (char *)uncompr); printf("inflate with dictionary: %s\n", (char *)uncompr);
} }
@ -523,6 +530,9 @@ int main(argc, argv)
fprintf(stderr, "warning: different zlib version\n"); fprintf(stderr, "warning: different zlib version\n");
} }
printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
compr = (Byte*)calloc((uInt)comprLen, 1); compr = (Byte*)calloc((uInt)comprLen, 1);
uncompr = (Byte*)calloc((uInt)uncomprLen, 1); uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
/* compr and uncompr are cleared to avoid reading uninitialized /* compr and uncompr are cleared to avoid reading uninitialized
@ -530,13 +540,12 @@ int main(argc, argv)
*/ */
if (compr == Z_NULL || uncompr == Z_NULL) { if (compr == Z_NULL || uncompr == Z_NULL) {
printf("out of memory\n"); printf("out of memory\n");
exit(1); exit(1);
} }
test_compress(compr, comprLen, uncompr, uncomprLen); test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : TESTFILE), test_gzio((argc > 1 ? argv[1] : TESTFILE),
(argc > 2 ? argv[2] : TESTFILE), uncompr, uncomprLen);
uncompr, (int)uncomprLen);
test_deflate(compr, comprLen); test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen); test_inflate(compr, comprLen, uncompr, uncomprLen);
@ -551,6 +560,8 @@ int main(argc, argv)
test_dict_deflate(compr, comprLen); test_dict_deflate(compr, comprLen);
test_dict_inflate(compr, comprLen, uncompr, uncomprLen); test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
exit(0); free(compr);
return 0; /* to avoid warning */ free(uncompr);
return 0;
} }

View File

@ -1,8 +1,8 @@
/* gzio.c -- IO on .gz files /* gzio.c -- IO on .gz files
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
* *
* Compile this file with -DNO_DEFLATE to avoid the compression code. * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
@ -11,7 +11,13 @@
#include "zutil.h" #include "zutil.h"
#ifdef NO_DEFLATE /* for compatiblity with old definition */
# define NO_GZCOMPRESS
#endif
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif
#ifndef Z_BUFSIZE #ifndef Z_BUFSIZE
# ifdef MAXSEG_64K # ifdef MAXSEG_64K
@ -24,10 +30,20 @@ struct internal_state {int dummy;}; /* for buggy compilers */
# define Z_PRINTF_BUFSIZE 4096 # define Z_PRINTF_BUFSIZE 4096
#endif #endif
#ifdef __MVS__
# pragma map (fdopen , "\174\174FDOPEN")
FILE *fdopen(int, const char *);
#endif
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
#endif
#define ALLOC(size) malloc(size) #define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);} #define TRYFREE(p) {if (p) free(p);}
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
/* gzip flag byte */ /* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
@ -49,7 +65,11 @@ typedef struct gz_stream {
char *path; /* path name for debugging only */ char *path; /* path name for debugging only */
int transparent; /* 1 if input file is not a .gz file */ int transparent; /* 1 if input file is not a .gz file */
char mode; /* 'w' or 'r' */ char mode; /* 'w' or 'r' */
long startpos; /* start of compressed data in file (header skipped) */ z_off_t start; /* start of compressed data in file (header skipped) */
z_off_t in; /* bytes into deflate or inflate */
z_off_t out; /* bytes out of deflate or inflate */
int back; /* one character push-back */
int last; /* true if push-back is last character */
} gz_stream; } gz_stream;
@ -65,7 +85,7 @@ local uLong getLong OF((gz_stream *s));
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1). or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was gz_open returns NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
@ -97,6 +117,9 @@ local gzFile gz_open (path, mode, fd)
s->file = NULL; s->file = NULL;
s->z_err = Z_OK; s->z_err = Z_OK;
s->z_eof = 0; s->z_eof = 0;
s->in = 0;
s->out = 0;
s->back = EOF;
s->crc = crc32(0L, Z_NULL, 0); s->crc = crc32(0L, Z_NULL, 0);
s->msg = NULL; s->msg = NULL;
s->transparent = 0; s->transparent = 0;
@ -112,19 +135,21 @@ local gzFile gz_open (path, mode, fd)
if (*p == 'r') s->mode = 'r'; if (*p == 'r') s->mode = 'r';
if (*p == 'w' || *p == 'a') s->mode = 'w'; if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '0' && *p <= '9') { if (*p >= '0' && *p <= '9') {
level = *p - '0'; level = *p - '0';
} else if (*p == 'f') { } else if (*p == 'f') {
strategy = Z_FILTERED; strategy = Z_FILTERED;
} else if (*p == 'h') { } else if (*p == 'h') {
strategy = Z_HUFFMAN_ONLY; strategy = Z_HUFFMAN_ONLY;
} else { } else if (*p == 'R') {
*m++ = *p; /* copy the mode */ strategy = Z_RLE;
} } else {
*m++ = *p; /* copy the mode */
}
} while (*p++ && m != fmode + sizeof(fmode)); } while (*p++ && m != fmode + sizeof(fmode));
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
err = Z_STREAM_ERROR; err = Z_STREAM_ERROR;
#else #else
err = deflateInit2(&(s->stream), level, err = deflateInit2(&(s->stream), level,
@ -163,17 +188,17 @@ local gzFile gz_open (path, mode, fd)
*/ */
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
s->startpos = 10L; s->start = 10L;
/* We use 10L instead of ftell(s->file) to because ftell causes an /* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use * fflush on some systems. This version of the library doesn't use
* startpos anyway in write mode, so this initialization is not * start anyway in write mode, so this initialization is not
* necessary. * necessary.
*/ */
} else { } else {
check_header(s); /* skip the .gz header */ check_header(s); /* skip the .gz header */
s->startpos = (ftell(s->file) - s->stream.avail_in); s->start = ftell(s->file) - s->stream.avail_in;
} }
return (gzFile)s; return (gzFile)s;
} }
@ -218,11 +243,11 @@ int ZEXPORT gzsetparams (file, level, strategy)
/* Make room to allow flushing */ /* Make room to allow flushing */
if (s->stream.avail_out == 0) { if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf; s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO; s->z_err = Z_ERRNO;
} }
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
} }
return deflateParams (&(s->stream), level, strategy); return deflateParams (&(s->stream), level, strategy);
@ -238,14 +263,14 @@ local int get_byte(s)
{ {
if (s->z_eof) return EOF; if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
errno = 0; errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO; if (ferror(s->file)) s->z_err = Z_ERRNO;
return EOF; return EOF;
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
s->stream.avail_in--; s->stream.avail_in--;
return *(s->stream.next_in)++; return *(s->stream.next_in)++;
@ -268,43 +293,57 @@ local void check_header(s)
uInt len; uInt len;
int c; int c;
/* Check the gzip magic header */ /* Assure two bytes in the buffer so we can peek ahead -- handle case
for (len = 0; len < 2; len++) { where first byte of header is at the end of the buffer after the last
c = get_byte(s); gzip segment */
if (c != gz_magic[len]) { len = s->stream.avail_in;
if (len != 0) s->stream.avail_in++, s->stream.next_in--; if (len < 2) {
if (c != EOF) { if (len) s->inbuf[0] = s->stream.next_in[0];
s->stream.avail_in++, s->stream.next_in--; errno = 0;
s->transparent = 1; len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
} if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END; s->stream.avail_in += len;
return; s->stream.next_in = s->inbuf;
} if (s->stream.avail_in < 2) {
s->transparent = s->stream.avail_in;
return;
}
} }
/* Peek ahead to check the gzip magic header */
if (s->stream.next_in[0] != gz_magic[0] ||
s->stream.next_in[1] != gz_magic[1]) {
s->transparent = 1;
return;
}
s->stream.avail_in -= 2;
s->stream.next_in += 2;
/* Check the rest of the gzip header */
method = get_byte(s); method = get_byte(s);
flags = get_byte(s); flags = get_byte(s);
if (method != Z_DEFLATED || (flags & RESERVED) != 0) { if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
s->z_err = Z_DATA_ERROR; s->z_err = Z_DATA_ERROR;
return; return;
} }
/* Discard time, xflags and OS code: */ /* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++) (void)get_byte(s); for (len = 0; len < 6; len++) (void)get_byte(s);
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte(s); len = (uInt)get_byte(s);
len += ((uInt)get_byte(s))<<8; len += ((uInt)get_byte(s))<<8;
/* len is garbage if EOF but the loop below will quit anyway */ /* len is garbage if EOF but the loop below will quit anyway */
while (len-- != 0 && get_byte(s) != EOF) ; while (len-- != 0 && get_byte(s) != EOF) ;
} }
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = get_byte(s)) != 0 && c != EOF) ; while ((c = get_byte(s)) != 0 && c != EOF) ;
} }
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = get_byte(s)) != 0 && c != EOF) ; while ((c = get_byte(s)) != 0 && c != EOF) ;
} }
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
for (len = 0; len < 2; len++) (void)get_byte(s); for (len = 0; len < 2; len++) (void)get_byte(s);
} }
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
} }
@ -323,21 +362,21 @@ local int destroy (s)
TRYFREE(s->msg); TRYFREE(s->msg);
if (s->stream.state != NULL) { if (s->stream.state != NULL) {
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
err = Z_STREAM_ERROR; err = Z_STREAM_ERROR;
#else #else
err = deflateEnd(&(s->stream)); err = deflateEnd(&(s->stream));
#endif #endif
} else if (s->mode == 'r') { } else if (s->mode == 'r') {
err = inflateEnd(&(s->stream)); err = inflateEnd(&(s->stream));
} }
} }
if (s->file != NULL && fclose(s->file)) { if (s->file != NULL && fclose(s->file)) {
#ifdef ESPIPE #ifdef ESPIPE
if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
#endif #endif
err = Z_ERRNO; err = Z_ERRNO;
} }
if (s->z_err < 0) err = s->z_err; if (s->z_err < 0) err = s->z_err;
@ -370,71 +409,82 @@ int ZEXPORT gzread (file, buf, len)
s->stream.next_out = (Bytef*)buf; s->stream.next_out = (Bytef*)buf;
s->stream.avail_out = len; s->stream.avail_out = len;
if (s->stream.avail_out && s->back != EOF) {
*next_out++ = s->back;
s->stream.next_out++;
s->stream.avail_out--;
s->back = EOF;
s->out++;
if (s->last) {
s->z_err = Z_STREAM_END;
return 1;
}
}
while (s->stream.avail_out != 0) { while (s->stream.avail_out != 0) {
if (s->transparent) { if (s->transparent) {
/* Copy first the lookahead bytes: */ /* Copy first the lookahead bytes: */
uInt n = s->stream.avail_in; uInt n = s->stream.avail_in;
if (n > s->stream.avail_out) n = s->stream.avail_out; if (n > s->stream.avail_out) n = s->stream.avail_out;
if (n > 0) { if (n > 0) {
zmemcpy(s->stream.next_out, s->stream.next_in, n); zmemcpy(s->stream.next_out, s->stream.next_in, n);
next_out += n; next_out += n;
s->stream.next_out = next_out; s->stream.next_out = next_out;
s->stream.next_in += n; s->stream.next_in += n;
s->stream.avail_out -= n; s->stream.avail_out -= n;
s->stream.avail_in -= n; s->stream.avail_in -= n;
} }
if (s->stream.avail_out > 0) { if (s->stream.avail_out > 0) {
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
s->file); s->file);
} }
len -= s->stream.avail_out; len -= s->stream.avail_out;
s->stream.total_in += (uLong)len; s->in += len;
s->stream.total_out += (uLong)len; s->out += len;
if (len == 0) s->z_eof = 1; if (len == 0) s->z_eof = 1;
return (int)len; return (int)len;
} }
if (s->stream.avail_in == 0 && !s->z_eof) { if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0; errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (ferror(s->file)) { if (ferror(s->file)) {
s->z_err = Z_ERRNO; s->z_err = Z_ERRNO;
break; break;
} }
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
s->in += s->stream.avail_in;
s->out += s->stream.avail_out;
s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
s->in -= s->stream.avail_in;
s->out -= s->stream.avail_out;
if (s->z_err == Z_STREAM_END) { if (s->z_err == Z_STREAM_END) {
/* Check CRC and original size */ /* Check CRC and original size */
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
start = s->stream.next_out; start = s->stream.next_out;
if (getLong(s) != s->crc) { if (getLong(s) != s->crc) {
s->z_err = Z_DATA_ERROR; s->z_err = Z_DATA_ERROR;
} else { } else {
(void)getLong(s); (void)getLong(s);
/* The uncompressed length returned by above getlong() may /* The uncompressed length returned by above getlong() may be
* be different from s->stream.total_out) in case of * different from s->out in case of concatenated .gz files.
* concatenated .gz files. Check for such files: * Check for such files:
*/ */
check_header(s); check_header(s);
if (s->z_err == Z_OK) { if (s->z_err == Z_OK) {
uLong total_in = s->stream.total_in; inflateReset(&(s->stream));
uLong total_out = s->stream.total_out; s->crc = crc32(0L, Z_NULL, 0);
}
inflateReset(&(s->stream)); }
s->stream.total_in = total_in; }
s->stream.total_out = total_out; if (s->z_err != Z_OK || s->z_eof) break;
s->crc = crc32(0L, Z_NULL, 0);
}
}
}
if (s->z_err != Z_OK || s->z_eof) break;
} }
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
@ -455,6 +505,25 @@ int ZEXPORT gzgetc(file)
} }
/* ===========================================================================
Push one byte back onto the stream.
*/
int ZEXPORT gzungetc(c, file)
int c;
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
s->back = c;
s->out--;
s->last = (s->z_err == Z_STREAM_END);
if (s->last) s->z_err = Z_OK;
s->z_eof = 0;
return c;
}
/* =========================================================================== /* ===========================================================================
Reads bytes from the compressed file until len-1 characters are Reads bytes from the compressed file until len-1 characters are
read, or a newline character is read and transferred to buf, or an read, or a newline character is read and transferred to buf, or an
@ -478,14 +547,14 @@ char * ZEXPORT gzgets(file, buf, len)
} }
#ifndef NO_DEFLATE #ifndef NO_GZCOMPRESS
/* =========================================================================== /* ===========================================================================
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error). gzwrite returns the number of bytes actually written (0 in case of error).
*/ */
int ZEXPORT gzwrite (file, buf, len) int ZEXPORT gzwrite (file, buf, len)
gzFile file; gzFile file;
const voidp buf; voidpc buf;
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
@ -506,7 +575,11 @@ int ZEXPORT gzwrite (file, buf, len)
} }
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
} }
s->in += s->stream.avail_in;
s->out += s->stream.avail_out;
s->z_err = deflate(&(s->stream), Z_NO_FLUSH); s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
s->in -= s->stream.avail_in;
s->out -= s->stream.avail_out;
if (s->z_err != Z_OK) break; if (s->z_err != Z_OK) break;
} }
s->crc = crc32(s->crc, (const Bytef *)buf, len); s->crc = crc32(s->crc, (const Bytef *)buf, len);
@ -514,6 +587,7 @@ int ZEXPORT gzwrite (file, buf, len)
return (int)(len - s->stream.avail_in); return (int)(len - s->stream.avail_in);
} }
/* =========================================================================== /* ===========================================================================
Converts, formats, and writes the args to the compressed file under Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of control of the format string, as in fprintf. gzprintf returns the number of
@ -528,40 +602,67 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
va_list va; va_list va;
int len; int len;
buf[sizeof(buf) - 1] = 0;
va_start(va, format); va_start(va, format);
#ifdef HAS_vsnprintf #ifdef NO_vsnprintf
(void)vsnprintf(buf, sizeof(buf), format, va); # ifdef HAS_vsprintf_void
#else
(void)vsprintf(buf, format, va); (void)vsprintf(buf, format, va);
#endif
va_end(va); va_end(va);
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */ for (len = 0; len < sizeof(buf); len++)
if (len <= 0) return 0; if (buf[len] == 0) break;
# else
len = vsprintf(buf, format, va);
va_end(va);
# endif
#else
# ifdef HAS_vsnprintf_void
(void)vsnprintf(buf, sizeof(buf), format, va);
va_end(va);
len = strlen(buf);
# else
len = vsnprintf(buf, sizeof(buf), format, va);
va_end(va);
# endif
#endif
if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
return 0;
return gzwrite(file, buf, (unsigned)len); return gzwrite(file, buf, (unsigned)len);
} }
#else /* not ANSI C */ #else /* not ANSI C */
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) a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file; gzFile file;
const char *format; const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{ {
char buf[Z_PRINTF_BUFSIZE]; char buf[Z_PRINTF_BUFSIZE];
int len; int len;
#ifdef HAS_snprintf buf[sizeof(buf) - 1] = 0;
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, #ifdef NO_snprintf
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # ifdef HAS_sprintf_void
#else
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < sizeof(buf); len++)
if (buf[len] == 0) break;
# else
len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#else
# ifdef HAS_snprintf_void
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
len = strlen(buf);
# else
len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#endif #endif
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */ if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
if (len <= 0) return 0; return 0;
return gzwrite(file, buf, len); return gzwrite(file, buf, len);
} }
#endif #endif
@ -621,16 +722,18 @@ local int do_flush (file, flush)
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
} }
if (done) break; if (done) break;
s->out += s->stream.avail_out;
s->z_err = deflate(&(s->stream), flush); s->z_err = deflate(&(s->stream), flush);
s->out -= s->stream.avail_out;
/* Ignore the second of two consecutive flushes: */ /* Ignore the second of two consecutive flushes: */
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
/* deflate has finished flushing only when it hasn't used up /* deflate has finished flushing only when it hasn't used up
* all the available space in the output buffer: * all the available space in the output buffer:
*/ */
done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
} }
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
@ -647,7 +750,7 @@ int ZEXPORT gzflush (file, flush)
fflush(s->file); fflush(s->file);
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
} }
#endif /* NO_DEFLATE */ #endif /* NO_GZCOMPRESS */
/* =========================================================================== /* ===========================================================================
Sets the starting position for the next gzread or gzwrite on the given Sets the starting position for the next gzread or gzwrite on the given
@ -665,99 +768,105 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
if (s == NULL || whence == SEEK_END || if (s == NULL || whence == SEEK_END ||
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
return -1L; return -1L;
} }
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
return -1L; return -1L;
#else #else
if (whence == SEEK_SET) { if (whence == SEEK_SET) {
offset -= s->stream.total_in; offset -= s->in;
} }
if (offset < 0) return -1L; if (offset < 0) return -1L;
/* At this point, offset is the number of zero bytes to write. */ /* At this point, offset is the number of zero bytes to write. */
if (s->inbuf == Z_NULL) { if (s->inbuf == Z_NULL) {
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
zmemzero(s->inbuf, Z_BUFSIZE); if (s->inbuf == Z_NULL) return -1L;
} zmemzero(s->inbuf, Z_BUFSIZE);
while (offset > 0) { }
uInt size = Z_BUFSIZE; while (offset > 0) {
if (offset < Z_BUFSIZE) size = (uInt)offset; uInt size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (uInt)offset;
size = gzwrite(file, s->inbuf, size); size = gzwrite(file, s->inbuf, size);
if (size == 0) return -1L; if (size == 0) return -1L;
offset -= size; offset -= size;
} }
return (z_off_t)s->stream.total_in; return s->in;
#endif #endif
} }
/* Rest of function is for reading only */ /* Rest of function is for reading only */
/* compute absolute position */ /* compute absolute position */
if (whence == SEEK_CUR) { if (whence == SEEK_CUR) {
offset += s->stream.total_out; offset += s->out;
} }
if (offset < 0) return -1L; if (offset < 0) return -1L;
if (s->transparent) { if (s->transparent) {
/* map to fseek */ /* map to fseek */
s->stream.avail_in = 0; s->back = EOF;
s->stream.next_in = s->inbuf; s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
s->stream.total_in = s->stream.total_out = (uLong)offset; s->in = s->out = offset;
return offset; return offset;
} }
/* For a negative seek, rewind and use positive seek */ /* For a negative seek, rewind and use positive seek */
if ((uLong)offset >= s->stream.total_out) { if (offset >= s->out) {
offset -= s->stream.total_out; offset -= s->out;
} else if (gzrewind(file) < 0) { } else if (gzrewind(file) < 0) {
return -1L; return -1L;
} }
/* offset is now the number of bytes to skip. */ /* offset is now the number of bytes to skip. */
if (offset != 0 && s->outbuf == Z_NULL) { if (offset != 0 && s->outbuf == Z_NULL) {
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
if (s->outbuf == Z_NULL) return -1L;
}
if (offset && s->back != EOF) {
s->back = EOF;
s->out++;
offset--;
if (s->last) s->z_err = Z_STREAM_END;
} }
while (offset > 0) { while (offset > 0) {
int size = Z_BUFSIZE; int size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (int)offset; if (offset < Z_BUFSIZE) size = (int)offset;
size = gzread(file, s->outbuf, (uInt)size); size = gzread(file, s->outbuf, (uInt)size);
if (size <= 0) return -1L; if (size <= 0) return -1L;
offset -= size; offset -= size;
} }
return (z_off_t)s->stream.total_out; return s->out;
} }
/* =========================================================================== /* ===========================================================================
Rewinds input file. Rewinds input file.
*/ */
int ZEXPORT gzrewind (file) int ZEXPORT gzrewind (file)
gzFile file; gzFile file;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r') return -1; if (s == NULL || s->mode != 'r') return -1;
s->z_err = Z_OK; s->z_err = Z_OK;
s->z_eof = 0; s->z_eof = 0;
s->back = EOF;
s->stream.avail_in = 0; s->stream.avail_in = 0;
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
s->crc = crc32(0L, Z_NULL, 0); s->crc = crc32(0L, Z_NULL, 0);
if (!s->transparent) (void)inflateReset(&s->stream);
if (s->startpos == 0) { /* not a compressed file */ s->in = 0;
rewind(s->file); s->out = 0;
return 0; return fseek(s->file, s->start, SEEK_SET);
}
(void) inflateReset(&s->stream);
return fseek(s->file, s->startpos, SEEK_SET);
} }
/* =========================================================================== /* ===========================================================================
@ -779,8 +888,14 @@ int ZEXPORT gzeof (file)
gzFile file; gzFile file;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof; /* With concatenated compressed files that can have embedded
* crc trailers, z_eof is no longer the only/best indicator of EOF
* on a gz_stream. Handle end-of-stream error explicitly here.
*/
if (s == NULL || s->mode != 'r') return 0;
if (s->z_eof) return 1;
return s->z_err == Z_STREAM_END;
} }
/* =========================================================================== /* ===========================================================================
@ -828,14 +943,14 @@ int ZEXPORT gzclose (file)
if (s == NULL) return Z_STREAM_ERROR; if (s == NULL) return Z_STREAM_ERROR;
if (s->mode == 'w') { if (s->mode == 'w') {
#ifdef NO_DEFLATE #ifdef NO_GZCOMPRESS
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
#else #else
err = do_flush (file, Z_FINISH); err = do_flush (file, Z_FINISH);
if (err != Z_OK) return destroy((gz_stream*)file); if (err != Z_OK) return destroy((gz_stream*)file);
putLong (s->file, s->crc); putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in); putLong (s->file, (uLong)(s->in & 0xffffffff));
#endif #endif
} }
return destroy((gz_stream*)file); return destroy((gz_stream*)file);
@ -848,7 +963,7 @@ int ZEXPORT gzclose (file)
errnum is set to Z_ERRNO and the application may consult errno errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code. to get the exact error code.
*/ */
const char* ZEXPORT gzerror (file, errnum) const char * ZEXPORT gzerror (file, errnum)
gzFile file; gzFile file;
int *errnum; int *errnum;
{ {
@ -862,14 +977,29 @@ const char* ZEXPORT gzerror (file, errnum)
*errnum = s->z_err; *errnum = s->z_err;
if (*errnum == Z_OK) return (const char*)""; if (*errnum == Z_OK) return (const char*)"";
m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
TRYFREE(s->msg); TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
strcpy(s->msg, s->path); strcpy(s->msg, s->path);
strcat(s->msg, ": "); strcat(s->msg, ": ");
strcat(s->msg, m); strcat(s->msg, m);
return (const char*)s->msg; return (const char*)s->msg;
} }
/* ===========================================================================
Clear the error and end-of-file flags, and do the same for the real file.
*/
void ZEXPORT gzclearerr (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL) return;
if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
s->z_eof = 0;
clearerr(s->file);
}

619
lib/libz/infback.c Normal file
View File

@ -0,0 +1,619 @@
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
This code is largely copied from inflate.c. Normally either infback.o or
inflate.o would be linked into an application--not both. The interface
with inffast.c is retained so that optimized assembler-coded versions of
inflate_fast() can be used with either inflate.c or infback.c.
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
/* function prototypes */
local void fixedtables OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
Z_NULL to use the library memory allocation functions.
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_stream FAR *strm;
int windowBits;
unsigned char FAR *window;
const char *version;
int stream_size;
{
struct inflate_state FAR *state;
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != (int)(sizeof(z_stream)))
return Z_VERSION_ERROR;
if (strm == Z_NULL || window == Z_NULL ||
windowBits < 8 || windowBits > 15)
return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
strm->zalloc = zcalloc;
strm->opaque = (voidpf)0;
}
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
sizeof(struct inflate_state));
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (voidpf)state;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
state->write = 0;
state->whave = 0;
return Z_OK;
}
/*
Return state with length and distance decoding tables and index sizes set to
fixed code decoding. Normally this returns fixed tables from inffixed.h.
If BUILDFIXED is defined, then instead this routine builds the tables the
first time it's called, and returns those tables the first time and
thereafter. This reduces the size of the code by about 2K bytes, in
exchange for a little execution time. However, BUILDFIXED should not be
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
static code fixed[544];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
unsigned sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
/* do this just once */
virgin = 0;
}
#else /* !BUILDFIXED */
# include "inffixed.h"
#endif /* BUILDFIXED */
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
/* Macros for inflateBack(): */
/* Load returned state from inflate_fast() */
#define LOAD() \
do { \
put = strm->next_out; \
left = strm->avail_out; \
next = strm->next_in; \
have = strm->avail_in; \
hold = state->hold; \
bits = state->bits; \
} while (0)
/* Set state from registers for inflate_fast() */
#define RESTORE() \
do { \
strm->next_out = put; \
strm->avail_out = left; \
strm->next_in = next; \
strm->avail_in = have; \
state->hold = hold; \
state->bits = bits; \
} while (0)
/* Clear the input bit accumulator */
#define INITBITS() \
do { \
hold = 0; \
bits = 0; \
} while (0)
/* Assure that some input is available. If input is requested, but denied,
then return a Z_BUF_ERROR from inflateBack(). */
#define PULL() \
do { \
if (have == 0) { \
have = in(in_desc, &next); \
if (have == 0) { \
next = Z_NULL; \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/* Get a byte of input into the bit accumulator, or return from inflateBack()
with an error if there is no input available. */
#define PULLBYTE() \
do { \
PULL(); \
have--; \
hold += (unsigned long)(*next++) << bits; \
bits += 8; \
} while (0)
/* Assure that there are at least n bits in the bit accumulator. If there is
not enough available input to do that, then return from inflateBack() with
an error. */
#define NEEDBITS(n) \
do { \
while (bits < (unsigned)(n)) \
PULLBYTE(); \
} while (0)
/* Return the low n bits of the bit accumulator (n < 16) */
#define BITS(n) \
((unsigned)hold & ((1U << (n)) - 1))
/* Remove n bits from the bit accumulator */
#define DROPBITS(n) \
do { \
hold >>= (n); \
bits -= (unsigned)(n); \
} while (0)
/* Remove zero to seven bits as needed to go to a byte boundary */
#define BYTEBITS() \
do { \
hold >>= bits & 7; \
bits -= bits & 7; \
} while (0)
/* Assure that some output space is available, by writing out the window
if it's full. If the write fails, return from inflateBack() with a
Z_BUF_ERROR. */
#define ROOM() \
do { \
if (left == 0) { \
put = state->window; \
left = state->wsize; \
state->whave = left; \
if (out(out_desc, put, left)) { \
ret = Z_BUF_ERROR; \
goto inf_leave; \
} \
} \
} while (0)
/*
strm provides the memory allocation functions and window buffer on input,
and provides information on the unused input on return. For Z_DATA_ERROR
returns, strm will also provide an error message.
in() and out() are the call-back input and output functions. When
inflateBack() needs more input, it calls in(). When inflateBack() has
filled the window with output, or when it completes with data in the
window, it calls out() to write out the data. The application must not
change the provided input until in() is called again or inflateBack()
returns. The application must not change the window/output buffer until
inflateBack() returns.
in() and out() are called with a descriptor parameter provided in the
inflateBack() call. This parameter can be a structure that provides the
information required to do the read or write, as well as accumulated
information on the input and output such as totals and check values.
in() should return zero on failure. out() should return non-zero on
failure. If either in() or out() fails, than inflateBack() returns a
Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
was in() or out() that caused in the error. Otherwise, inflateBack()
returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
error, or Z_MEM_ERROR if it could not allocate memory for the state.
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_stream FAR *strm;
in_func in;
void FAR *in_desc;
out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
unsigned bits; /* bits in bit buffer */
unsigned copy; /* number of stored or match bytes to copy */
unsigned char FAR *from; /* where to copy match bytes from */
code this; /* current decoding table entry */
code last; /* parent table entry */
unsigned len; /* length to copy for repeats, bits to drop */
int ret; /* return code */
static const unsigned short order[19] = /* permutation of code lengths */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* Check that the strm exists and that the state was initialized */
if (strm == Z_NULL || strm->state == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* Reset the state */
strm->msg = Z_NULL;
state->mode = TYPE;
state->last = 0;
state->whave = 0;
next = strm->next_in;
have = next != Z_NULL ? strm->avail_in : 0;
hold = 0;
bits = 0;
put = state->window;
left = state->wsize;
/* Inflate until end of block marked as last */
for (;;)
switch (state->mode) {
case TYPE:
/* determine and dispatch block type */
if (state->last) {
BYTEBITS();
state->mode = DONE;
break;
}
NEEDBITS(3);
state->last = BITS(1);
DROPBITS(1);
switch (BITS(2)) {
case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n",
state->last ? " (last)" : ""));
state->mode = STORED;
break;
case 1: /* fixed block */
fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n",
state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */
break;
case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n",
state->last ? " (last)" : ""));
state->mode = TABLE;
break;
case 3:
strm->msg = (char *)"invalid block type";
state->mode = BAD;
}
DROPBITS(2);
break;
case STORED:
/* get and verify stored block length */
BYTEBITS(); /* go to byte boundary */
NEEDBITS(32);
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
strm->msg = (char *)"invalid stored block lengths";
state->mode = BAD;
break;
}
state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n",
state->length));
INITBITS();
/* copy stored block from input to output */
while (state->length != 0) {
copy = state->length;
PULL();
ROOM();
if (copy > have) copy = have;
if (copy > left) copy = left;
zmemcpy(put, next, copy);
have -= copy;
next += copy;
left -= copy;
put += copy;
state->length -= copy;
}
Tracev((stderr, "inflate: stored end\n"));
state->mode = TYPE;
break;
case TABLE:
/* get dynamic table entries descriptor */
NEEDBITS(14);
state->nlen = BITS(5) + 257;
DROPBITS(5);
state->ndist = BITS(5) + 1;
DROPBITS(5);
state->ncode = BITS(4) + 4;
DROPBITS(4);
#ifndef PKZIP_BUG_WORKAROUND
if (state->nlen > 286 || state->ndist > 30) {
strm->msg = (char *)"too many length or distance symbols";
state->mode = BAD;
break;
}
#endif
Tracev((stderr, "inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */
state->have = 0;
while (state->have < state->ncode) {
NEEDBITS(3);
state->lens[order[state->have++]] = (unsigned short)BITS(3);
DROPBITS(3);
}
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid code lengths set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: code lengths ok\n"));
/* get length and distance code code lengths */
state->have = 0;
while (state->have < state->nlen + state->ndist) {
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.val < 16) {
NEEDBITS(this.bits);
DROPBITS(this.bits);
state->lens[state->have++] = this.val;
}
else {
if (this.val == 16) {
NEEDBITS(this.bits + 2);
DROPBITS(this.bits);
if (state->have == 0) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
len = (unsigned)(state->lens[state->have - 1]);
copy = 3 + BITS(2);
DROPBITS(2);
}
else if (this.val == 17) {
NEEDBITS(this.bits + 3);
DROPBITS(this.bits);
len = 0;
copy = 3 + BITS(3);
DROPBITS(3);
}
else {
NEEDBITS(this.bits + 7);
DROPBITS(this.bits);
len = 0;
copy = 11 + BITS(7);
DROPBITS(7);
}
if (state->have + copy > state->nlen + state->ndist) {
strm->msg = (char *)"invalid bit length repeat";
state->mode = BAD;
break;
}
while (copy--)
state->lens[state->have++] = (unsigned short)len;
}
}
/* build code tables */
state->next = state->codes;
state->lencode = (code const FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
if (ret) {
strm->msg = (char *)"invalid literal/lengths set";
state->mode = BAD;
break;
}
state->distcode = (code const FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
if (ret) {
strm->msg = (char *)"invalid distances set";
state->mode = BAD;
break;
}
Tracev((stderr, "inflate: codes ok\n"));
state->mode = LEN;
case LEN:
/* use inflate_fast() if we have enough input and output */
if (have >= 6 && left >= 258) {
RESTORE();
if (state->whave < state->wsize)
state->whave = state->wsize - left;
inflate_fast(strm, state->wsize);
LOAD();
break;
}
/* get a literal, length, or end-of-block code */
for (;;) {
this = state->lencode[BITS(state->lenbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if (this.op && (this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->lencode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
state->length = (unsigned)this.val;
/* process literal */
if (this.op == 0) {
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
ROOM();
*put++ = (unsigned char)(state->length);
left--;
state->mode = LEN;
break;
}
/* process end of block */
if (this.op & 32) {
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
/* invalid code */
if (this.op & 64) {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
/* length code -- get extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->length += BITS(state->extra);
DROPBITS(state->extra);
}
Tracevv((stderr, "inflate: length %u\n", state->length));
/* get distance code */
for (;;) {
this = state->distcode[BITS(state->distbits)];
if ((unsigned)(this.bits) <= bits) break;
PULLBYTE();
}
if ((this.op & 0xf0) == 0) {
last = this;
for (;;) {
this = state->distcode[last.val +
(BITS(last.bits + last.op) >> last.bits)];
if ((unsigned)(last.bits + this.bits) <= bits) break;
PULLBYTE();
}
DROPBITS(last.bits);
}
DROPBITS(this.bits);
if (this.op & 64) {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
state->offset = (unsigned)this.val;
/* get distance extra bits, if any */
state->extra = (unsigned)(this.op) & 15;
if (state->extra != 0) {
NEEDBITS(state->extra);
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
if (state->offset > state->wsize - (state->whave < state->wsize ?
left : 0)) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
Tracevv((stderr, "inflate: distance %u\n", state->offset));
/* copy match from window to output */
do {
ROOM();
copy = state->wsize - state->offset;
if (copy < left) {
from = put + copy;
copy = left - copy;
}
else {
from = put - state->offset;
copy = left;
}
if (copy > state->length) copy = state->length;
state->length -= copy;
left -= copy;
do {
*put++ = *from++;
} while (--copy);
} while (state->length != 0);
break;
case DONE:
/* inflate stream terminated properly -- write leftover output */
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 */
ret = Z_STREAM_ERROR;
goto inf_leave;
}
/* Return unused input */
inf_leave:
strm->next_in = next;
strm->avail_in = have;
return ret;
}
int ZEXPORT inflateBackEnd(strm)
z_stream FAR *strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}

View File

@ -1,183 +1,305 @@
/* inffast.c -- process literals and length/distance pairs fast /* inffast.c -- fast decoding
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
#include "infblock.h" #include "inflate.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h" #include "inffast.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #ifndef ASMINF
/* simplify the use of the inflate_huft type with some defines */ /* Allow machine dependent optimization for post-increment or pre-increment.
#define exop word.what.Exop Based on testing to date,
#define bits word.what.Bits Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- 68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define OFF 1
# define PUP(a) *++(a)
#endif
/* macros for bit input with no checking and for returning unused bytes */ /*
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} Decode literal, length, and distance codes and write out the resulting
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
/* Called with number of bytes left to write in window at least 258 Entry assumptions:
(the maximum string length) and number of input bytes available
at least ten. The ten bytes are six bytes for the longest length/
distance pair plus four bytes for overloading the bit buffer. */
int inflate_fast(bl, bd, tl, td, s, z) state->mode == LEN
uInt bl, bd; strm->avail_in >= 6
inflate_huft *tl; strm->avail_out >= 258
inflate_huft *td; /* need separate declaration for Borland C++ */ start >= strm->avail_out
inflate_blocks_statef *s; state->bits < 8
z_streamp z;
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{ {
inflate_huft *t; /* temporary pointer */ struct inflate_state FAR *state;
uInt e; /* extra bits or operation */ unsigned char FAR *in; /* local strm->next_in */
uLong b; /* bit buffer */ unsigned char FAR *last; /* while in < last, enough input available */
uInt k; /* bits in bit buffer */ unsigned char FAR *out; /* local strm->next_out */
Bytef *p; /* input data pointer */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
uInt n; /* bytes available there */ unsigned char FAR *end; /* while out < end, enough space available */
Bytef *q; /* output window write pointer */ unsigned wsize; /* window size or zero if not using window */
uInt m; /* bytes to end of window or read pointer */ unsigned whave; /* valid bytes in the window */
uInt ml; /* mask for literal/length tree */ unsigned write; /* window write index */
uInt md; /* mask for distance tree */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
uInt c; /* bytes to copy */ unsigned long hold; /* local strm->hold */
uInt d; /* distance back to copy from */ unsigned bits; /* local strm->bits */
Bytef *r; /* copy source pointer */ code const FAR *lcode; /* local strm->lencode */
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 this; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
unsigned dist; /* match distance */
unsigned char FAR *from; /* where to copy match from */
/* load input, output, bit values */ /* copy state to local variables */
LOAD state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
wsize = state->wsize;
whave = state->whave;
write = state->write;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* initialize masks */ /* decode literals and length/distances until end-of-block or not enough
ml = inflate_mask[bl]; input data or output space */
md = inflate_mask[bd];
/* do until not enough input or output space for fast loop */
do { /* assume called with m >= 258 && n >= 10 */
/* get literal/length code */
GRABBITS(20) /* max bits for literal/length code */
if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
continue;
}
do { do {
DUMPBITS(t->bits) if (bits < 15) {
if (e & 16) hold += (unsigned long)(PUP(in)) << bits;
{ bits += 8;
/* get extra bits for length */ hold += (unsigned long)(PUP(in)) << bits;
e &= 15; bits += 8;
c = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * length %u\n", c));
/* decode distance base of block to copy */
GRABBITS(15); /* max bits for distance code */
e = (t = td + ((uInt)b & md))->exop;
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits to add to distance base */
e &= 15;
GRABBITS(e) /* get extra bits (up to 13) */
d = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * distance %u\n", d));
/* do the copy */
m -= c;
r = q - d;
if (r < s->window) /* wrap if needed */
{
do {
r += s->end - s->window; /* force pointer in window */
} while (r < s->window); /* covers invalid distances */
e = s->end - r;
if (c > e)
{
c -= e; /* wrapped copy */
do {
*q++ = *r++;
} while (--e);
r = s->window;
do {
*q++ = *r++;
} while (--c);
}
else /* normal copy */
{
*q++ = *r++; c--;
*q++ = *r++; c--;
do {
*q++ = *r++;
} while (--c);
}
}
else /* normal copy */
{
*q++ = *r++; c--;
*q++ = *r++; c--;
do {
*q++ = *r++;
} while (--c);
}
break;
}
else if ((e & 64) == 0)
{
t += t->base;
e = (t += ((uInt)b & inflate_mask[e]))->exop;
}
else
{
z->msg = (char*)"invalid distance code";
UNGRAB
UPDATE
return Z_DATA_ERROR;
}
} while (1);
break;
}
if ((e & 64) == 0)
{
t += t->base;
if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
break;
} }
} this = lcode[hold & lmask];
else if (e & 32) dolen:
{ op = (unsigned)(this.bits);
Tracevv((stderr, "inflate: * end of block\n")); hold >>= op;
UNGRAB bits -= op;
UPDATE op = (unsigned)(this.op);
return Z_STREAM_END; if (op == 0) { /* literal */
} Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
else "inflate: literal '%c'\n" :
{ "inflate: literal 0x%02x\n", this.val));
z->msg = (char*)"invalid literal/length code"; PUP(out) = (unsigned char)(this.val);
UNGRAB }
UPDATE else if (op & 16) { /* length base */
return Z_DATA_ERROR; len = (unsigned)(this.val);
} op &= 15; /* number of extra bits */
} while (1); if (op) {
} while (m >= 258 && n >= 10); if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
this = dcode[hold & dmask];
dodist:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
if (op & 16) { /* distance base */
dist = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
from = window - OFF;
if (write == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += write - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
this = dcode[this.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD;
break;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
this = lcode[this.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
state->mode = TYPE;
break;
}
else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD;
break;
}
} while (in < last && out < end);
/* not enough input or output--restore pointers and return */ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
UNGRAB len = bits >> 3;
UPDATE in -= len;
return Z_OK; bits -= len << 3;
hold &= (1U << bits) - 1;
/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
} }
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */

View File

@ -1,6 +1,6 @@
/* inffast.h -- header to use inffast.c /* inffast.h -- header to use inffast.c
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* WARNING: this file should *not* be used by applications. It is /* WARNING: this file should *not* be used by applications. It is
@ -8,10 +8,4 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
extern int inflate_fast OF(( void inflate_fast OF((z_streamp strm, unsigned start));
uInt,
uInt,
inflate_huft *,
inflate_huft *,
inflate_blocks_statef *,
z_streamp ));

View File

@ -1,151 +1,94 @@
/* inffixed.h -- table for decoding fixed codes /* inffixed.h -- table for decoding fixed codes
* Generated automatically by the maketree.c program * Generated automatically by makefixed().
*/ */
/* WARNING: this file should *not* be used by applications. It is /* WARNING: this file should *not* be used by applications. It
part of the implementation of the compression library and is is part of the implementation of the compression library and
subject to change. Applications should only use zlib.h. is subject to change. Applications should only use zlib.h.
*/ */
local uInt fixed_bl = 9; static const code lenfix[512] = {
local uInt fixed_bd = 5; {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
local inflate_huft fixed_tl[] = { {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, {0,9,255}
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, };
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, static const code distfix[32] = {
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, {22,5,193},{64,5,0}
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, };
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
};
local inflate_huft fixed_td[] = {
{{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
{{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
{{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
{{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
{{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
{{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
{{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
{{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
};

File diff suppressed because it is too large Load Diff

117
lib/libz/inflate.h Normal file
View File

@ -0,0 +1,117 @@
/* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* define NO_GZIP when compiling if you want to disable gzip header and
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
# define GUNZIP
#endif
/* Possible inflate modes between inflate() calls */
typedef enum {
HEAD, /* i: waiting for magic header */
#ifdef GUNZIP
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
#endif
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN, /* i: waiting for length/lit code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
#ifdef GUNZIP
LENGTH, /* i: waiting for 32-bit length (gzip) */
#endif
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
State transitions between above modes -
(most modes can go to the BAD or MEM mode -- not shown for clarity)
Process header:
HEAD -> (gzip) or (zlib)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
NAME -> COMMENT -> HCRC -> TYPE
(zlib) -> DICTID or TYPE
DICTID -> DICT -> TYPE
Read deflate blocks:
TYPE -> STORED or TABLE or LEN or CHECK
STORED -> COPY -> TYPE
TABLE -> LENLENS -> CODELENS -> LEN
Read deflate codes:
LEN -> LENEXT or LIT or TYPE
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
LIT -> LEN
Process trailer:
CHECK -> LENGTH -> DONE
*/
/* state maintained between inflate() calls. Approximately 7K bytes. */
struct inflate_state {
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
};

View File

@ -1,454 +1,321 @@
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
#if !defined(BUILDFIXED) && !defined(STDC) #define MAXBITS 15
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif
const char inflate_copyright[] = const char inflate_copyright[] =
" inflate 1.1.4 Copyright 1995-2002 Mark Adler "; " inflate 1.2.1 Copyright 1995-2003 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome 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 in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product. copyright string in the executable of your product.
*/ */
struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
local int huft_build OF((
uIntf *, /* code lengths in bits */
uInt, /* number of codes */
uInt, /* number of "simple" codes */
const uIntf *, /* list of base values for non-simple codes */
const uIntf *, /* list of extra bits for non-simple codes */
inflate_huft * FAR*,/* result: starting table */
uIntf *, /* maximum lookup bits (returns actual) */
inflate_huft *, /* space for trees */
uInt *, /* hufts used in space */
uIntf * )); /* space for values */
/* Tables for deflate from PKZIP's appnote.txt. */
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* see note #13 above about 258 */
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
local const uInt cpdext[30] = { /* Extra bits for distance codes */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
/* /*
Huffman code decoding is performed using a multi-level table lookup. Build a set of tables to decode the provided canonical Huffman code.
The fastest way to decode is to simply build a lookup table whose The code lengths are lens[0..codes-1]. The result starts at *table,
size is determined by the longest code. However, the time it takes whose indices are 0..2^bits-1. work is a writable array of at least
to build this table can also be a factor if the data being decoded lens shorts, which is used as a work area. type is the type of code
is not very long. The most common codes are necessarily the to be generated, CODES, LENS, or DISTS. On return, zero is success,
shortest codes, so those codes dominate the decoding time, and hence -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
the speed. The idea is you can have a shorter table that decodes the on return points to the next available entry's address. bits is the
shorter, more probable codes, and then point to subsidiary tables for requested root table index bits, and on return it is the actual root
the longer codes. The time it costs to decode the longer codes is table index bits. It will differ if the request is greater than the
then traded against the time it takes to make longer tables. longest code or if it is less than the shortest code.
This results of this trade are in the variables lbits and dbits
below. lbits is the number of bits the first level table for literal/
length codes can decode in one step, and dbits is the same thing for
the distance codes. Subsequent tables are also less than or equal to
those sizes. These values may be adjusted either when all of the
codes are shorter than that, in which case the longest code length in
bits is used, or when the shortest code is *longer* than the requested
table size, in which case the length of the shortest code in bits is
used.
There are two different values for the two tables, since they code a
different number of possibilities each. The literal/length table
codes 286 possible values, or in a flat code, a little over eight
bits. The distance table codes 30 possible values, or a little less
than five bits, flat. The optimum values for speed end up being
about one bit more than those, so lbits is 8+1 and dbits is 5+1.
The optimum values may differ though from machine to machine, and
possibly even between compilers. Your mileage may vary.
*/ */
int inflate_table(type, lens, codes, table, bits, work)
codetype type;
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ unsigned short FAR *lens;
#define BMAX 15 /* maximum bit length of any code */ unsigned codes;
code FAR * FAR *table;
local int huft_build(b, n, s, d, e, t, m, hp, hn, v) unsigned FAR *bits;
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ unsigned short FAR *work;
uInt n; /* number of codes (assumed <= 288) */
uInt s; /* number of simple-valued codes (0..s-1) */
const uIntf *d; /* list of base values for non-simple codes */
const uIntf *e; /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */
inflate_huft *hp; /* space for trees */
uInt *hn; /* hufts used in space */
uIntf *v; /* working area: values in order of bit length */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this
case), or Z_DATA_ERROR if the input is invalid. */
{ {
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */
unsigned min, max; /* minimum and maximum code lengths */
unsigned root; /* number of index bits for root table */
unsigned curr; /* number of index bits for current table */
unsigned drop; /* code bits to drop for sub-table */
int left; /* number of prefix codes available */
unsigned used; /* code entries in table used */
unsigned huff; /* Huffman code */
unsigned incr; /* for incrementing code, index */
unsigned fill; /* index for replicating entries */
unsigned low; /* low bits for current root entry */
unsigned mask; /* mask for low root bits */
code this; /* table entry for duplication */
code FAR *next; /* next available space in table */
const unsigned short FAR *base; /* base value table to use */
const unsigned short FAR *extra; /* extra bits table to use */
int end; /* use base and extra for symbol > end */
unsigned short count[MAXBITS+1]; /* number of codes of each length */
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 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, 76, 66};
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,
8193, 12289, 16385, 24577, 0, 0};
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
28, 28, 29, 29, 64, 64};
uInt a; /* counter for codes of length k */ /*
uInt c[BMAX+1]; /* bit length count table */ Process a set of code lengths to create a canonical Huffman code. The
uInt f; /* i repeats in table every f entries */ code lengths are lens[0..codes-1]. Each length corresponds to the
int g; /* maximum code length */ symbols 0..codes-1. The Huffman code is generated by first sorting the
int h; /* table level */ symbols by length from short to long, and retaining the symbol order
register uInt i; /* counter, current code */ for codes with equal lengths. Then the code starts with all zero bits
register uInt j; /* counter */ for the first code of the shortest length, and the codes are integer
register int k; /* number of bits in current code */ increments for the same length, and zeros are appended as the length
int l; /* bits per table (returned in m) */ increases. For the deflate format, these bits are stored backwards
uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ from their more natural integer increment ordering, and so when the
register uIntf *p; /* pointer into c[], b[], or v[] */ decoding tables are built in the large loop below, the integer codes
inflate_huft *q; /* points to current table */ are incremented backwards.
struct inflate_huft_s r; /* table entry for structure assignment */
inflate_huft *u[BMAX]; /* table stack */
register int w; /* bits before this table == (l * h) */
uInt x[BMAX+1]; /* bit offsets, then code stack */
uIntf *xp; /* pointer into x */
int y; /* number of dummy codes added */
uInt z; /* number of entries in current table */
This routine assumes, but does not check, that all of the entries in
lens[] are in the range 0..MAXBITS. The caller must assure this.
1..MAXBITS is interpreted as that code length. zero means that that
symbol does not occur in this code.
/* Generate counts for each bit length */ The codes are sorted by computing a count of codes for each length,
p = c; creating from that a table of starting indices for each length in the
#define C0 *p++ = 0; sorted table, and then entering the symbols in order in the sorted
#define C2 C0 C0 C0 C0 table. The sorted table is work[], with that space being provided by
#define C4 C2 C2 C2 C2 the caller.
C4 /* clear c[]--assume BMAX+1 is 16 */
p = b; i = n;
do {
c[*p++]++; /* assume all entries <= BMAX */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (inflate_huft *)Z_NULL;
*m = 0;
return Z_OK;
}
The length counts are used for other purposes as well, i.e. finding
the minimum and maximum length codes, determining if there are any
codes at all, checking for a valid set of lengths, and looking ahead
at length counts to determine sub-table sizes when building the
decoding tables.
*/
/* Find minimum and maximum length, bound *m by those */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
l = *m; for (len = 0; len <= MAXBITS; len++)
for (j = 1; j <= BMAX; j++) count[len] = 0;
if (c[j]) for (sym = 0; sym < codes; sym++)
break; count[lens[sym]]++;
k = j; /* minimum code length */
if ((uInt)l < j)
l = j;
for (i = BMAX; i; i--)
if (c[i])
break;
g = i; /* maximum code length */
if ((uInt)l > i)
l = i;
*m = l;
/* bound code lengths, force root to be within code lengths */
root = *bits;
for (max = MAXBITS; max >= 1; max--)
if (count[max] != 0) break;
if (root > max) root = max;
if (max == 0) return -1; /* no codes! */
for (min = 1; min <= MAXBITS; min++)
if (count[min] != 0) break;
if (root < min) root = min;
/* Adjust last length count to fill out codes, if needed */ /* check for an over-subscribed or incomplete set of lengths */
for (y = 1 << j; j < i; j++, y <<= 1) left = 1;
if ((y -= c[j]) < 0) for (len = 1; len <= MAXBITS; len++) {
return Z_DATA_ERROR; left <<= 1;
if ((y -= c[i]) < 0) left -= count[len];
return Z_DATA_ERROR; if (left < 0) return -1; /* over-subscribed */
c[i] += y; }
if (left > 0 && (type == CODES || (codes - count[0] != 1)))
return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + count[len];
/* Generate starting offsets into the value table for each length */ /* sort symbols by length, by symbol order within each length */
x[1] = j = 0; for (sym = 0; sym < codes; sym++)
p = c + 1; xp = x + 2; if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
}
/*
Create and fill in decoding tables. In this loop, the table being
filled is at next and has curr index bits. The code being used is huff
with length len. That code is converted to an index by dropping drop
bits off of the bottom. For codes where len is less than drop + curr,
those top drop + curr - len bits are incremented through all values to
fill the table with replicated entries.
/* Make a table of values in order of bit lengths */ root is the number of index bits for the root table. When len exceeds
p = b; i = 0; root, sub-tables are created pointed to by the root entry with an index
do { of the low root bits of huff. This is saved in low to check for when a
if ((j = *p++) != 0) new sub-table should be started. drop is zero when the root table is
v[x[j]++] = i; being filled, and drop is root when sub-tables are being filled.
} while (++i < n);
n = x[g]; /* set n to length of v */
When a new sub-table is needed, it is necessary to look ahead in the
code lengths to determine what size sub-table is needed. The length
counts are used for this, and so count[] is decremented as codes are
entered in the tables.
/* Generate the Huffman codes and for each, make the table entries */ used keeps track of how many table entries have been allocated from the
x[0] = i = 0; /* first Huffman code is zero */ provided *table space. It is checked when a LENS table is being made
p = v; /* grab values in bit order */ against the space in *table, ENOUGH, minus the maximum space needed by
h = -1; /* no tables yet--level -1 */ the worst case distance code, MAXD. This should never happen, but the
w = -l; /* bits decoded == (l * h) */ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ This assumes that when type == LENS, bits == 9.
q = (inflate_huft *)Z_NULL; /* ditto */
z = 0; /* ditto */
/* go through the bit lengths (k already is bits in shortest code) */ sym increments through all symbols, and the loop terminates when
for (; k <= g; k++) all codes of length max, i.e. all codes, have been processed. This
{ routine permits incomplete codes, so another loop after this one fills
a = c[k]; in the rest of the decoding tables with invalid code markers.
while (a--) */
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */ /* set up for code type */
z = g - w; switch (type) {
z = z > (uInt)l ? l : z; /* table size upper limit */ case CODES:
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ base = extra = work; /* dummy value--not used */
{ /* too few codes for k-w bit table */ end = 19;
f -= a + 1; /* deduct codes from patterns left */ break;
xp = c + k; case LENS:
if (j < z) base = lbase;
while (++j < z) /* try smaller tables up to z bits */ base -= 257;
{ extra = lext;
if ((f <<= 1) <= *++xp) extra -= 257;
break; /* enough codes to use up j bits */ end = 256;
f -= *xp; /* else deduct codes from patterns */ break;
} default: /* DISTS */
base = dbase;
extra = dext;
end = -1;
}
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* check available table space */
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* process all codes and make table entries */
for (;;) {
/* create table entry */
this.bits = (unsigned char)(len - drop);
if ((int)(work[sym]) < end) {
this.op = (unsigned char)0;
this.val = work[sym];
}
else if ((int)(work[sym]) > end) {
this.op = (unsigned char)(extra[work[sym]]);
this.val = base[work[sym]];
}
else {
this.op = (unsigned char)(32 + 64); /* end of block */
this.val = 0;
} }
z = 1 << j; /* table entries for j-bit table */
/* allocate new table */ /* replicate for those indices with low len bits equal to huff */
if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ incr = 1U << (len - drop);
return Z_DATA_ERROR; /* overflow of MANY */ fill = 1U << curr;
u[h] = q = hp + *hn; do {
*hn += z; fill -= incr;
next[(huff >> drop) + fill] = this;
} while (fill != 0);
/* connect to last table, if there is one */ /* backwards increment the len-bit code huff */
if (h) incr = 1U << (len - 1);
{ while (huff & incr)
x[h] = i; /* save pattern for backing up */ incr >>= 1;
r.bits = (Byte)l; /* bits to dump before this table */ if (incr != 0) {
r.exop = (Byte)j; /* bits in this table */ huff &= incr - 1;
j = i >> (w - l); huff += incr;
r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
u[h-1][j] = r; /* connect to last table */
} }
else else
*t = q; /* first table is returned result */ huff = 0;
}
/* set up table entry in r */ /* go to next symbol, update count, len */
r.bits = (Byte)(k - w); sym++;
if (p >= v + n) if (--(count[len]) == 0) {
r.exop = 128 + 64; /* out of values--invalid code */ if (len == max) break;
else if (*p < s) len = lens[work[sym]];
{ }
r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
r.base = *p++; /* simple code is just the value */
}
else
{
r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
r.base = d[*p++ - s];
}
/* fill code-like entries with r */ /* create new sub-table if needed */
f = 1 << (k - w); if (len > root && (huff & mask) != low) {
for (j = i >> w; j < z; j += f) /* if first time, transition to sub-tables */
q[j] = r; if (drop == 0)
drop = root;
/* backwards increment the k-bit code i */ /* increment past last table */
for (j = 1 << (k - 1); i & j; j >>= 1) next += 1U << curr;
i ^= j;
i ^= j;
/* backup over finished tables */ /* determine length of next table */
mask = (1 << w) - 1; /* needed on HP, cc -O bug */ curr = len - drop;
while ((i & mask) != x[h]) left = (int)(1 << curr);
{ while (curr + drop < max) {
h--; /* don't need to update q */ left -= count[curr + drop];
w -= l; if (left <= 0) break;
mask = (1 << w) - 1; curr++;
} left <<= 1;
}
/* check for enough space */
used += 1U << curr;
if (type == LENS && used >= ENOUGH - MAXD)
return 1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsigned char)curr;
(*table)[low].bits = (unsigned char)root;
(*table)[low].val = (unsigned short)(next - *table);
}
} }
}
/*
Fill in rest of table for incomplete codes. This loop is similar to the
loop above in incrementing huff for table indices. It is assumed that
len is equal to curr + drop, so there is no loop needed to increment
through high index bits. When the current sub-table is filled, the loop
drops back to the root table to fill in any remaining entries there.
*/
this.op = (unsigned char)64; /* invalid code marker */
this.bits = (unsigned char)(len - drop);
this.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
curr = root;
this.bits = (unsigned char)len;
}
/* Return Z_BUF_ERROR if we were given an incomplete table */ /* put invalid code marker in table */
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; next[huff >> drop] = this;
}
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
int inflate_trees_bits(c, bb, tb, hp, z) while (huff & incr)
uIntf *c; /* 19 code lengths */ incr >>= 1;
uIntf *bb; /* bits tree desired/actual depth */ if (incr != 0) {
inflate_huft * FAR *tb; /* bits tree result */ huff &= incr - 1;
inflate_huft *hp; /* space for trees */ huff += incr;
z_streamp z; /* for messages */ }
{ else
int r; huff = 0;
uInt hn = 0; /* hufts used in space */ }
uIntf *v; /* work area for huft_build */
/* set return parameters */
if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) *table += used;
return Z_MEM_ERROR; *bits = root;
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, return 0;
tb, bb, hp, &hn, v);
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed dynamic bit lengths tree";
else if (r == Z_BUF_ERROR || *bb == 0)
{
z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
uInt nl; /* number of literal/length codes */
uInt nd; /* number of distance codes */
uIntf *c; /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
/* allocate work area */
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
/* build literal/length tree */
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
if (r != Z_OK || *bl == 0)
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed literal/length tree";
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
/* build distance tree */
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
if (r != Z_OK || (*bd == 0 && nl > 257))
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed distance tree";
else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND
r = Z_OK;
}
#else
z->msg = (char*)"incomplete distance tree";
r = Z_DATA_ERROR;
}
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"empty distance tree with lengths";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
#endif
}
/* done */
ZFREE(z, v);
return Z_OK;
}
/* build fixed tables only once--keep them here */
#ifdef BUILDFIXED
local int fixed_built = 0;
#define FIXEDH 544 /* number of hufts used by fixed tables */
local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl;
local uInt fixed_bd;
local inflate_huft *fixed_tl;
local inflate_huft *fixed_td;
#else
#include "inffixed.h"
#endif
int inflate_trees_fixed(bl, bd, tl, td, z)
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
z_streamp z; /* for memory allocation */
{
#ifdef BUILDFIXED
/* build fixed tables if not already */
if (!fixed_built)
{
int k; /* temporary variable */
uInt f = 0; /* number of hufts used in fixed_mem */
uIntf *c; /* length list for huft_build */
uIntf *v; /* work area for huft_build */
/* allocate memory */
if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
{
ZFREE(z, c);
return Z_MEM_ERROR;
}
/* literal table */
for (k = 0; k < 144; k++)
c[k] = 8;
for (; k < 256; k++)
c[k] = 9;
for (; k < 280; k++)
c[k] = 7;
for (; k < 288; k++)
c[k] = 8;
fixed_bl = 9;
huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
fixed_mem, &f, v);
/* distance table */
for (k = 0; k < 30; k++)
c[k] = 5;
fixed_bd = 5;
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
fixed_mem, &f, v);
/* done */
ZFREE(z, v);
ZFREE(z, c);
fixed_built = 1;
}
#endif
*bl = fixed_bl;
*bd = fixed_bd;
*tl = fixed_tl;
*td = fixed_td;
return Z_OK;
} }

View File

@ -1,6 +1,6 @@
/* inftrees.h -- header to use inftrees.c /* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-2002 Mark Adler * Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* WARNING: this file should *not* be used by applications. It is /* WARNING: this file should *not* be used by applications. It is
@ -8,51 +8,48 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* Huffman code lookup table entry--this entry is four bytes for machines /* Structure for decoding tables. Each entry provides either the
that have 16-bit pointers (e.g. PC's in the small or medium model). */ information needed to do the operation requested by the code that
indexed that table entry, or it provides a pointer to another
table that indexes more bits of the code. op indicates whether
the entry is a pointer to another table, a literal, a length or
distance, an end-of-block, or an invalid code. For a table
pointer, the low four bits of op is the number of index bits of
that table. For a length or distance, the low four bits of op
is the number of extra bits to get after the code. bits is
the number of bits in this code or part of the code to drop off
of the bit buffer. val is the actual byte to output in the case
of a literal, the base length or distance, or the offset from
the current table to the next table. Each entry is four bytes. */
typedef struct {
unsigned char op; /* operation, extra bits, table bits */
unsigned char bits; /* bits in this part of the code */
unsigned short val; /* offset in table or code value */
} code;
typedef struct inflate_huft_s FAR inflate_huft; /* op values as set by inflate_table():
00000000 - literal
struct inflate_huft_s { 0000tttt - table link, tttt != 0 is the number of table index bits
union { 0001eeee - length or distance, eeee is the number of extra bits
struct { 01100000 - end of block
Byte Exop; /* number of extra bits or operation */ 01000000 - invalid code
Byte Bits; /* number of bits in this code or subcode */ */
} what;
uInt pad; /* pad structure to a power of 2 (4 bytes for */
} word; /* 16-bit, 8 bytes for 32-bit int's) */
uInt base; /* literal, length base, distance base,
or table offset */
};
/* Maximum size of dynamic tree. The maximum found in a long but non- /* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1004 huft structures (850 for length/literals exhaustive search was 1004 code structures (850 for length/literals
and 154 for distances, the latter actually the result of an and 154 for distances, the latter actually the result of an
exhaustive search). The actual maximum is not known, but the exhaustive search). The true maximum is not known, but the value
value below is more than safe. */ below is more than safe. */
#define MANY 1440 #define ENOUGH 1440
#define MAXD 154
extern int inflate_trees_bits OF(( /* Type of code to build for inftable() */
uIntf *, /* 19 code lengths */ typedef enum {
uIntf *, /* bits tree desired/actual depth */ CODES,
inflate_huft * FAR *, /* bits tree result */ LENS,
inflate_huft *, /* space for trees */ DISTS
z_streamp)); /* for messages */ } codetype;
extern int inflate_trees_dynamic OF(( extern int inflate_table OF((codetype type, unsigned short FAR *lens,
uInt, /* number of literal/length codes */ unsigned codes, code FAR * FAR *table,
uInt, /* number of distance codes */ unsigned FAR *bits, unsigned short FAR *work));
uIntf *, /* that many (total) code lengths */
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
inflate_huft *, /* space for trees */
z_streamp)); /* for messages */
extern int inflate_trees_fixed OF((
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
z_streamp)); /* for memory allocation */

View File

@ -1,6 +1,6 @@
/* minigzip.c -- simulate gzip using the zlib compression library /* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* /*
@ -31,7 +31,7 @@
# include <sys/stat.h> # include <sys/stat.h>
#endif #endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32) #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h> # include <fcntl.h>
# include <io.h> # include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
@ -112,7 +112,7 @@ void gz_compress(in, out)
if (gz_compress_mmap(in, out) == Z_OK) return; if (gz_compress_mmap(in, out) == Z_OK) return;
#endif #endif
for (;;) { for (;;) {
len = fread(buf, 1, sizeof(buf), in); len = (int)fread(buf, 1, sizeof(buf), in);
if (ferror(in)) { if (ferror(in)) {
perror("fread"); perror("fread");
exit(1); exit(1);
@ -147,7 +147,7 @@ int gz_compress_mmap(in, out)
if (buf_len <= 0) return Z_ERRNO; if (buf_len <= 0) return Z_ERRNO;
/* Now do the actual mmap: */ /* Now do the actual mmap: */
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
if (buf == (caddr_t)(-1)) return Z_ERRNO; if (buf == (caddr_t)(-1)) return Z_ERRNO;
/* Compress the whole file at once: */ /* Compress the whole file at once: */
@ -179,8 +179,8 @@ void gz_uncompress(in, out)
if (len == 0) break; if (len == 0) break;
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
error("failed fwrite"); error("failed fwrite");
} }
} }
if (fclose(out)) error("failed fclose"); if (fclose(out)) error("failed fclose");
@ -229,7 +229,7 @@ void file_uncompress(file)
char *infile, *outfile; char *infile, *outfile;
FILE *out; FILE *out;
gzFile in; gzFile in;
int len = strlen(file); uInt len = (uInt)strlen(file);
strcpy(buf, file); strcpy(buf, file);
@ -260,10 +260,11 @@ void file_uncompress(file)
/* =========================================================================== /* ===========================================================================
* Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...] * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
* -d : decompress * -d : decompress
* -f : compress with Z_FILTERED * -f : compress with Z_FILTERED
* -h : compress with Z_HUFFMAN_ONLY * -h : compress with Z_HUFFMAN_ONLY
* -r : compress with Z_RLE
* -1 to -9 : compression level * -1 to -9 : compression level
*/ */
@ -282,16 +283,18 @@ int main(argc, argv)
while (argc > 0) { while (argc > 0) {
if (strcmp(*argv, "-d") == 0) if (strcmp(*argv, "-d") == 0)
uncompr = 1; uncompr = 1;
else if (strcmp(*argv, "-f") == 0) else if (strcmp(*argv, "-f") == 0)
outmode[3] = 'f'; outmode[3] = 'f';
else if (strcmp(*argv, "-h") == 0) else if (strcmp(*argv, "-h") == 0)
outmode[3] = 'h'; outmode[3] = 'h';
else if (strcmp(*argv, "-r") == 0)
outmode[3] = 'R';
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
(*argv)[2] == 0) (*argv)[2] == 0)
outmode[2] = (*argv)[1]; outmode[2] = (*argv)[1];
else else
break; break;
argc--, argv++; argc--, argv++;
} }
if (argc == 0) { if (argc == 0) {
@ -315,6 +318,5 @@ int main(argc, argv)
} }
} while (argv++, --argc); } while (argv++, --argc);
} }
exit(0); return 0;
return 0; /* to avoid warning */
} }

View File

@ -1,6 +1,6 @@
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2002 Jean-loup Gailly * Copyright (C) 1995-2003 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* /*
@ -230,7 +230,6 @@ local void send_bits(s, value, length)
#endif /* DEBUG */ #endif /* DEBUG */
#define MAX(a,b) (a >= b ? a : b)
/* the arguments must not have side effects */ /* the arguments must not have side effects */
/* =========================================================================== /* ===========================================================================
@ -335,42 +334,42 @@ void gen_trees_header()
Assert (header != NULL, "Can't open trees.h"); Assert (header != NULL, "Can't open trees.h");
fprintf(header, fprintf(header,
"/* header created automatically with -DGEN_TREES_H */\n\n"); "/* header created automatically with -DGEN_TREES_H */\n\n");
fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
for (i = 0; i < L_CODES+2; i++) { for (i = 0; i < L_CODES+2; i++) {
fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
} }
fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) { for (i = 0; i < D_CODES; i++) {
fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
} }
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
for (i = 0; i < DIST_CODE_LEN; i++) { for (i = 0; i < DIST_CODE_LEN; i++) {
fprintf(header, "%2u%s", _dist_code[i], fprintf(header, "%2u%s", _dist_code[i],
SEPARATOR(i, DIST_CODE_LEN-1, 20)); SEPARATOR(i, DIST_CODE_LEN-1, 20));
} }
fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
fprintf(header, "%2u%s", _length_code[i], fprintf(header, "%2u%s", _length_code[i],
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
} }
fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
for (i = 0; i < LENGTH_CODES; i++) { for (i = 0; i < LENGTH_CODES; i++) {
fprintf(header, "%1u%s", base_length[i], fprintf(header, "%1u%s", base_length[i],
SEPARATOR(i, LENGTH_CODES-1, 20)); SEPARATOR(i, LENGTH_CODES-1, 20));
} }
fprintf(header, "local const int base_dist[D_CODES] = {\n"); fprintf(header, "local const int base_dist[D_CODES] = {\n");
for (i = 0; i < D_CODES; i++) { for (i = 0; i < D_CODES; i++) {
fprintf(header, "%5u%s", base_dist[i], fprintf(header, "%5u%s", base_dist[i],
SEPARATOR(i, D_CODES-1, 10)); SEPARATOR(i, D_CODES-1, 10));
} }
fclose(header); fclose(header);
@ -675,7 +674,8 @@ local void build_tree(s, desc)
/* Create a new node father of n and m */ /* Create a new node father of n and m */
tree[node].Freq = tree[n].Freq + tree[m].Freq; tree[node].Freq = tree[n].Freq + tree[m].Freq;
s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
s->depth[n] : s->depth[m]) + 1);
tree[n].Dad = tree[m].Dad = (ush)node; tree[n].Dad = tree[m].Dad = (ush)node;
#ifdef DUMP_BL_TREE #ifdef DUMP_BL_TREE
if (tree == s->bl_tree) { if (tree == s->bl_tree) {
@ -930,39 +930,39 @@ void _tr_flush_block(s, buf, stored_len, eof)
/* Build the Huffman trees unless a stored block is forced */ /* Build the Huffman trees unless a stored block is forced */
if (s->level > 0) { if (s->level > 0) {
/* Check if the file is ascii or binary */ /* Check if the file is ascii or binary */
if (s->data_type == Z_UNKNOWN) set_data_type(s); if (s->data_type == Z_UNKNOWN) set_data_type(s);
/* Construct the literal and distance trees */ /* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc))); build_tree(s, (tree_desc *)(&(s->l_desc)));
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
s->static_len)); s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc))); build_tree(s, (tree_desc *)(&(s->d_desc)));
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
s->static_len)); s->static_len));
/* At this point, opt_len and static_len are the total bit lengths of /* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations. * the compressed block data, excluding the tree representations.
*/ */
/* Build the bit length tree for the above two trees, and get the index /* Build the bit length tree for the above two trees, and get the index
* in bl_order of the last bit length code to send. * in bl_order of the last bit length code to send.
*/ */
max_blindex = build_bl_tree(s); max_blindex = build_bl_tree(s);
/* Determine the best encoding. Compute first the block length in bytes*/ /* Determine the best encoding. Compute the block lengths in bytes. */
opt_lenb = (s->opt_len+3+7)>>3; opt_lenb = (s->opt_len+3+7)>>3;
static_lenb = (s->static_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3;
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
s->last_lit)); s->last_lit));
if (static_lenb <= opt_lenb) opt_lenb = static_lenb; if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
} else { } else {
Assert(buf != (char*)0, "lost buf"); Assert(buf != (char*)0, "lost buf");
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
} }
#ifdef FORCE_STORED #ifdef FORCE_STORED
@ -1107,7 +1107,8 @@ local void compress_block(s, ltree, dtree)
} /* literal or match pair ? */ } /* literal or match pair ? */
/* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
"pendingBuf overflow");
} while (lx < s->last_lit); } while (lx < s->last_lit);
@ -1199,7 +1200,7 @@ local void copy_block(s, buf, len, header)
s->last_eob_len = 8; /* enough lookahead for inflate */ s->last_eob_len = 8; /* enough lookahead for inflate */
if (header) { if (header) {
put_short(s, (ush)len); put_short(s, (ush)len);
put_short(s, (ush)~len); put_short(s, (ush)~len);
#ifdef DEBUG #ifdef DEBUG
s->bits_sent += 2*16; s->bits_sent += 2*16;

View File

@ -1,10 +1,11 @@
/* uncompr.c -- decompress a memory buffer /* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
/* =========================================================================== /* ===========================================================================
@ -49,7 +50,9 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen)
err = inflate(&stream, Z_FINISH); err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) { if (err != Z_STREAM_END) {
inflateEnd(&stream); inflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err; if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
} }
*destLen = stream.total_out; *destLen = stream.total_out;

View File

@ -1,102 +1,126 @@
/* zconf.h -- configuration of the zlib compression library /* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _ZCONF_H #ifndef ZCONF_H
#define _ZCONF_H #define ZCONF_H
/* /*
* If you *really* need a unique prefix for all types and library functions, * If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/ */
#ifdef Z_PREFIX #ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_ # define deflateInit_ z_deflateInit_
# define deflate z_deflate # define deflate z_deflate
# define deflateEnd z_deflateEnd # define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_ # define inflateInit_ z_inflateInit_
# define inflate z_inflate # define inflate z_inflate
# define inflateEnd z_inflateEnd # define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_ # define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary # define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy # define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset # define deflateReset z_deflateReset
# define deflateParams z_deflateParams # define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_ # define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary # define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync # define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint # define inflateSyncPoint z_inflateSyncPoint
# define inflateReset z_inflateReset # define inflateCopy z_inflateCopy
# define compress z_compress # define inflateReset z_inflateReset
# define compress2 z_compress2 # define compress z_compress
# define uncompress z_uncompress # define compress2 z_compress2
# define adler32 z_adler32 # define compressBound z_compressBound
# define crc32 z_crc32 # define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table # define get_crc_table z_get_crc_table
# define Byte z_Byte # define Byte z_Byte
# define uInt z_uInt # define uInt z_uInt
# define uLong z_uLong # define uLong z_uLong
# define Bytef z_Bytef # define Bytef z_Bytef
# define charf z_charf # define charf z_charf
# define intf z_intf # define intf z_intf
# define uIntf z_uIntf # define uIntf z_uIntf
# define uLongf z_uLongf # define uLongf z_uLongf
# define voidpf z_voidpf # define voidpf z_voidpf
# define voidp z_voidp # define voidp z_voidp
#endif #endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32 # define WIN32
#endif #endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# ifndef __32BIT__ # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# define __32BIT__ # ifndef SYS16BIT
# define SYS16BIT
# endif
# endif # endif
#endif #endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
/* /*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int). * than 64k bytes at a time (needed on systems with 16-bit int).
*/ */
#if defined(MSDOS) && !defined(__32BIT__) #ifdef SYS16BIT
# define MAXSEG_64K # define MAXSEG_64K
#endif #endif
#ifdef MSDOS #ifdef MSDOS
# define UNALIGNED_OK # define UNALIGNED_OK
#endif #endif
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) #ifdef __STDC_VERSION__
# define STDC
#endif
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
# ifndef STDC # ifndef STDC
# define STDC # define STDC
# endif # endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif #endif
#ifndef STDC #ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const # define const /* note: need a more gentle solution here */
# endif # endif
#endif #endif
/* Some Mac compilers merge all .h files incorrectly: */ /* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL # define NO_DUMMY_DECL
#endif #endif
/* Old Borland C incorrectly complains about missing returns: */
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL #ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K # ifdef MAXSEG_64K
@ -144,73 +168,87 @@
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty. * just define FAR to be empty.
*/ */
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) #ifdef SYS16BIT
/* MSC small or medium model */ # if defined(M_I86SM) || defined(M_I86MM)
# define SMALL_MEDIUM /* MSC small or medium model */
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
#endif
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
# ifndef __32BIT__
# define SMALL_MEDIUM # define SMALL_MEDIUM
# define FAR _far # ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif # endif
#endif #endif
/* Compile with -DZLIB_DLL for Windows DLL support */ #if defined(WINDOWS) || defined(WIN32)
#if defined(ZLIB_DLL) /* If building or using zlib as a DLL, define ZLIB_DLL.
# if defined(_WINDOWS) || defined(WINDOWS) * This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR # ifdef FAR
# undef FAR # undef FAR
# endif # endif
# include <windows.h> # include <windows.h>
# define ZEXPORT WINAPI /* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32 # ifdef WIN32
# define ZEXPORTVA WINAPIV # define ZEXPORTVA WINAPIV
# else # else
# define ZEXPORTVA FAR _cdecl _export # define ZEXPORTVA FAR CDECL
# endif
# endif
# if defined (__BORLANDC__)
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
# include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
# else
# if defined (_Windows) && defined (__DLL__)
# define ZEXPORT _export
# define ZEXPORTVA _export
# endif
# endif # endif
# endif # endif
#endif #endif
#if defined (__BEOS__) #if defined (__BEOS__)
# if defined (ZLIB_DLL) # ifdef ZLIB_DLL
# define ZEXTERN extern __declspec(dllexport) # ifdef ZLIB_INTERNAL
# else # define ZEXPORT __declspec(dllexport)
# define ZEXTERN extern __declspec(dllimport) # define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif # endif
#endif #endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT #ifndef ZEXPORT
# define ZEXPORT # define ZEXPORT
#endif #endif
#ifndef ZEXPORTVA #ifndef ZEXPORTVA
# define ZEXPORTVA # define ZEXPORTVA
#endif #endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef FAR #ifndef FAR
# define FAR # define FAR
#endif #endif
#if !defined(MACOS) && !defined(TARGET_OS_MAC) #if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */ typedef unsigned char Byte; /* 8 bits */
#endif #endif
typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned int uInt; /* 16 bits or more */
@ -228,16 +266,21 @@ typedef uInt FAR uIntf;
typedef uLong FAR uLongf; typedef uLong FAR uLongf;
#ifdef STDC #ifdef STDC
typedef void FAR *voidpf; typedef void const *voidpc;
typedef void *voidp; typedef void FAR *voidpf;
typedef void *voidp;
#else #else
typedef Byte FAR *voidpf; typedef Byte const *voidpc;
typedef Byte *voidp; typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif #endif
#ifdef HAVE_UNISTD_H #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */ # include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */ # include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t # define z_off_t off_t
#endif #endif
#ifndef SEEK_SET #ifndef SEEK_SET
@ -249,31 +292,32 @@ typedef uLong FAR uLongf;
# define z_off_t long # define z_off_t long
#endif #endif
#if defined(__OS400__)
#define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */ /* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__) #if defined(__MVS__)
# pragma map(deflateInit_,"DEIN") # pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2") # pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND") # pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ") # pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2") # pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND") # pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY") # pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI") # pragma map(inflateSetDictionary,"INSEDI")
# pragma map(inflate_blocks,"INBL") # pragma map(compressBound,"CMBND")
# pragma map(inflate_blocks_new,"INBLNE") # pragma map(inflate_table,"INTABL")
# pragma map(inflate_blocks_free,"INBLFR")
# pragma map(inflate_blocks_reset,"INBLRE")
# pragma map(inflate_codes_free,"INCOFR")
# pragma map(inflate_codes,"INCO")
# pragma map(inflate_fast,"INFA") # pragma map(inflate_fast,"INFA")
# pragma map(inflate_flush,"INFLU")
# pragma map(inflate_mask,"INMA")
# pragma map(inflate_set_dictionary,"INSEDI2")
# pragma map(inflate_copyright,"INCOPY") # pragma map(inflate_copyright,"INCOPY")
# pragma map(inflate_trees_bits,"INTRBI")
# pragma map(inflate_trees_dynamic,"INTRDY")
# pragma map(inflate_trees_fixed,"INTRFI")
# pragma map(inflate_trees_free,"INTRFR")
#endif #endif
#endif /* _ZCONF_H */ #endif /* ZCONF_H */

View File

@ -1,4 +1,4 @@
.TH ZLIB 3 "11 March 2002" .TH ZLIB 3 "17 November 2003"
.SH NAME .SH NAME
zlib \- compression/decompression library zlib \- compression/decompression library
.SH SYNOPSIS .SH SYNOPSIS
@ -13,7 +13,8 @@ The code is thread safe.
It provides in-memory compression and decompression functions, It provides in-memory compression and decompression functions,
including integrity checks of the uncompressed data. including integrity checks of the uncompressed data.
This version of the library supports only one compression method (deflation) This version of the library supports only one compression method (deflation)
but other algorithms will be added later and will have the same stream interface. but other algorithms will be added later
and will have the same stream interface.
.LP .LP
Compression can be done in a single step if the buffers are large enough Compression can be done in a single step if the buffers are large enough
(for example if an input file is mmap'ed), (for example if an input file is mmap'ed),
@ -23,66 +24,117 @@ the application must provide more input and/or consume the output
(providing more output space) before each call. (providing more output space) before each call.
.LP .LP
The library also supports reading and writing files in The library also supports reading and writing files in
.I gzip .IR gzip (1)
(.gz) format (.gz) format
with an interface similar to that of stdio. with an interface similar to that of stdio.
.LP .LP
The library does not install any signal handler. The decoder checks The library does not install any signal handler.
the consistency of the compressed data, so the library should never The decoder checks the consistency of the compressed data,
crash even in case of corrupted input. so the library should never crash even in case of corrupted input.
.LP .LP
All functions of the compression library are documented in the file All functions of the compression library are documented in the file
.IR zlib.h. .IR zlib.h .
The distribution source includes examples of use of the library The distribution source includes examples of use of the library
the files in the files
.I example.c .I example.c
and and
.IR minigzip.c . .IR minigzip.c .
.LP .LP
Changes to this version are documented in the file
.I ChangeLog
that accompanies the source,
and are concerned primarily with bug fixes and portability enhancements.
.LP
A Java implementation of A Java implementation of
.IR zlib .I zlib
is available in the Java Development Kit 1.1 is available in the Java Development Kit 1.1:
.IP .IP
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
.LP .LP
A Perl interface to A Perl interface to
.IR zlib , .IR zlib ,
written by Paul Marquess (pmarquess@bfsec.bt.co.uk) written by Paul Marquess (pmqs@cpan.org),
is available at CPAN (Comprehensive Perl Archive Network) sites, is available at CPAN (Comprehensive Perl Archive Network) sites,
such as: including:
.IP .IP
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* http://www.cpan.org/modules/by-module/Compress/
.LP .LP
A Python interface to A Python interface to
.IR zlib .IR zlib ,
written by A.M. Kuchling <amk@magnet.com> written by A.M. Kuchling (amk@magnet.com),
is available from the Python Software Association sites, such as: is available in Python 1.5 and later versions:
.IP .IP
ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz http://www.python.org/doc/lib/module-zlib.html
.LP
A
.I zlib
binding for
.IR tcl (1),
written by Andreas Kupries (a.kupries@westend.com),
is availlable at:
.IP
http://www.westend.com/~kupries/doc/trf/man/man.html
.LP
An experimental package to read and write files in .zip format,
written on top of
.I zlib
by Gilles Vollant (info@winimage.com),
is available at:
.IP
http://www.winimage.com/zLibDll/unzip.html
and also in the
.I contrib/minizip
directory of the main
.I zlib
web site.
.SH "SEE ALSO" .SH "SEE ALSO"
Questions about zlib should be sent to: The
.I zlib
web site can be found at either of these locations:
.IP .IP
zlib@quest.jpl.nasa.gov http://www.zlib.org
or, if this fails, to the author addresses given below. .br
The zlib home page is: http://www.gzip.org/zlib/
.IP
http://www.cdrom.com/pub/infozip/zlib/
.LP .LP
The data format used by the zlib library is described by RFC The data format used by the zlib library is described by RFC
(Request for Comments) 1950 to 1952 in the files: (Request for Comments) 1950 to 1952 in the files:
.IP .IP
ftp://ds.internic.net/rfc/rfc1950.txt (zlib format) http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
.br .br
rfc1951.txt (deflate format) http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
.br .br
rfc1952.txt (gzip format) http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
.LP .LP
These documents are also available in other formats from: These documents are also available in other formats from:
.IP .IP
ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
.LP
Mark Nelson (markn@ieee.org) wrote an article about
.I zlib
for the Jan. 1997 issue of Dr. Dobb's Journal;
a copy of the article is available at:
.IP
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
.SH "REPORTING PROBLEMS"
Before reporting a problem,
please check the
.I zlib
web site to verify that you have the latest version of
.IR zlib ;
otherwise,
obtain the latest version and see if the problem still exists.
Please read the
.I zlib
FAQ at:
.IP
http://www.gzip.org/zlib/zlib_faq.html
.LP
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 .SH AUTHORS
Version 1.1.4 Version 1.2.1
Copyright (C) 1995-2002 Jean-loup Gailly (jloup@gzip.org) Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu). and Mark Adler (madler@alumni.caltech.edu).
.LP .LP
This software is provided "as-is," This software is provided "as-is,"

View File

@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.1.4, March 11th, 2002 version 1.2.1, November 17th, 2003
Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -24,12 +24,12 @@
The data format used by the zlib library is described by RFCs (Request for The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/ */
#ifndef _ZLIB_H #ifndef ZLIB_H
#define _ZLIB_H #define ZLIB_H
#include "zconf.h" #include "zconf.h"
@ -37,9 +37,10 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.1.4" #define ZLIB_VERSION "1.2.1"
#define ZLIB_VERNUM 0x1210
/* /*
The 'zlib' compression library provides in-memory compression and The 'zlib' compression library provides in-memory compression and
decompression functions, including integrity checks of the uncompressed decompression functions, including integrity checks of the uncompressed
data. This version of the library supports only one compression method data. This version of the library supports only one compression method
@ -52,8 +53,23 @@ extern "C" {
application must provide more input and/or consume the output application must provide more input and/or consume the output
(providing more output space) before each call. (providing more output space) before each call.
The compressed data format used by the in-memory functions is the zlib
format, which is a zlib wrapper documented in RFC 1950, wrapped around a
deflate stream, which is itself documented in RFC 1951.
The library also supports reading and writing files in gzip (.gz) format The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio. with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib.
This library does not provide any functions to write gzip files in memory.
However such functions could be easily written using zlib's deflate function,
the documentation in the gzip RFC, and the examples in gzio.c.
The library does not install any signal handler. The decoder checks The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never the consistency of the compressed data, so the library should never
@ -127,7 +143,8 @@ typedef z_stream FAR *z_streamp;
#define Z_SYNC_FLUSH 2 #define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3 #define Z_FULL_FLUSH 3
#define Z_FINISH 4 #define Z_FINISH 4
/* Allowed flush values; see deflate() below for details */ #define Z_BLOCK 5
/* Allowed flush values; see deflate() and inflate() below for details */
#define Z_OK 0 #define Z_OK 0
#define Z_STREAM_END 1 #define Z_STREAM_END 1
@ -150,13 +167,14 @@ typedef z_stream FAR *z_streamp;
#define Z_FILTERED 1 #define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2 #define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_DEFAULT_STRATEGY 0 #define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */ /* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0 #define Z_BINARY 0
#define Z_ASCII 1 #define Z_ASCII 1
#define Z_UNKNOWN 2 #define Z_UNKNOWN 2
/* Possible values of the data_type field */ /* Possible values of the data_type field (though see inflate()) */
#define Z_DEFLATED 8 #define Z_DEFLATED 8
/* The deflate compression method (the only one supported in this version) */ /* The deflate compression method (the only one supported in this version) */
@ -175,7 +193,7 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void));
This check is automatically made by deflateInit and inflateInit. This check is automatically made by deflateInit and inflateInit.
*/ */
/* /*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
Initializes the internal stream state for compression. The fields Initializes the internal stream state for compression. The fields
@ -244,7 +262,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
If deflate returns with avail_out == 0, this function must be called again If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero avail_out), until the flush is complete (deflate returns with non-zero
avail_out). avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
avail_out is greater than six to avoid repeated flush markers due to
avail_out == 0 on return.
If the parameter flush is set to Z_FINISH, pending input is processed, If the parameter flush is set to Z_FINISH, pending input is processed,
pending output is flushed and deflate returns with Z_STREAM_END if there pending output is flushed and deflate returns with Z_STREAM_END if there
@ -253,10 +273,10 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
more input data, until it returns with Z_STREAM_END or an error. After more input data, until it returns with Z_STREAM_END or an error. After
deflate has returned Z_STREAM_END, the only possible operations on the deflate has returned Z_STREAM_END, the only possible operations on the
stream are deflateReset or deflateEnd. stream are deflateReset or deflateEnd.
Z_FINISH can be used immediately after deflateInit if all the compression Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least is to be done in a single step. In this case, avail_out must be at least
0.1% larger than avail_in plus 12 bytes. If deflate does not return the value returned by deflateBound (see below). If deflate does not return
Z_STREAM_END, then it must be called again as described above. Z_STREAM_END, then it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read deflate() sets strm->adler to the adler32 checksum of all input read
@ -272,7 +292,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
consumed and all output has been produced (only when flush is set to consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
(for example avail_in or avail_out was zero). (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
fatal, and deflate() can be called again with more input and more output
space to continue compressing.
*/ */
@ -290,7 +312,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
*/ */
/* /*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields Initializes the internal stream state for decompression. The fields
@ -314,9 +336,9 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/* /*
inflate decompresses as much data as possible, and stops when the input inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may some buffer becomes empty or the output buffer becomes full. It may introduce
introduce some output latency (reading input without producing any output) some output latency (reading input without producing any output) except when
except when forced to flush. forced to flush.
The detailed semantics are as follows. inflate performs one or both of the The detailed semantics are as follows. inflate performs one or both of the
following actions: following actions:
@ -340,11 +362,26 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
must be called again after making room in the output buffer because there must be called again after making room in the output buffer because there
might be more output pending. might be more output pending.
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
output as possible to the output buffer. The flushing behavior of inflate is Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
not specified for values of the flush parameter other than Z_SYNC_FLUSH output as possible to the output buffer. Z_BLOCK requests that inflate() stop
and Z_FINISH, but the current implementation actually flushes as much output if and when it get to the next deflate block boundary. When decoding the zlib
as possible anyway. or gzip format, this will cause inflate() to return immediately after the
header and before the first block. When doing a raw inflate, inflate() will
go ahead and process the first block, and will return when it gets to the end
of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the
number of unused bits in the last byte taken from strm->next_in, plus 64
if inflate() is currently decoding the last block in the deflate stream,
plus 128 if inflate() returned immediately after decoding an end-of-block
code or decoding the complete header up to just before the first byte of the
deflate stream. The end-of-block will not be indicated until all of the
uncompressed data from that block has been written to strm->next_out. The
number of unused bits may in general be greater than seven, except when
bit 7 of data_type is set, in which case the number of unused bits will be
less than eight.
inflate() should normally be called until it returns Z_STREAM_END or an inflate() should normally be called until it returns Z_STREAM_END or an
error. However if all decompression is to be performed in a single step error. However if all decompression is to be performed in a single step
@ -354,29 +391,44 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
uncompressed data. (The size of the uncompressed data may have been saved uncompressed data. (The size of the uncompressed data may have been saved
by the compressor for this purpose.) The next operation on this stream must by the compressor for this purpose.) The next operation on this stream must
be inflateEnd to deallocate the decompression state. The use of Z_FINISH be inflateEnd to deallocate the decompression state. The use of Z_FINISH
is never required, but can be used to inform inflate that a faster routine is never required, but can be used to inform inflate that a faster approach
may be used for the single inflate() call. may be used for the single inflate() call.
If a preset dictionary is needed at this point (see inflateSetDictionary In this implementation, inflate() always flushes as much output as
below), inflate sets strm-adler to the adler32 checksum of the possible to the output buffer, and always uses the faster approach on the
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise first call. So the only effect of the flush parameter in this implementation
it sets strm->adler to the adler32 checksum of all output produced is on the return value of inflate(), as noted below, or when it returns early
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or because Z_BLOCK is used.
an error code as described below. At the end of the stream, inflate()
checks that its computed adler32 checksum is equal to that saved by the If a preset dictionary is needed after this call (see inflateSetDictionary
compressor and returns Z_STREAM_END only if the checksum is correct. below), inflate sets strm-adler to the adler32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
only if the checksum is correct.
inflate() will decompress and check either zlib-wrapped or gzip-wrapped
deflate data. The header type is detected automatically. Any information
contained in the gzip header is not retained, so applications that need that
information should instead use raw inflate, see inflateInit2() below, or
inflateBack() and perform their own processing of the gzip header and
trailer.
inflate() returns Z_OK if some progress has been made (more input processed inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has or more output produced), Z_STREAM_END if the end of the compressed data has
been reached and all uncompressed output has been produced, Z_NEED_DICT if a been reached and all uncompressed output has been produced, Z_NEED_DICT if a
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect corrupted (input stream not conforming to the zlib format or incorrect check
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
enough memory, Z_BUF_ERROR if no progress is possible or if there was not Z_BUF_ERROR if no progress is possible or if there was not enough room in the
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
case, the application may then call inflateSync to look for a good inflate() can be called again with more input and more output space to
compression block. continue decompressing. If Z_DATA_ERROR is returned, the application may then
call inflateSync() to look for a good compression block if a partial recovery
of the data is desired.
*/ */
@ -397,7 +449,7 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
The following functions are needed only in some special applications. The following functions are needed only in some special applications.
*/ */
/* /*
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int level, int level,
int method, int method,
@ -413,11 +465,21 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
this version of the library. this version of the library.
The windowBits parameter is the base two logarithm of the window size The windowBits parameter is the base two logarithm of the window size
(the size of the history buffer). It should be in the range 8..15 for this (the size of the history buffer). It should be in the range 8..15 for this
version of the library. Larger values of this parameter result in better version of the library. Larger values of this parameter result in better
compression at the expense of memory usage. The default value is 15 if compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead. deflateInit is used instead.
windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
determines the window size. deflate() will then generate raw deflate data
with no zlib header or trailer, and will not compute an adler32 check value.
windowBits can also be greater than 15 for optional gzip encoding. Add
16 to windowBits to write a simple gzip header and trailer around the
compressed data instead of a zlib wrapper. The gzip header will have no
file name, no extra data, no comment, no modification time (set to zero),
no header crc, and the operating system will be set to 255 (unknown).
The memLevel parameter specifies how much memory should be allocated The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but for the internal compression state. memLevel=1 uses minimum memory but
is slow and reduces compression ratio; memLevel=9 uses maximum memory is slow and reduces compression ratio; memLevel=9 uses maximum memory
@ -426,21 +488,23 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
The strategy parameter is used to tune the compression algorithm. Use the The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match). Filtered data consists mostly of small values with a string match), or Z_RLE to limit match distances to one (run-length
somewhat random distribution. In this case, the compression algorithm is encoding). Filtered data consists mostly of small values with a somewhat
tuned to compress them better. The effect of Z_FILTERED is to force more random distribution. In this case, the compression algorithm is tuned to
Huffman coding and less string matching; it is somewhat intermediate compress them better. The effect of Z_FILTERED is to force more Huffman
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects coding and less string matching; it is somewhat intermediate between
the compression ratio but not the correctness of the compressed output even Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
if it is not set appropriately. Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
parameter only affects the compression ratio but not the correctness of the
compressed output even if it is not set appropriately.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
method). msg is set to null if there is no error message. deflateInit2 does method). msg is set to null if there is no error message. deflateInit2 does
not perform any compression: this will be done by deflate(). not perform any compression: this will be done by deflate().
*/ */
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary, const Bytef *dictionary,
uInt dictLength)); uInt dictLength));
@ -464,11 +528,12 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflate or deflate2. Thus the strings most likely to be useful should be deflate or deflate2. Thus the strings most likely to be useful should be
put at the end of the dictionary, not at the front. put at the end of the dictionary, not at the front.
Upon return of this function, strm->adler is set to the Adler32 value Upon return of this function, strm->adler is set to the adler32 value
of the dictionary; the decompressor may later use this value to determine of the dictionary; the decompressor may later use this value to determine
which dictionary has been used by the compressor. (The Adler32 value which dictionary has been used by the compressor. (The adler32 value
applies to the whole dictionary even if only a subset of the dictionary is applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.) actually used by the compressor.) If a raw deflate was requested, then the
adler32 value is not computed and strm->adler is not set.
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is parameter is invalid (such as NULL dictionary) or the stream state is
@ -507,8 +572,8 @@ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
*/ */
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
int level, int level,
int strategy)); int strategy));
/* /*
Dynamically update the compression level and compression strategy. The Dynamically update the compression level and compression strategy. The
interpretation of level and strategy is as in deflateInit2. This can be interpretation of level and strategy is as in deflateInit2. This can be
@ -527,7 +592,32 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
if strm->avail_out was zero. if strm->avail_out was zero.
*/ */
/* ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
/*
deflateBound() returns an upper bound on the compressed size after
deflation of sourceLen bytes. It must be called after deflateInit()
or deflateInit2(). This would be used to allocate an output buffer
for deflation in a single pass, and so would be called before deflate().
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
/*
deflatePrime() inserts bits in the deflate output stream. The intent
is that this function is used to start off the deflate output with the
bits leftover from a previous deflate stream when appending to it. As such,
this function can only be used for raw deflate, and must be used before the
first deflate() call after a deflateInit2() or deflateReset(). bits must be
less than or equal to 16, and that many of the least significant bits of
value will be inserted in the output.
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits)); int windowBits));
@ -538,11 +628,30 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
The windowBits parameter is the base two logarithm of the maximum window The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for size (the size of the history buffer). It should be in the range 8..15 for
this version of the library. The default value is 15 if inflateInit is used this version of the library. The default value is 15 if inflateInit is used
instead. If a compressed stream with a larger window size is given as instead. windowBits must be greater than or equal to the windowBits value
input, inflate() will return with the error code Z_DATA_ERROR instead of provided to deflateInit2() while compressing, or it must be equal to 15 if
trying to allocate a larger window. deflateInit2() was not used. If a compressed stream with a larger window
size is given as input, inflate() will return with the error code
Z_DATA_ERROR instead of trying to allocate a larger window.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
determines the window size. inflate() will then process raw deflate data,
not looking for a zlib or gzip header, not generating a check value, and not
looking for any check values for comparison at the end of the stream. This
is for use with other formats that use the deflate compressed data format
such as zip. Those formats provide their own check values. If a custom
format is developed using the raw deflate format for compressed data, it is
recommended that a check value such as an adler32 or a crc32 be applied to
the uncompressed data as is done in the zlib, gzip, and zip formats. For
most applications, the zlib format should be used as is. Note that comments
above on the use in deflateInit2() applies to the magnitude of windowBits.
windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will
return a Z_DATA_ERROR).
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
memLevel). msg is set to null if there is no error message. inflateInit2 memLevel). msg is set to null if there is no error message. inflateInit2
does not perform any decompression apart from reading the zlib header if does not perform any decompression apart from reading the zlib header if
@ -557,20 +666,20 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
Initializes the decompression dictionary from the given uncompressed byte Initializes the decompression dictionary from the given uncompressed byte
sequence. This function must be called immediately after a call of inflate sequence. This function must be called immediately after a call of inflate
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the Adler32 value returned by this call of can be determined from the adler32 value returned by this call of
inflate. The compressor and decompressor must use exactly the same inflate. The compressor and decompressor must use exactly the same
dictionary (see deflateSetDictionary). dictionary (see deflateSetDictionary).
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is parameter is invalid (such as NULL dictionary) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
expected one (incorrect Adler32 value). inflateSetDictionary does not expected one (incorrect adler32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of perform any decompression: this will be done by subsequent calls of
inflate(). inflate().
*/ */
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/* /*
Skips invalid compressed data until a full flush point (see above the Skips invalid compressed data until a full flush point (see above the
description of deflate with Z_FULL_FLUSH) can be found, or until all description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided. available input is skipped. No output is provided.
@ -584,6 +693,22 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
until success or end of the input data. until success or end of the input data.
*/ */
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
z_streamp source));
/*
Sets the destination stream as a complete copy of the source stream.
This function can be useful when randomly accessing a large stream. The
first pass through the stream can periodically record the inflate state,
allowing restarting inflate at those points when randomly accessing the
stream.
inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being NULL). msg is left unchanged in both source and
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
/* /*
This function is equivalent to inflateEnd followed by inflateInit, This function is equivalent to inflateEnd followed by inflateInit,
@ -594,6 +719,149 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
stream state was inconsistent (such as zalloc or state being NULL). stream state was inconsistent (such as zalloc or state being NULL).
*/ */
/*
ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
unsigned char FAR *window));
Initialize the internal stream state for decompression using inflateBack()
calls. The fields zalloc, zfree and opaque in strm must be initialized
before the call. If zalloc and zfree are Z_NULL, then the default library-
derived memory allocation routines are used. windowBits is the base two
logarithm of the window size, in the range 8..15. window is a caller
supplied buffer of that size. Except for special applications where it is
assured that deflate was used with small window sizes, windowBits must be 15
and a 32K byte window must be supplied to be able to decompress general
deflate streams.
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
the paramaters are invalid, Z_MEM_ERROR if the internal state could not
be allocated, or Z_VERSION_ERROR if the version of the library does not
match the version of the header file.
*/
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
interface for input and output. This is more efficient than inflate() for
file i/o applications in that it avoids copying between the output and the
sliding window by simply making the window itself the output buffer. This
function trusts the application to not change the output buffer passed by
the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
inflateBack() may then be used multiple times to inflate a complete, raw
deflate stream with each call. inflateBackEnd() is then called to free
the allocated state.
A raw deflate stream is one with no zlib or gzip header or trailer.
This routine would normally be used in a utility that reads zip or gzip
files and writes out uncompressed files. The utility would decode the
header and process the trailer on its own, hence this routine expects
only the raw deflate stream to decompress. This is different from the
normal behavior of inflate(), which expects either a zlib or gzip header and
trailer around the deflate stream.
inflateBack() uses two subroutines supplied by the caller that are then
called by inflateBack() for input and output. inflateBack() calls those
routines until it reads a complete deflate stream and writes out all of the
uncompressed data, or until it encounters an error. The function's
parameters and return types are defined above in the in_func and out_func
typedefs. inflateBack() will call in(in_desc, &buf) which should return the
number of bytes of provided input, and a pointer to that input in buf. If
there is no input available, in() must return zero--buf is ignored in that
case--and inflateBack() will return a buffer error. inflateBack() will call
out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
should return zero on success, or non-zero on failure. If out() returns
non-zero, inflateBack() will return with an error. Neither in() nor out()
are permitted to change the contents of the window provided to
inflateBackInit(), which is also the buffer that out() uses to write from.
The length written by out() will be at most the window size. Any non-zero
amount of input may be provided by in().
For convenience, inflateBack() can be provided input on the first call by
setting strm->next_in and strm->avail_in. If that input is exhausted, then
in() will be called. Therefore strm->next_in must be initialized before
calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
must also be initialized, and then if strm->avail_in is not zero, input will
initially be taken from strm->next_in[0 .. strm->avail_in - 1].
The in_desc and out_desc parameters of inflateBack() is passed as the
first parameter of in() and out() respectively when they are called. These
descriptors can be optionally used to pass any information that the caller-
supplied in() and out() functions need to do their job.
On return, inflateBack() will set strm->next_in and strm->avail_in to
pass back any unused input that was provided by the last in() call. The
return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
if in() or out() returned an error, Z_DATA_ERROR if there was a format
error in the deflate stream (in which case strm->msg is set to indicate the
nature of the error), or Z_STREAM_ERROR if the stream was not properly
initialized. In the case of Z_BUF_ERROR, an input or output error can be
distinguished using strm->next_in which will be Z_NULL only if in() returned
an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
out() returning non-zero. (in() will always be called before out(), so
strm->next_in is assured to be defined if out() returns non-zero.) Note
that inflateBack() cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
/*
All memory allocated by inflateBackInit() is freed.
inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
state was inconsistent.
*/
ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
/* Return flags indicating compile-time options.
Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
1.0: size of uInt
3.2: size of uLong
5.4: size of voidpf (pointer)
7.6: size of z_off_t
Compiler, assembler, and debug options:
8: DEBUG
9: ASMV or ASMINF -- use ASM code
10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
11: 0 (reserved)
One-time table building (smaller code, but not thread-safe if true):
12: BUILDFIXED -- build static block decoding tables when needed
13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
14,15: 0 (reserved)
Library content (indicates missing functionality):
16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
deflate code when not needed)
17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
and decode gzip streams (to avoid linking crc code)
18-19: 0 (reserved)
Operation variations (changes in library functionality):
20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
21: FASTEST -- deflate algorithm with only one, lowest compression level
22,23: 0 (reserved)
The sprintf variant used by gzprintf (zero is best):
24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
26: 0 = returns value, 1 = void -- 1 means inferred string length returned
Remainder:
27-31: 0 (reserved)
*/
/* utility functions */ /* utility functions */
@ -610,8 +878,8 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
/* /*
Compresses the source buffer into the destination buffer. sourceLen is Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be at least 0.1% larger than size of the destination buffer, which must be at least the value returned
sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the by compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer. compressed buffer.
This function can be used to compress a whole file at once if the This function can be used to compress a whole file at once if the
input file is mmap'ed. input file is mmap'ed.
@ -627,14 +895,22 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
Compresses the source buffer into the destination buffer. The level Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus destination buffer, which must be at least the value returned by
12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer, memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid. Z_STREAM_ERROR if the level parameter is invalid.
*/ */
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/*
compressBound() returns an upper bound on the compressed size after
compress() or compress2() on sourceLen bytes. It would be used before
a compress() or compress2() call to allocate the destination buffer.
*/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen)); const Bytef *source, uLong sourceLen));
/* /*
@ -650,7 +926,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted. buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
*/ */
@ -661,8 +937,9 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
Opens a gzip (.gz) file for reading or writing. The mode parameter 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 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 ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
Huffman only compression as in "wb1h". (See the description Huffman only compression as in "wb1h", or 'R' for run-length encoding
of deflateInit2 for more information about the strategy parameter.) as in "wb1R". (See the description of deflateInit2 for more information
about the strategy parameter.)
gzopen can be used to read a file which is not in gzip format; in this gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression. case gzread will directly read from the file without decompression.
@ -701,8 +978,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
gzread returns the number of uncompressed bytes actually read (0 for gzread returns the number of uncompressed bytes actually read (0 for
end of file, -1 for error). */ end of file, -1 for error). */
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
const voidp buf, unsigned len)); voidpc buf, unsigned len));
/* /*
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of uncompressed bytes actually written gzwrite returns the number of uncompressed bytes actually written
@ -713,7 +990,13 @@ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
/* /*
Converts, formats, and writes the args to the compressed file under Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error). uncompressed bytes actually written (0 in case of error). The number of
uncompressed bytes written is limited to 4095. The caller should assure that
this limit is not exceeded. If it is exceeded, then gzprintf() will return
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()
because the secure snprintf() or vsnprintf() functions were not available.
*/ */
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
@ -744,6 +1027,16 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
or -1 in case of end of file or error. or -1 in case of end of file or error.
*/ */
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
/*
Push one character back onto the stream to be read again later.
Only one character of push-back is allowed. gzungetc() returns the
character pushed, or -1 on failure. gzungetc() will fail if a
character has been pushed but not read yet, or if c is -1. The pushed
character will be discarded if the stream is repositioned with gzseek()
or gzrewind().
*/
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
/* /*
Flushes all pending output into the compressed file. The parameter Flushes all pending output into the compressed file. The parameter
@ -755,8 +1048,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
*/ */
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
z_off_t offset, int whence)); z_off_t offset, int whence));
/* /*
Sets the starting position for the next gzread or gzwrite on the Sets the starting position for the next gzread or gzwrite on the
given compressed file. The offset represents a number of bytes in the given compressed file. The offset represents a number of bytes in the
uncompressed data stream. The whence parameter is defined as in lseek(2); uncompressed data stream. The whence parameter is defined as in lseek(2);
@ -810,6 +1103,13 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
to get the exact error code. to get the exact error code.
*/ */
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
/*
Clears 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.
*/
/* checksum functions */ /* checksum functions */
/* /*
@ -867,6 +1167,10 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int stream_size)); int stream_size));
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size)); const char *version, int stream_size));
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
unsigned char FAR *window,
const char *version,
int stream_size));
#define deflateInit(strm, level) \ #define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit(strm) \ #define inflateInit(strm) \
@ -876,9 +1180,12 @@ ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
(strategy), ZLIB_VERSION, sizeof(z_stream)) (strategy), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit2(strm, windowBits) \ #define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, sizeof(z_stream))
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; /* hack for buggy compilers */ struct internal_state {int dummy;}; /* hack for buggy compilers */
#endif #endif
@ -890,4 +1197,4 @@ ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
} }
#endif #endif
#endif /* _ZLIB_H */ #endif /* ZLIB_H */

View File

@ -1,19 +1,21 @@
/* zutil.c -- target dependent utility functions for the compression library /* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
#include "zutil.h" #include "zutil.h"
#ifndef NO_DUMMY_DECL
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif
#ifndef STDC #ifndef STDC
extern void exit OF((int)); extern void exit OF((int));
#endif #endif
const char *z_errmsg[10] = { const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */ "need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */ "stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */ "", /* Z_OK 0 */
@ -31,6 +33,89 @@ const char * ZEXPORT zlibVersion()
return ZLIB_VERSION; return ZLIB_VERSION;
} }
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
flags = 0;
switch (sizeof(uInt)) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
switch (sizeof(uLong)) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
switch (sizeof(voidpf)) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
switch (sizeof(z_off_t)) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
#ifdef DEBUG
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
flags += 1 << 9;
#endif
#ifdef ZLIB_WINAPI
flags += 1 << 10;
#endif
#ifdef BUILDFIXED
flags += 1 << 12;
#endif
#ifdef DYNAMIC_CRC_TABLE
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
flags += 1 << 16;
#endif
#ifdef NO_GZIP
flags += 1 << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
flags += 1 << 20;
#endif
#ifdef FASTEST
flags += 1 << 21;
#endif
#ifdef STDC
# ifdef NO_vsnprintf
flags += 1 << 25;
# ifdef HAS_vsprintf_void
flags += 1 << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1 << 26;
# endif
# endif
#else
flags += 1 << 24;
# ifdef NO_snprintf
flags += 1 << 25;
# ifdef HAS_sprintf_void
flags += 1 << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1 << 26;
# endif
# endif
#endif
return flags;
}
#ifdef DEBUG #ifdef DEBUG
# ifndef verbose # ifndef verbose
@ -55,6 +140,10 @@ const char * ZEXPORT zError(err)
return ERR_MSG(err); return ERR_MSG(err);
} }
#if defined(_WIN32_WCE)
/* does not exist on WCE */
int errno = 0;
#endif
#ifndef HAVE_MEMCPY #ifndef HAVE_MEMCPY
@ -93,11 +182,12 @@ void zmemzero(dest, len)
} }
#endif #endif
#ifdef SYS16BIT
#ifdef __TURBOC__ #ifdef __TURBOC__
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) /* Turbo C in 16-bit mode */
/* Small and medium model in Turbo C are for now limited to near allocation
* with reduced MAX_WBITS and MAX_MEM_LEVEL
*/
# define MY_ZCALLOC # define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
@ -169,11 +259,11 @@ void zcfree (voidpf opaque, voidpf ptr)
ptr = opaque; /* just to make some compilers happy */ ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found"); Assert(0, "zcfree: ptr not found");
} }
#endif
#endif /* __TURBOC__ */ #endif /* __TURBOC__ */
#if defined(M_I86) && !defined(__32BIT__) #ifdef M_I86
/* Microsoft C in 16-bit mode */ /* Microsoft C in 16-bit mode */
# define MY_ZCALLOC # define MY_ZCALLOC
@ -195,12 +285,15 @@ void zcfree (voidpf opaque, voidpf ptr)
_hfree(ptr); _hfree(ptr);
} }
#endif /* MSC */ #endif /* M_I86 */
#endif /* SYS16BIT */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC #ifndef STDC
extern voidp malloc OF((uInt size));
extern voidp calloc OF((uInt items, uInt size)); extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr)); extern void free OF((voidpf ptr));
#endif #endif
@ -211,7 +304,8 @@ voidpf zcalloc (opaque, items, size)
unsigned size; unsigned size;
{ {
if (opaque) items += size - size; /* make compiler happy */ if (opaque) items += size - size; /* make compiler happy */
return (voidpf)calloc(items, size); return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
(voidpf)calloc(items, size);
} }
void zcfree (opaque, ptr) void zcfree (opaque, ptr)

View File

@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library /* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@ -10,9 +10,10 @@
/* @(#) $Id$ */ /* @(#) $Id$ */
#ifndef _Z_UTIL_H #ifndef ZUTIL_H
#define _Z_UTIL_H #define ZUTIL_H
#define ZLIB_INTERNAL
#include "zlib.h" #include "zlib.h"
#ifdef STDC #ifdef STDC
@ -37,7 +38,7 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; typedef unsigned long ulg;
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */ /* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
@ -73,7 +74,7 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* target dependencies */ /* target dependencies */
#ifdef MSDOS #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00 # define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__) # if defined(__TURBOC__) || defined(__BORLANDC__)
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
@ -81,19 +82,15 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
void _Cdecl farfree( void *block ); void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes ); void *_Cdecl farmalloc( unsigned long nbytes );
# else # else
# include <alloc.h> # include <alloc.h>
# endif # endif
# else /* MSC or DJGPP */ # else /* MSC or DJGPP */
# include <malloc.h> # include <malloc.h>
# endif # endif
#endif #endif
#ifdef OS2 #ifdef AMIGA
# define OS_CODE 0x06 # define OS_CODE 0x01
#endif
#ifdef WIN32 /* Window 95 & Windows NT */
# define OS_CODE 0x0b
#endif #endif
#if defined(VAXC) || defined(VMS) #if defined(VAXC) || defined(VMS)
@ -102,14 +99,14 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif #endif
#ifdef AMIGA
# define OS_CODE 0x01
#endif
#if defined(ATARI) || defined(atarist) #if defined(ATARI) || defined(atarist)
# define OS_CODE 0x05 # define OS_CODE 0x05
#endif #endif
#ifdef OS2
# define OS_CODE 0x06
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC) #if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07 # define OS_CODE 0x07
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
@ -121,24 +118,37 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
# endif # endif
#endif #endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0F
#endif
#ifdef TOPS20 #ifdef TOPS20
# define OS_CODE 0x0a # define OS_CODE 0x0a
#endif #endif
#ifdef WIN32
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
# define OS_CODE 0x0b
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0f
#endif
#if defined(_BEOS_) || defined(RISCOS) #if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */ # define fdopen(fd,mode) NULL /* No fdopen() */
#endif #endif
#if (defined(_MSC_VER) && (_MSC_VER > 600)) #if (defined(_MSC_VER) && (_MSC_VER > 600))
# define fdopen(fd,type) _fdopen(fd,type) # 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
#endif #endif
/* common defaults */
/* Common defaults */
#ifndef OS_CODE #ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */ # define OS_CODE 0x03 /* assume Unix */
@ -150,6 +160,36 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */ /* functions */
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#if defined(__CYGWIN__)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#ifndef HAVE_VSNPRINTF
# ifdef MSDOS
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
but for now we just assume it doesn't. */
# define NO_vsnprintf
# endif
# ifdef __TURBOC__
# define NO_vsnprintf
# endif
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
# define vsnprintf _vsnprintf
# endif
# endif
# ifdef __SASC
# define NO_vsnprintf
# endif
#endif
#ifdef HAVE_STRERROR #ifdef HAVE_STRERROR
extern char *strerror OF((int)); extern char *strerror OF((int));
# define zstrerror(errnum) strerror(errnum) # define zstrerror(errnum) strerror(errnum)
@ -207,8 +247,6 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
#endif #endif
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
uInt len));
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
void zcfree OF((voidpf opaque, voidpf ptr)); void zcfree OF((voidpf opaque, voidpf ptr));
@ -217,4 +255,4 @@ void zcfree OF((voidpf opaque, voidpf ptr));
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
#endif /* _Z_UTIL_H */ #endif /* ZUTIL_H */