Codebase list deltarpm / d49e64a
Import upstream version 3.6.3+git20220919.1.758b89f+dfsg Debian Janitor 1 year, 5 months ago
196 changed file(s) with 46770 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
+0
-9
.gitignore less more
0 *.o
1 *.a
2 applydeltaiso
3 applydeltarpm
4 combinedeltarpm
5 fragiso
6 makedeltaiso
7 makedeltarpm
8 rpmdumpheader
1111
1212 Options:
1313 -V: create a specific version, default is V3
14 -s: write sequence info into file (usefull for creating
14 -s: write sequence info into file (useful for creating
1515 yast patchfiles)
1616
1717 applydeltarpm [-v] [-p] [-c] [-C] [-r oldrpm] deltarpm newrpm
9595 4 bytes seqlength (always 16 if header included in diff)
9696 x bytes sequence, containing
9797 16 bytes seq md5sum
98 x bytes compressed seqence
98 x bytes compressed sequence
9999 (the sequence defines which files get included from the rpm
100100 filelist in which order)
101101
3838 .B -v
3939 to make it more verbose about its operation.
4040
41 The second an third form can be used to check if the reconstruction
42 is possible. It may fail if the on-disk data got changed
41 The second and third form can be used to check if the reconstruction
42 is possible. It may fail if the on-disk data was changed
4343 (deltarpms are created in a way that config file changes do not
4444 matter) or the deltarpm does not match the rpm the delta was generated
4545 with. The
847847 }
848848
849849
850 /* construct the block "id". Note that the tupel (idx, id) will
850 /* construct the block "id". Note that the tuple (idx, id) will
851851 * only get bigger, so we use this to recycly no longer needed
852852 * blocks */
853853
14481448 if (strcmp(fnevr, (char *)d.nevr) != 0)
14491449 {
14501450 fprintf(stderr, "delta rpm made for %s, not %s\n", d.nevr, fnevr);
1451 exit(1);
1452 }
1451 free(fnevr);
1452 exit(1);
1453 }
1454 free(fnevr);
14531455 if (!seqmatches)
14541456 {
14551457 fprintf(stderr, "rpm does not match the one used for creating the deltarpm\n");
15741576 exit(1);
15751577 }
15761578 rpmMD5Update(&wrmd5, d.h->intro, 16);
1577 strncpy((char *)d.h->dp + d.payformatoff, "cpio", 4);
1579 memcpy((char *)d.h->dp + d.payformatoff, "cpio", 4);
15781580 if (fwrite(d.h->data, 16 * d.h->cnt + d.h->dcnt, 1, ofp) != 1)
15791581 {
15801582 fprintf(stderr, "write error\n");
3535 signature you can also specify a rpm with the
3636 .B -S
3737 option which will be used as signature reference. This feature can
38 be used to if a deltarpm was made against an unsigned rpm which
39 later got signed.
38 be used to if a deltarpm was made against an unsigned rpm which was
39 later signed.
4040
4141 .SH MEMORY CONSIDERATIONS
4242 The implementation of combinedeltarpm currently unpacks the
226226 unsigned int x = 0x83d31df4U;
227227 int i;
228228 for (i = HSIZE; i != 0; i--)
229 x = (x << 1) ^ (x & (1 << 31) ? 1 : 0) ^ noise[*buf++];
229 x = (x << 1) ^ (x & (1u << 31) ? 1 : 0) ^ noise[*buf++];
230230 return x;
231231 }
232232
254254 unsigned int prime;
255255 unsigned int num;
256256
257 hd = malloc(sizeof(*hd));
258 if (!hd)
259 return 0;
260257 #ifdef BSDIFF_64BIT
261258 /* this is a 16GB limit for HSIZESHIFT == 4 */
262259 if (len >= (bsuint)(0xffffffff / 4) << HSIZESHIFT)
263260 return 0;
264261 #endif
262 hd = malloc(sizeof(*hd));
263 if (!hd)
264 return 0;
265265 num = (len + HSIZE - 1) >> HSIZESHIFT;
266266 prime = num * 4;
267267 for (s = 0; s < sizeof(primes)/sizeof(*primes) - 1; s++)
334334 scannext:
335335 if (llen >= 32 && scan - lscan >= HSIZE)
336336 goto gotit;
337 ssx = (ssx << 1) ^ (ssx & (1 << 31) ? 1 : 0) ^ noise[new[scan + HSIZE]];
337 ssx = (ssx << 1) ^ (ssx & (1u << 31) ? 1 : 0) ^ noise[new[scan + HSIZE]];
338338 oldc = noise[new[scan]] ^ (0x83d31df4U ^ 0x07a63be9U);
339339 #if HSIZE % 32 != 0
340340 ssx ^= (oldc << (HSIZE % 32)) ^ (oldc >> (32 - (HSIZE % 32)));
4444 /* Sequence */
4545 if (d.seq) {
4646 char *tmp = calloc(d.seql * 2 + 1, sizeof(char));
47 int i;
47 unsigned int i;
4848
4949 if(tmp == NULL) {
5050 PyErr_SetFromErrno(PyExc_SystemError);
24852485 last if $buf eq "\@RSYNCD: OK";
24862486 die("$buf\n") if $buf =~ /^\@ERROR/s;
24872487 if ($buf =~ /^\@RSYNCD: AUTHREQD /) {
2488 die("'$module' needs authentification, but Digest::MD4 is not installed\n") unless $have_md4;
2488 die("'$module' needs authentication, but Digest::MD4 is not installed\n") unless $have_md4;
24892489 $user = "nobody" if !defined($user) || $user eq '';
24902490 $password = '' unless defined $password;
24912491 my $digest = "$user ".Digest::MD4::md4_base64("\0\0\0\0$password".substr($buf, 18))."\n";
104104 Configures whether drpmsync should request that the full rpm is
105105 always sent along with the delta. Only makes sense if you have a
106106 fast network connection so that applydeltarpm takes longer than
107 transmitting the ful rpm.
107 transmitting the full rpm.
108108 .sp
109109 .ne 3
110110 .B deltarpmpath:
116116 variable.
117117
118118 .SH SERVER MODE
119 Drpmsync can wither work as CGI script or as a standalone server.
119 Drpmsync can either work as CGI script or as a standalone server.
120120 CGI script mode is automatically selected if the
121121 .B REQUEST_METHOD
122122 environment variable is set. In this mode drpmsync expects the
178178 .BR true|false
179179 .PP
180180 If this setting is true the server does not combine deltarpms.
181 This increases to amount of data that has to be transferred but
181 This increases the amount of data that has to be transferred but
182182 reduces the processor load on the server.
183183 .sp
184184 .ne 3
7272 .I oldrpm
7373 and the created
7474 patch rpm. This option tells makedeltarpm to exclude the files that
75 were not included in the patch rpm but are not byteswise identical
75 were not included in the patch rpm but are not bytewise identical
7676 to the ones in oldrpm.
7777 .PP
7878 makedeltarpm can also create an "identity" deltarpm by adding the
8787 .B -m
8888 option to enable a sliding block algorithm that needs
8989 .IR mbytes
90 megabytes of memory. This trades memory usage with the size of
90 megabytes of memory. This trades memory usage for the size of
9191 the created deltarpm. Furthermore, the uncompressed deltarpm
9292 payload is currently also stored in memory when this option is
9393 used, but it tends to be small in most cases.
12321232 if (size != filesizes[i])
12331233 {
12341234 if (verbose > 1)
1235 fprintf(vfp, "skipping %s: size missmatch\n", np);
1235 fprintf(vfp, "skipping %s: size mismatch\n", np);
12361236 skipped_badsize++;
12371237 }
12381238 else if ((fileflags[i] & (FILE_CONFIG|FILE_MISSINGOK|FILE_GHOST)) != 0)
160160 if (ctx->doByteReverse)
161161 byteReverse((unsigned char *) ctx->buf, 4);
162162 memcpy(digest, ctx->buf, 16);
163 memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
163 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
164164 }
165165
166166 /* The four core functions - F1 is optimized somewhat */
287287 {
288288 rpmbalen += 0x800 * 4;
289289 rpmb = realloc(rpmb, rpmbalen);
290 if (!rpmb)
291 {
292 fprintf(stderr, "out of memory\n");
293 exit(1);
294 }
290295 }
291296 readblk(fp, rpmb + rpmblen, filepos2++);
292297 rpmblen += 0x800;
311316 {
312317 rpmbalen += 0x800 * 4;
313318 rpmb = realloc(rpmb, rpmbalen);
319 if (!rpmb)
320 {
321 fprintf(stderr, "out of memory\n");
322 exit(1);
323 }
314324 }
315325 readblk(fp, rpmb + rpmblen, filepos2++);
316326 rpmblen += 0x800;
0
1 Changes for 1.2.2.f (6 May 2005, mls@suse.de)
2 - added rsyncable patch
3 https://svn.uhulinux.hu/packages/dev/zlib/patches/02-rsync.patch
4 - modified patch to honor new Z_RSYNCABLE strategy flag
5
6
7 ChangeLog file for zlib
8
9 Changes in 1.2.2.2 (30 December 2004)
10 - Replace structure assignments in deflate.c and inflate.c with zmemcpy to
11 avoid implicit memcpy calls (portability for no-library compilation)
12 - Increase sprintf() buffer size in gzdopen() to allow for large numbers
13 - Add INFLATE_STRICT to check distances against zlib header
14 - Improve WinCE errno handling and comments [Chang]
15 - Remove comment about no gzip header processing in FAQ
16 - Add Z_FIXED strategy option to deflateInit2() to force fixed trees
17 - Add updated make_vms.com [Coghlan], update README
18 - Create a new "examples" directory, move gzappend.c there, add zpipe.c,
19 fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
20 - Add FAQ entry and comments in deflate.c on uninitialized memory access
21 - Add Solaris 9 make options in configure [Gilbert]
22 - Allow strerror() usage in gzio.c for STDC
23 - Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
24 - Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
25 - Use z_off_t for adler32_combine() and crc32_combine() lengths
26 - Make adler32() much faster for small len
27 - Use OS_CODE in deflate() default gzip header
28
29 Changes in 1.2.2.1 (31 October 2004)
30 - Allow inflateSetDictionary() call for raw inflate
31 - Fix inflate header crc check bug for file names and comments
32 - Add deflateSetHeader() and gz_header structure for custom gzip headers
33 - Add inflateGetheader() to retrieve gzip headers
34 - Add crc32_combine() and adler32_combine() functions
35 - Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
36 - Use zstreamp consistently in zlib.h (inflate_back functions)
37 - Remove GUNZIP condition from definition of inflate_mode in inflate.h
38 and in contrib/inflate86/inffast.S [Truta, Anderson]
39 - Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
40 - Update projects/README.projects and projects/visualc6 [Truta]
41 - Update win32/DLL_FAQ.txt [Truta]
42 - Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
43 - Deprecate Z_ASCII; use Z_TEXT instead [Truta]
44 - Use a new algorithm for setting strm->data_type in trees.c [Truta]
45 - Do not define an exit() prototype in zutil.c unless DEBUG defined
46 - Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
47 - Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
48 - Fix Darwin build version identification [Peterson]
49
50 Changes in 1.2.2 (3 October 2004)
51 - Update zlib.h comments on gzip in-memory processing
52 - Set adler to 1 in inflateReset() to support Java test suite [Walles]
53 - Add contrib/dotzlib [Ravn]
54 - Update win32/DLL_FAQ.txt [Truta]
55 - Update contrib/minizip [Vollant]
56 - Move contrib/visual-basic.txt to old/ [Truta]
57 - Fix assembler builds in projects/visualc6/ [Truta]
58
59 Changes in 1.2.1.2 (9 September 2004)
60 - Update INDEX file
61 - Fix trees.c to update strm->data_type (no one ever noticed!)
62 - Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
63 - Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
64 - Add limited multitasking protection to DYNAMIC_CRC_TABLE
65 - Add NO_vsnprintf for VMS in zutil.h [Mozilla]
66 - Don't declare strerror() under VMS [Mozilla]
67 - Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
68 - Update contrib/ada [Anisimkov]
69 - Update contrib/minizip [Vollant]
70 - Fix configure to not hardcode directories for Darwin [Peterson]
71 - Fix gzio.c to not return error on empty files [Brown]
72 - Fix indentation; update version in contrib/delphi/ZLib.pas and
73 contrib/pascal/zlibpas.pas [Truta]
74 - Update mkasm.bat in contrib/masmx86 [Truta]
75 - Update contrib/untgz [Truta]
76 - Add projects/README.projects [Truta]
77 - Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
78 - Update win32/DLL_FAQ.txt [Truta]
79 - Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
80 - Remove an unnecessary assignment to curr in inftrees.c [Truta]
81 - Add OS/2 to exe builds in configure [Poltorak]
82 - Remove err dummy parameter in zlib.h [Kientzle]
83
84 Changes in 1.2.1.1 (9 January 2004)
85 - Update email address in README
86 - Several FAQ updates
87 - Fix a big fat bug in inftrees.c that prevented decoding valid
88 dynamic blocks with only literals and no distance codes --
89 Thanks to "Hot Emu" for the bug report and sample file
90 - Add a note to puff.c on no distance codes case.
91
92 Changes in 1.2.1 (17 November 2003)
93 - Remove a tab in contrib/gzappend/gzappend.c
94 - Update some interfaces in contrib for new zlib functions
95 - Update zlib version number in some contrib entries
96 - Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
97 - Support shared libraries on Hurd and KFreeBSD [Brown]
98 - Fix error in NO_DIVIDE option of adler32.c
99
100 Changes in 1.2.0.8 (4 November 2003)
101 - Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
102 - Add experimental NO_DIVIDE #define in adler32.c
103 - Possibly faster on some processors (let me know if it is)
104 - Correct Z_BLOCK to not return on first inflate call if no wrap
105 - Fix strm->data_type on inflate() return to correctly indicate EOB
106 - Add deflatePrime() function for appending in the middle of a byte
107 - Add contrib/gzappend for an example of appending to a stream
108 - Update win32/DLL_FAQ.txt [Truta]
109 - Delete Turbo C comment in README [Truta]
110 - Improve some indentation in zconf.h [Truta]
111 - Fix infinite loop on bad input in configure script [Church]
112 - Fix gzeof() for concatenated gzip files [Johnson]
113 - Add example to contrib/visual-basic.txt [Michael B.]
114 - Add -p to mkdir's in Makefile.in [vda]
115 - Fix configure to properly detect presence or lack of printf functions
116 - Add AS400 support [Monnerat]
117 - Add a little Cygwin support [Wilson]
118
119 Changes in 1.2.0.7 (21 September 2003)
120 - Correct some debug formats in contrib/infback9
121 - Cast a type in a debug statement in trees.c
122 - Change search and replace delimiter in configure from % to # [Beebe]
123 - Update contrib/untgz to 0.2 with various fixes [Truta]
124 - Add build support for Amiga [Nikl]
125 - Remove some directories in old that have been updated to 1.2
126 - Add dylib building for Mac OS X in configure and Makefile.in
127 - Remove old distribution stuff from Makefile
128 - Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
129 - Update links in README
130
131 Changes in 1.2.0.6 (13 September 2003)
132 - Minor FAQ updates
133 - Update contrib/minizip to 1.00 [Vollant]
134 - Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
135 - Update POSTINC comment for 68060 [Nikl]
136 - Add contrib/infback9 with deflate64 decoding (unsupported)
137 - For MVS define NO_vsnprintf and undefine FAR [van Burik]
138 - Add pragma for fdopen on MVS [van Burik]
139
140 Changes in 1.2.0.5 (8 September 2003)
141 - Add OF to inflateBackEnd() declaration in zlib.h
142 - Remember start when using gzdopen in the middle of a file
143 - Use internal off_t counters in gz* functions to properly handle seeks
144 - Perform more rigorous check for distance-too-far in inffast.c
145 - Add Z_BLOCK flush option to return from inflate at block boundary
146 - Set strm->data_type on return from inflate
147 - Indicate bits unused, if at block boundary, and if in last block
148 - Replace size_t with ptrdiff_t in crc32.c, and check for correct size
149 - Add condition so old NO_DEFLATE define still works for compatibility
150 - FAQ update regarding the Windows DLL [Truta]
151 - INDEX update: add qnx entry, remove aix entry [Truta]
152 - Install zlib.3 into mandir [Wilson]
153 - Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
154 - Adapt the zlib interface to the new DLL convention guidelines [Truta]
155 - Introduce ZLIB_WINAPI macro to allow the export of functions using
156 the WINAPI calling convention, for Visual Basic [Vollant, Truta]
157 - Update msdos and win32 scripts and makefiles [Truta]
158 - Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
159 - Add contrib/ada [Anisimkov]
160 - Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
161 - Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
162 - Add contrib/masm686 [Truta]
163 - Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
164 [Truta, Vollant]
165 - Update contrib/delphi; rename to contrib/pascal; add example [Truta]
166 - Remove contrib/delphi2; add a new contrib/delphi [Truta]
167 - Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
168 and fix some method prototypes [Truta]
169 - Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
170 [Truta]
171 - Avoid the use of backslash (\) in contrib/minizip [Vollant]
172 - Fix file time handling in contrib/untgz; update makefiles [Truta]
173 - Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
174 [Vollant]
175 - Remove contrib/vstudio/vc15_16 [Vollant]
176 - Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
177 - Update README.contrib [Truta]
178 - Invert the assignment order of match_head and s->prev[...] in
179 INSERT_STRING [Truta]
180 - Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
181 [Truta]
182 - Compare function pointers with 0, not with NULL or Z_NULL [Truta]
183 - Fix prototype of syncsearch in inflate.c [Truta]
184 - Introduce ASMINF macro to be enabled when using an ASM implementation
185 of inflate_fast [Truta]
186 - Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
187 - Modify test_gzio in example.c to take a single file name as a
188 parameter [Truta]
189 - Exit the example.c program if gzopen fails [Truta]
190 - Add type casts around strlen in example.c [Truta]
191 - Remove casting to sizeof in minigzip.c; give a proper type
192 to the variable compared with SUFFIX_LEN [Truta]
193 - Update definitions of STDC and STDC99 in zconf.h [Truta]
194 - Synchronize zconf.h with the new Windows DLL interface [Truta]
195 - Use SYS16BIT instead of __32BIT__ to distinguish between
196 16- and 32-bit platforms [Truta]
197 - Use far memory allocators in small 16-bit memory models for
198 Turbo C [Truta]
199 - Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
200 zlibCompileFlags [Truta]
201 - Cygwin has vsnprintf [Wilson]
202 - In Windows16, OS_CODE is 0, as in MSDOS [Truta]
203 - In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
204
205 Changes in 1.2.0.4 (10 August 2003)
206 - Minor FAQ updates
207 - Be more strict when checking inflateInit2's windowBits parameter
208 - Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
209 - Add gzip wrapper option to deflateInit2 using windowBits
210 - Add updated QNX rule in configure and qnx directory [Bonnefoy]
211 - Make inflate distance-too-far checks more rigorous
212 - Clean up FAR usage in inflate
213 - Add casting to sizeof() in gzio.c and minigzip.c
214
215 Changes in 1.2.0.3 (19 July 2003)
216 - Fix silly error in gzungetc() implementation [Vollant]
217 - Update contrib/minizip and contrib/vstudio [Vollant]
218 - Fix printf format in example.c
219 - Correct cdecl support in zconf.in.h [Anisimkov]
220 - Minor FAQ updates
221
222 Changes in 1.2.0.2 (13 July 2003)
223 - Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
224 - Attempt to avoid warnings in crc32.c for pointer-int conversion
225 - Add AIX to configure, remove aix directory [Bakker]
226 - Add some casts to minigzip.c
227 - Improve checking after insecure sprintf() or vsprintf() calls
228 - Remove #elif's from crc32.c
229 - Change leave label to inf_leave in inflate.c and infback.c to avoid
230 library conflicts
231 - Remove inflate gzip decoding by default--only enable gzip decoding by
232 special request for stricter backward compatibility
233 - Add zlibCompileFlags() function to return compilation information
234 - More typecasting in deflate.c to avoid warnings
235 - Remove leading underscore from _Capital #defines [Truta]
236 - Fix configure to link shared library when testing
237 - Add some Windows CE target adjustments [Mai]
238 - Remove #define ZLIB_DLL in zconf.h [Vollant]
239 - Add zlib.3 [Rodgers]
240 - Update RFC URL in deflate.c and algorithm.txt [Mai]
241 - Add zlib_dll_FAQ.txt to contrib [Truta]
242 - Add UL to some constants [Truta]
243 - Update minizip and vstudio [Vollant]
244 - Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
245 - Expand use of NO_DUMMY_DECL to avoid all dummy structures
246 - Added iostream3 to contrib [Schwardt]
247 - Replace rewind() with fseek() for WinCE [Truta]
248 - Improve setting of zlib format compression level flags
249 - Report 0 for huffman and rle strategies and for level == 0 or 1
250 - Report 2 only for level == 6
251 - Only deal with 64K limit when necessary at compile time [Truta]
252 - Allow TOO_FAR check to be turned off at compile time [Truta]
253 - Add gzclearerr() function [Souza]
254 - Add gzungetc() function
255
256 Changes in 1.2.0.1 (17 March 2003)
257 - Add Z_RLE strategy for run-length encoding [Truta]
258 - When Z_RLE requested, restrict matches to distance one
259 - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
260 - Correct FASTEST compilation to allow level == 0
261 - Clean up what gets compiled for FASTEST
262 - Incorporate changes to zconf.in.h [Vollant]
263 - Refine detection of Turbo C need for dummy returns
264 - Refine ZLIB_DLL compilation
265 - Include additional header file on VMS for off_t typedef
266 - Try to use _vsnprintf where it supplants vsprintf [Vollant]
267 - Add some casts in inffast.c
268 - Enchance comments in zlib.h on what happens if gzprintf() tries to
269 write more than 4095 bytes before compression
270 - Remove unused state from inflateBackEnd()
271 - Remove exit(0) from minigzip.c, example.c
272 - Get rid of all those darn tabs
273 - Add "check" target to Makefile.in that does the same thing as "test"
274 - Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
275 - Update contrib/inflate86 [Anderson]
276 - Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
277 - Add msdos and win32 directories with makefiles [Truta]
278 - More additions and improvements to the FAQ
279
280 Changes in 1.2.0 (9 March 2003)
281 - New and improved inflate code
282 - About 20% faster
283 - Does not allocate 32K window unless and until needed
284 - Automatically detects and decompresses gzip streams
285 - Raw inflate no longer needs an extra dummy byte at end
286 - Added inflateBack functions using a callback interface--even faster
287 than inflate, useful for file utilities (gzip, zip)
288 - Added inflateCopy() function to record state for random access on
289 externally generated deflate streams (e.g. in gzip files)
290 - More readable code (I hope)
291 - New and improved crc32()
292 - About 50% faster, thanks to suggestions from Rodney Brown
293 - Add deflateBound() and compressBound() functions
294 - Fix memory leak in deflateInit2()
295 - Permit setting dictionary for raw deflate (for parallel deflate)
296 - Fix const declaration for gzwrite()
297 - Check for some malloc() failures in gzio.c
298 - Fix bug in gzopen() on single-byte file 0x1f
299 - Fix bug in gzread() on concatenated file with 0x1f at end of buffer
300 and next buffer doesn't start with 0x8b
301 - Fix uncompress() to return Z_DATA_ERROR on truncated input
302 - Free memory at end of example.c
303 - Remove MAX #define in trees.c (conflicted with some libraries)
304 - Fix static const's in deflate.c, gzio.c, and zutil.[ch]
305 - Declare malloc() and free() in gzio.c if STDC not defined
306 - Use malloc() instead of calloc() in zutil.c if int big enough
307 - Define STDC for AIX
308 - Add aix/ with approach for compiling shared library on AIX
309 - Add HP-UX support for shared libraries in configure
310 - Add OpenUNIX support for shared libraries in configure
311 - Use $cc instead of gcc to build shared library
312 - Make prefix directory if needed when installing
313 - Correct Macintosh avoidance of typedef Byte in zconf.h
314 - Correct Turbo C memory allocation when under Linux
315 - Use libz.a instead of -lz in Makefile (assure use of compiled library)
316 - Update configure to check for snprintf or vsnprintf functions and their
317 return value, warn during make if using an insecure function
318 - Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
319 is lost when library is used--resolution is to build new zconf.h
320 - Documentation improvements (in zlib.h):
321 - Document raw deflate and inflate
322 - Update RFCs URL
323 - Point out that zlib and gzip formats are different
324 - Note that Z_BUF_ERROR is not fatal
325 - Document string limit for gzprintf() and possible buffer overflow
326 - Note requirement on avail_out when flushing
327 - Note permitted values of flush parameter of inflate()
328 - Add some FAQs (and even answers) to the FAQ
329 - Add contrib/inflate86/ for x86 faster inflate
330 - Add contrib/blast/ for PKWare Data Compression Library decompression
331 - Add contrib/puff/ simple inflate for deflate format description
332
333 Changes in 1.1.4 (11 March 2002)
334 - ZFREE was repeated on same allocation on some error conditions.
335 This creates a security problem described in
336 http://www.zlib.org/advisory-2002-03-11.txt
337 - Returned incorrect error (Z_MEM_ERROR) on some invalid data
338 - Avoid accesses before window for invalid distances with inflate window
339 less than 32K.
340 - force windowBits > 8 to avoid a bug in the encoder for a window size
341 of 256 bytes. (A complete fix will be available in 1.1.5).
342
343 Changes in 1.1.3 (9 July 1998)
344 - fix "an inflate input buffer bug that shows up on rare but persistent
345 occasions" (Mark)
346 - fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
347 - fix gzseek(..., SEEK_SET) in write mode
348 - fix crc check after a gzeek (Frank Faubert)
349 - fix miniunzip when the last entry in a zip file is itself a zip file
350 (J Lillge)
351 - add contrib/asm586 and contrib/asm686 (Brian Raiter)
352 See http://www.muppetlabs.com/~breadbox/software/assembly.html
353 - add support for Delphi 3 in contrib/delphi (Bob Dellaca)
354 - add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
355 - do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
356 - use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
357 - added a FAQ file
358
359 - Support gzdopen on Mac with Metrowerks (Jason Linhart)
360 - Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
361 - define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
362 - avoid some warnings with Borland C (Tom Tanner)
363 - fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
364 - emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
365 - allow several arguments to configure (Tim Mooney, Frodo Looijaard)
366 - use libdir and includedir in Makefile.in (Tim Mooney)
367 - support shared libraries on OSF1 V4 (Tim Mooney)
368 - remove so_locations in "make clean" (Tim Mooney)
369 - fix maketree.c compilation error (Glenn, Mark)
370 - Python interface to zlib now in Python 1.5 (Jeremy Hylton)
371 - new Makefile.riscos (Rich Walker)
372 - initialize static descriptors in trees.c for embedded targets (Nick Smith)
373 - use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
374 - add the OS/2 files in Makefile.in too (Andrew Zabolotny)
375 - fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
376 - fix maketree.c to allow clean compilation of inffixed.h (Mark)
377 - fix parameter check in deflateCopy (Gunther Nikl)
378 - cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
379 - Many portability patches by Christian Spieler:
380 . zutil.c, zutil.h: added "const" for zmem*
381 . Make_vms.com: fixed some typos
382 . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
383 . msdos/Makefile.msc: remove "default rtl link library" info from obj files
384 . msdos/Makefile.*: use model-dependent name for the built zlib library
385 . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
386 new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
387 - use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
388 - replace __far with _far for better portability (Christian Spieler, Tom Lane)
389 - fix test for errno.h in configure (Tim Newsham)
390
391 Changes in 1.1.2 (19 March 98)
392 - added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
393 See http://www.winimage.com/zLibDll/unzip.html
394 - preinitialize the inflate tables for fixed codes, to make the code
395 completely thread safe (Mark)
396 - some simplifications and slight speed-up to the inflate code (Mark)
397 - fix gzeof on non-compressed files (Allan Schrum)
398 - add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
399 - use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
400 - added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
401 - add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
402 - do not wrap extern "C" around system includes (Tom Lane)
403 - mention zlib binding for TCL in README (Andreas Kupries)
404 - added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
405 - allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
406 - allow "configure --prefix $HOME" (Tim Mooney)
407 - remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
408 - move Makefile.sas to amiga/Makefile.sas
409
410 Changes in 1.1.1 (27 Feb 98)
411 - fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
412 - remove block truncation heuristic which had very marginal effect for zlib
413 (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
414 compression ratio on some files. This also allows inlining _tr_tally for
415 matches in deflate_slow.
416 - added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
417
418 Changes in 1.1.0 (24 Feb 98)
419 - do not return STREAM_END prematurely in inflate (John Bowler)
420 - revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
421 - compile with -DFASTEST to get compression code optimized for speed only
422 - in minigzip, try mmap'ing the input file first (Miguel Albrecht)
423 - increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
424 on Sun but significant on HP)
425
426 - add a pointer to experimental unzip library in README (Gilles Vollant)
427 - initialize variable gcc in configure (Chris Herborth)
428
429 Changes in 1.0.9 (17 Feb 1998)
430 - added gzputs and gzgets functions
431 - do not clear eof flag in gzseek (Mark Diekhans)
432 - fix gzseek for files in transparent mode (Mark Diekhans)
433 - do not assume that vsprintf returns the number of bytes written (Jens Krinke)
434 - replace EXPORT with ZEXPORT to avoid conflict with other programs
435 - added compress2 in zconf.h, zlib.def, zlib.dnt
436 - new asm code from Gilles Vollant in contrib/asm386
437 - simplify the inflate code (Mark):
438 . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
439 . ZALLOC the length list in inflate_trees_fixed() instead of using stack
440 . ZALLOC the value area for huft_build() instead of using stack
441 . Simplify Z_FINISH check in inflate()
442
443 - Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
444 - in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
445 - in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
446 the declaration of FAR (Gilles VOllant)
447 - install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
448 - read_buf buf parameter of type Bytef* instead of charf*
449 - zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
450 - do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
451 - fix check for presence of directories in "make install" (Ian Willis)
452
453 Changes in 1.0.8 (27 Jan 1998)
454 - fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
455 - fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
456 - added compress2() to allow setting the compression level
457 - include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
458 - use constant arrays for the static trees in trees.c instead of computing
459 them at run time (thanks to Ken Raeburn for this suggestion). To create
460 trees.h, compile with GEN_TREES_H and run "make test".
461 - check return code of example in "make test" and display result
462 - pass minigzip command line options to file_compress
463 - simplifying code of inflateSync to avoid gcc 2.8 bug
464
465 - support CC="gcc -Wall" in configure -s (QingLong)
466 - avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
467 - fix test for shared library support to avoid compiler warnings
468 - zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
469 - check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
470 - do not use fdopen for Metrowerks on Mac (Brad Pettit))
471 - add checks for gzputc and gzputc in example.c
472 - avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
473 - use const for the CRC table (Ken Raeburn)
474 - fixed "make uninstall" for shared libraries
475 - use Tracev instead of Trace in infblock.c
476 - in example.c use correct compressed length for test_sync
477 - suppress +vnocompatwarnings in configure for HPUX (not always supported)
478
479 Changes in 1.0.7 (20 Jan 1998)
480 - fix gzseek which was broken in write mode
481 - return error for gzseek to negative absolute position
482 - fix configure for Linux (Chun-Chung Chen)
483 - increase stack space for MSC (Tim Wegner)
484 - get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
485 - define EXPORTVA for gzprintf (Gilles Vollant)
486 - added man page zlib.3 (Rick Rodgers)
487 - for contrib/untgz, fix makedir() and improve Makefile
488
489 - check gzseek in write mode in example.c
490 - allocate extra buffer for seeks only if gzseek is actually called
491 - avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
492 - add inflateSyncPoint in zconf.h
493 - fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
494
495 Changes in 1.0.6 (19 Jan 1998)
496 - add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
497 gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
498 - Fix a deflate bug occuring only with compression level 0 (thanks to
499 Andy Buckler for finding this one).
500 - In minigzip, pass transparently also the first byte for .Z files.
501 - return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
502 - check Z_FINISH in inflate (thanks to Marc Schluper)
503 - Implement deflateCopy (thanks to Adam Costello)
504 - make static libraries by default in configure, add --shared option.
505 - move MSDOS or Windows specific files to directory msdos
506 - suppress the notion of partial flush to simplify the interface
507 (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
508 - suppress history buffer provided by application to simplify the interface
509 (this feature was not implemented anyway in 1.0.4)
510 - next_in and avail_in must be initialized before calling inflateInit or
511 inflateInit2
512 - add EXPORT in all exported functions (for Windows DLL)
513 - added Makefile.nt (thanks to Stephen Williams)
514 - added the unsupported "contrib" directory:
515 contrib/asm386/ by Gilles Vollant <info@winimage.com>
516 386 asm code replacing longest_match().
517 contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
518 A C++ I/O streams interface to the zlib gz* functions
519 contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
520 Another C++ I/O streams interface
521 contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
522 A very simple tar.gz file extractor using zlib
523 contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
524 How to use compress(), uncompress() and the gz* functions from VB.
525 - pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
526 level) in minigzip (thanks to Tom Lane)
527
528 - use const for rommable constants in deflate
529 - added test for gzseek and gztell in example.c
530 - add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
531 - add undocumented function zError to convert error code to string
532 (for Tim Smithers)
533 - Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
534 - Use default memcpy for Symantec MSDOS compiler.
535 - Add EXPORT keyword for check_func (needed for Windows DLL)
536 - add current directory to LD_LIBRARY_PATH for "make test"
537 - create also a link for libz.so.1
538 - added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
539 - use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
540 - added -soname for Linux in configure (Chun-Chung Chen,
541 - assign numbers to the exported functions in zlib.def (for Windows DLL)
542 - add advice in zlib.h for best usage of deflateSetDictionary
543 - work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
544 - allow compilation with ANSI keywords only enabled for TurboC in large model
545 - avoid "versionString"[0] (Borland bug)
546 - add NEED_DUMMY_RETURN for Borland
547 - use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
548 - allow compilation with CC
549 - defined STDC for OS/2 (David Charlap)
550 - limit external names to 8 chars for MVS (Thomas Lund)
551 - in minigzip.c, use static buffers only for 16-bit systems
552 - fix suffix check for "minigzip -d foo.gz"
553 - do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
554 - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
555 - added makelcc.bat for lcc-win32 (Tom St Denis)
556 - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
557 - Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
558 - check for unistd.h in configure (for off_t)
559 - remove useless check parameter in inflate_blocks_free
560 - avoid useless assignment of s->check to itself in inflate_blocks_new
561 - do not flush twice in gzclose (thanks to Ken Raeburn)
562 - rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
563 - use NO_ERRNO_H instead of enumeration of operating systems with errno.h
564 - work around buggy fclose on pipes for HP/UX
565 - support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
566 - fix configure if CC is already equal to gcc
567
568 Changes in 1.0.5 (3 Jan 98)
569 - Fix inflate to terminate gracefully when fed corrupted or invalid data
570 - Use const for rommable constants in inflate
571 - Eliminate memory leaks on error conditions in inflate
572 - Removed some vestigial code in inflate
573 - Update web address in README
574
575 Changes in 1.0.4 (24 Jul 96)
576 - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
577 bit, so the decompressor could decompress all the correct data but went
578 on to attempt decompressing extra garbage data. This affected minigzip too.
579 - zlibVersion and gzerror return const char* (needed for DLL)
580 - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
581 - use z_error only for DEBUG (avoid problem with DLLs)
582
583 Changes in 1.0.3 (2 Jul 96)
584 - use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
585 small and medium models; this makes the library incompatible with previous
586 versions for these models. (No effect in large model or on other systems.)
587 - return OK instead of BUF_ERROR if previous deflate call returned with
588 avail_out as zero but there is nothing to do
589 - added memcmp for non STDC compilers
590 - define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
591 - define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
592 - better check for 16-bit mode MSC (avoids problem with Symantec)
593
594 Changes in 1.0.2 (23 May 96)
595 - added Windows DLL support
596 - added a function zlibVersion (for the DLL support)
597 - fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
598 - Bytef is define's instead of typedef'd only for Borland C
599 - avoid reading uninitialized memory in example.c
600 - mention in README that the zlib format is now RFC1950
601 - updated Makefile.dj2
602 - added algorithm.doc
603
604 Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
605 - fix array overlay in deflate.c which sometimes caused bad compressed data
606 - fix inflate bug with empty stored block
607 - fix MSDOS medium model which was broken in 0.99
608 - fix deflateParams() which could generated bad compressed data.
609 - Bytef is define'd instead of typedef'ed (work around Borland bug)
610 - added an INDEX file
611 - new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
612 Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
613 - speed up adler32 for modern machines without auto-increment
614 - added -ansi for IRIX in configure
615 - static_init_done in trees.c is an int
616 - define unlink as delete for VMS
617 - fix configure for QNX
618 - add configure branch for SCO and HPUX
619 - avoid many warnings (unused variables, dead assignments, etc...)
620 - no fdopen for BeOS
621 - fix the Watcom fix for 32 bit mode (define FAR as empty)
622 - removed redefinition of Byte for MKWERKS
623 - work around an MWKERKS bug (incorrect merge of all .h files)
624
625 Changes in 0.99 (27 Jan 96)
626 - allow preset dictionary shared between compressor and decompressor
627 - allow compression level 0 (no compression)
628 - add deflateParams in zlib.h: allow dynamic change of compression level
629 and compression strategy.
630 - test large buffers and deflateParams in example.c
631 - add optional "configure" to build zlib as a shared library
632 - suppress Makefile.qnx, use configure instead
633 - fixed deflate for 64-bit systems (detected on Cray)
634 - fixed inflate_blocks for 64-bit systems (detected on Alpha)
635 - declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
636 - always return Z_BUF_ERROR when deflate() has nothing to do
637 - deflateInit and inflateInit are now macros to allow version checking
638 - prefix all global functions and types with z_ with -DZ_PREFIX
639 - make falloc completely reentrant (inftrees.c)
640 - fixed very unlikely race condition in ct_static_init
641 - free in reverse order of allocation to help memory manager
642 - use zlib-1.0/* instead of zlib/* inside the tar.gz
643 - make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
644 -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
645 - allow gzread on concatenated .gz files
646 - deflateEnd now returns Z_DATA_ERROR if it was premature
647 - deflate is finally (?) fully deterministic (no matches beyond end of input)
648 - Document Z_SYNC_FLUSH
649 - add uninstall in Makefile
650 - Check for __cpluplus in zlib.h
651 - Better test in ct_align for partial flush
652 - avoid harmless warnings for Borland C++
653 - initialize hash_head in deflate.c
654 - avoid warning on fdopen (gzio.c) for HP cc -Aa
655 - include stdlib.h for STDC compilers
656 - include errno.h for Cray
657 - ignore error if ranlib doesn't exist
658 - call ranlib twice for NeXTSTEP
659 - use exec_prefix instead of prefix for libz.a
660 - renamed ct_* as _tr_* to avoid conflict with applications
661 - clear z->msg in inflateInit2 before any error return
662 - initialize opaque in example.c, gzio.c, deflate.c and inflate.c
663 - fixed typo in zconf.h (_GNUC__ => __GNUC__)
664 - check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
665 - fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
666 - in fcalloc, normalize pointer if size > 65520 bytes
667 - don't use special fcalloc for 32 bit Borland C++
668 - use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
669 - use Z_BINARY instead of BINARY
670 - document that gzclose after gzdopen will close the file
671 - allow "a" as mode in gzopen.
672 - fix error checking in gzread
673 - allow skipping .gz extra-field on pipes
674 - added reference to Perl interface in README
675 - put the crc table in FAR data (I dislike more and more the medium model :)
676 - added get_crc_table
677 - added a dimension to all arrays (Borland C can't count).
678 - workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
679 - guard against multiple inclusion of *.h (for precompiled header on Mac)
680 - Watcom C pretends to be Microsoft C small model even in 32 bit mode.
681 - don't use unsized arrays to avoid silly warnings by Visual C++:
682 warning C4746: 'inflate_mask' : unsized array treated as '__far'
683 (what's wrong with far data in far model?).
684 - define enum out of inflate_blocks_state to allow compilation with C++
685
686 Changes in 0.95 (16 Aug 95)
687 - fix MSDOS small and medium model (now easier to adapt to any compiler)
688 - inlined send_bits
689 - fix the final (:-) bug for deflate with flush (output was correct but
690 not completely flushed in rare occasions).
691 - default window size is same for compression and decompression
692 (it's now sufficient to set MAX_WBITS in zconf.h).
693 - voidp -> voidpf and voidnp -> voidp (for consistency with other
694 typedefs and because voidnp was not near in large model).
695
696 Changes in 0.94 (13 Aug 95)
697 - support MSDOS medium model
698 - fix deflate with flush (could sometimes generate bad output)
699 - fix deflateReset (zlib header was incorrectly suppressed)
700 - added support for VMS
701 - allow a compression level in gzopen()
702 - gzflush now calls fflush
703 - For deflate with flush, flush even if no more input is provided.
704 - rename libgz.a as libz.a
705 - avoid complex expression in infcodes.c triggering Turbo C bug
706 - work around a problem with gcc on Alpha (in INSERT_STRING)
707 - don't use inline functions (problem with some gcc versions)
708 - allow renaming of Byte, uInt, etc... with #define.
709 - avoid warning about (unused) pointer before start of array in deflate.c
710 - avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
711 - avoid reserved word 'new' in trees.c
712
713 Changes in 0.93 (25 June 95)
714 - temporarily disable inline functions
715 - make deflate deterministic
716 - give enough lookahead for PARTIAL_FLUSH
717 - Set binary mode for stdin/stdout in minigzip.c for OS/2
718 - don't even use signed char in inflate (not portable enough)
719 - fix inflate memory leak for segmented architectures
720
721 Changes in 0.92 (3 May 95)
722 - don't assume that char is signed (problem on SGI)
723 - Clear bit buffer when starting a stored block
724 - no memcpy on Pyramid
725 - suppressed inftest.c
726 - optimized fill_window, put longest_match inline for gcc
727 - optimized inflate on stored blocks.
728 - untabify all sources to simplify patches
729
730 Changes in 0.91 (2 May 95)
731 - Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
732 - Document the memory requirements in zconf.h
733 - added "make install"
734 - fix sync search logic in inflateSync
735 - deflate(Z_FULL_FLUSH) now works even if output buffer too short
736 - after inflateSync, don't scare people with just "lo world"
737 - added support for DJGPP
738
739 Changes in 0.9 (1 May 95)
740 - don't assume that zalloc clears the allocated memory (the TurboC bug
741 was Mark's bug after all :)
742 - let again gzread copy uncompressed data unchanged (was working in 0.71)
743 - deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
744 - added a test of inflateSync in example.c
745 - moved MAX_WBITS to zconf.h because users might want to change that.
746 - document explicitly that zalloc(64K) on MSDOS must return a normalized
747 pointer (zero offset)
748 - added Makefiles for Microsoft C, Turbo C, Borland C++
749 - faster crc32()
750
751 Changes in 0.8 (29 April 95)
752 - added fast inflate (inffast.c)
753 - deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
754 is incompatible with previous versions of zlib which returned Z_OK.
755 - work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
756 (actually that was not a compiler bug, see 0.81 above)
757 - gzread no longer reads one extra byte in certain cases
758 - In gzio destroy(), don't reference a freed structure
759 - avoid many warnings for MSDOS
760 - avoid the ERROR symbol which is used by MS Windows
761
762 Changes in 0.71 (14 April 95)
763 - Fixed more MSDOS compilation problems :( There is still a bug with
764 TurboC large model.
765
766 Changes in 0.7 (14 April 95)
767 - Added full inflate support.
768 - Simplified the crc32() interface. The pre- and post-conditioning
769 (one's complement) is now done inside crc32(). WARNING: this is
770 incompatible with previous versions; see zlib.h for the new usage.
771
772 Changes in 0.61 (12 April 95)
773 - workaround for a bug in TurboC. example and minigzip now work on MSDOS.
774
775 Changes in 0.6 (11 April 95)
776 - added minigzip.c
777 - added gzdopen to reopen a file descriptor as gzFile
778 - added transparent reading of non-gziped files in gzread.
779 - fixed bug in gzread (don't read crc as data)
780 - fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
781 - don't allocate big arrays in the stack (for MSDOS)
782 - fix some MSDOS compilation problems
783
784 Changes in 0.5:
785 - do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
786 not yet Z_FULL_FLUSH.
787 - support decompression but only in a single step (forced Z_FINISH)
788 - added opaque object for zalloc and zfree.
789 - added deflateReset and inflateReset
790 - added a variable zlib_version for consistency checking.
791 - renamed the 'filter' parameter of deflateInit2 as 'strategy'.
792 Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
793
794 Changes in 0.4:
795 - avoid "zip" everywhere, use zlib instead of ziplib.
796 - suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
797 if compression method == 8.
798 - added adler32 and crc32
799 - renamed deflateOptions as deflateInit2, call one or the other but not both
800 - added the method parameter for deflateInit2.
801 - added inflateInit2
802 - simplied considerably deflateInit and inflateInit by not supporting
803 user-provided history buffer. This is supported only in deflateInit2
804 and inflateInit2.
805
806 Changes in 0.3:
807 - prefix all macro names with Z_
808 - use Z_FINISH instead of deflateEnd to finish compression.
809 - added Z_HUFFMAN_ONLY
810 - added gzerror()
0
1 Frequently Asked Questions about zlib
2
3
4 If your question is not there, please check the zlib home page
5 http://www.zlib.org which may have more recent information.
6 The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
7
8
9 1. Is zlib Y2K-compliant?
10
11 Yes. zlib doesn't handle dates.
12
13 2. Where can I get a Windows DLL version?
14
15 The zlib sources can be compiled without change to produce a DLL.
16 See the file win32/DLL_FAQ.txt in the zlib distribution.
17 Pointers to the precompiled DLL are found in the zlib web site at
18 http://www.zlib.org.
19
20 3. Where can I get a Visual Basic interface to zlib?
21
22 See
23 * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
24 * contrib/visual-basic.txt in the zlib distribution
25 * win32/DLL_FAQ.txt in the zlib distribution
26
27 4. compress() returns Z_BUF_ERROR.
28
29 Make sure that before the call of compress, the length of the compressed
30 buffer is equal to the total size of the compressed buffer and not
31 zero. For Visual Basic, check that this parameter is passed by reference
32 ("as any"), not by value ("as long").
33
34 5. deflate() or inflate() returns Z_BUF_ERROR.
35
36 Before making the call, make sure that avail_in and avail_out are not
37 zero. When setting the parameter flush equal to Z_FINISH, also make sure
38 that avail_out is big enough to allow processing all pending input.
39 Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
40 inflate() can be made with more input or output space. A Z_BUF_ERROR
41 may in fact be unavoidable depending on how the functions are used, since
42 it is not possible to tell whether or not there is more output pending
43 when strm.avail_out returns with zero.
44
45 6. Where's the zlib documentation (man pages, etc.)?
46
47 It's in zlib.h for the moment, and Francis S. Lin has converted it to a
48 web page zlib.html. Volunteers to transform this to Unix-style man pages,
49 please contact us (zlib@gzip.org). Examples of zlib usage are in the files
50 example.c and minigzip.c.
51
52 7. Why don't you use GNU autoconf or libtool or ...?
53
54 Because we would like to keep zlib as a very small and simple
55 package. zlib is rather portable and doesn't need much configuration.
56
57 8. I found a bug in zlib.
58
59 Most of the time, such problems are due to an incorrect usage of
60 zlib. Please try to reproduce the problem with a small program and send
61 the corresponding source to us at zlib@gzip.org . Do not send
62 multi-megabyte data files without prior agreement.
63
64 9. Why do I get "undefined reference to gzputc"?
65
66 If "make test" produces something like
67
68 example.o(.text+0x154): undefined reference to `gzputc'
69
70 check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
71 /usr/X11R6/lib. Remove any old versions, then do "make install".
72
73 10. I need a Delphi interface to zlib.
74
75 See the contrib/delphi directory in the zlib distribution.
76
77 11. Can zlib handle .zip archives?
78
79 Not by itself, no. See the directory contrib/minizip in the zlib
80 distribution.
81
82 12. Can zlib handle .Z files?
83
84 No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
85 the code of uncompress on your own.
86
87 13. How can I make a Unix shared library?
88
89 make clean
90 ./configure -s
91 make
92
93 14. How do I install a shared zlib library on Unix?
94
95 After the above, then:
96
97 make install
98
99 However, many flavors of Unix come with a shared zlib already installed.
100 Before going to the trouble of compiling a shared version of zlib and
101 trying to install it, you may want to check if it's already there! If you
102 can #include <zlib.h>, it's there. The -lz option will probably link to it.
103
104 15. I have a question about OttoPDF.
105
106 We are not the authors of OttoPDF. The real author is on the OttoPDF web
107 site: Joel Hainley, jhainley@myndkryme.com.
108
109 16. Can zlib decode Flate data in an Adobe PDF file?
110
111 Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
112 To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
113
114 17. Why am I getting this "register_frame_info not found" error on Solaris?
115
116 After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
117 generates an error such as:
118
119 ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
120 symbol __register_frame_info: referenced symbol not found
121
122 The symbol __register_frame_info is not part of zlib, it is generated by
123 the C compiler (cc or gcc). You must recompile applications using zlib
124 which have this problem. This problem is specific to Solaris. See
125 http://www.sunfreeware.com for Solaris versions of zlib and applications
126 using zlib.
127
128 18. Why does gzip give an error on a file I make with compress/deflate?
129
130 The compress and deflate functions produce data in the zlib format, which
131 is different and incompatible with the gzip format. The gz* functions in
132 zlib on the other hand use the gzip format. Both the zlib and gzip
133 formats use the same compressed data format internally, but have different
134 headers and trailers around the compressed data.
135
136 19. Ok, so why are there two different formats?
137
138 The gzip format was designed to retain the directory information about
139 a single file, such as the name and last modification date. The zlib
140 format on the other hand was designed for in-memory and communication
141 channel applications, and has a much more compact header and trailer and
142 uses a faster integrity check than gzip.
143
144 20. Well that's nice, but how do I make a gzip file in memory?
145
146 You can request that deflate write the gzip format instead of the zlib
147 format using deflateInit2(). You can also request that inflate decode
148 the gzip format using inflateInit2(). Read zlib.h for more details.
149
150 21. Is zlib thread-safe?
151
152 Yes. However any library routines that zlib uses and any application-
153 provided memory allocation routines must also be thread-safe. zlib's gz*
154 functions use stdio library routines, and most of zlib's functions use the
155 library memory allocation routines by default. zlib's Init functions allow
156 for the application to provide custom memory allocation routines.
157
158 Of course, you should only operate on any given zlib or gzip stream from a
159 single thread at a time.
160
161 22. Can I use zlib in my commercial application?
162
163 Yes. Please read the license in zlib.h.
164
165 23. Is zlib under the GNU license?
166
167 No. Please read the license in zlib.h.
168
169 24. The license says that altered source versions must be "plainly marked". So
170 what exactly do I need to do to meet that requirement?
171
172 You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
173 particular, the final version number needs to be changed to "f", and an
174 identification string should be appended to ZLIB_VERSION. Version numbers
175 x.x.x.f are reserved for modifications to zlib by others than the zlib
176 maintainers. For example, if the version of the base zlib you are altering
177 is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
178 ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
179 update the version strings in deflate.c and inftrees.c.
180
181 For altered source distributions, you should also note the origin and
182 nature of the changes in zlib.h, as well as in ChangeLog and README, along
183 with the dates of the alterations. The origin should include at least your
184 name (or your company's name), and an email address to contact for help or
185 issues with the library.
186
187 Note that distributing a compiled zlib library along with zlib.h and
188 zconf.h is also a source distribution, and so you should change
189 ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
190 in zlib.h as you would for a full source distribution.
191
192 25. Will zlib work on a big-endian or little-endian architecture, and can I
193 exchange compressed data between them?
194
195 Yes and yes.
196
197 26. Will zlib work on a 64-bit machine?
198
199 It should. It has been tested on 64-bit machines, and has no dependence
200 on any data types being limited to 32-bits in length. If you have any
201 difficulties, please provide a complete problem report to zlib@gzip.org
202
203 27. Will zlib decompress data from the PKWare Data Compression Library?
204
205 No. The PKWare DCL uses a completely different compressed data format
206 than does PKZIP and zlib. However, you can look in zlib's contrib/blast
207 directory for a possible solution to your problem.
208
209 28. Can I access data randomly in a compressed stream?
210
211 No, not without some preparation. If when compressing you periodically
212 use Z_FULL_FLUSH, carefully write all the pending data at those points,
213 and keep an index of those locations, then you can start decompression
214 at those points. You have to be careful to not use Z_FULL_FLUSH too
215 often, since it can significantly degrade compression.
216
217 29. Does zlib work on MVS, OS/390, CICS, etc.?
218
219 We don't know for sure. We have heard occasional reports of success on
220 these systems. If you do use it on one of these, please provide us with
221 a report, instructions, and patches that we can reference when we get
222 these questions. Thanks.
223
224 30. Is there some simpler, easier to read version of inflate I can look at
225 to understand the deflate format?
226
227 First off, you should read RFC 1951. Second, yes. Look in zlib's
228 contrib/puff directory.
229
230 31. Does zlib infringe on any patents?
231
232 As far as we know, no. In fact, that was originally the whole point behind
233 zlib. Look here for some more information:
234
235 http://www.gzip.org/#faq11
236
237 32. Can zlib work with greater than 4 GB of data?
238
239 Yes. inflate() and deflate() will process any amount of data correctly.
240 Each call of inflate() or deflate() is limited to input and output chunks
241 of the maximum value that can be stored in the compiler's "unsigned int"
242 type, but there is no limit to the number of chunks. Note however that the
243 strm.total_in and strm_total_out counters may be limited to 4 GB. These
244 counters are provided as a convenience and are not used internally by
245 inflate() or deflate(). The application can easily set up its own counters
246 updated after each call of inflate() or deflate() to count beyond 4 GB.
247 compress() and uncompress() may be limited to 4 GB, since they operate in a
248 single call. gzseek() and gztell() may be limited to 4 GB depending on how
249 zlib is compiled. See the zlibCompileFlags() function in zlib.h.
250
251 The word "may" appears several times above since there is a 4 GB limit
252 only if the compiler's "long" type is 32 bits. If the compiler's "long"
253 type is 64 bits, then the limit is 16 exabytes.
254
255 33. Does zlib have any security vulnerabilities?
256
257 The only one that we are aware of is potentially in gzprintf(). If zlib
258 is compiled to use sprintf() or vsprintf(), then there is no protection
259 against a buffer overflow of a 4K string space, other than the caller of
260 gzprintf() assuring that the output will not exceed 4K. On the other
261 hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
262 normally be the case, then there is no vulnerability. The ./configure
263 script will display warnings if an insecure variation of sprintf() will
264 be used by gzprintf(). Also the zlibCompileFlags() function will return
265 information on what variant of sprintf() is used by gzprintf().
266
267 If you don't have snprintf() or vsnprintf() and would like one, you can
268 find a portable implementation here:
269
270 http://www.ijs.si/software/snprintf/
271
272 Note that you should be using the most recent version of zlib. Versions
273 1.1.3 and before were subject to a double-free vulnerability.
274
275 34. Is there a Java version of zlib?
276
277 Probably what you want is to use zlib in Java. zlib is already included
278 as part of the Java SDK in the java.util.zip package. If you really want
279 a version of zlib written in the Java language, look on the zlib home
280 page for links: http://www.zlib.org/
281
282 35. I get this or that compiler or source-code scanner warning when I crank it
283 up to maximally-pedantic. Can't you guys write proper code?
284
285 Many years ago, we gave up attempting to avoid warnings on every compiler
286 in the universe. It just got to be a waste of time, and some compilers
287 were downright silly. So now, we simply make sure that the code always
288 works.
289
290 36. Valgrind (or some similar memory access checker) says that deflate is
291 performing a conditional jump that depends on an uninitialized value.
292 Isn't that a bug?
293
294 No. That is intentional for performance reasons, and the output of
295 deflate is not affected. This only started showing up recently since
296 zlib 1.2.x uses malloc() by default for allocations, whereas earlier
297 versions used calloc(), which zeros out the allocated memory.
298
299 37. Will zlib read the (insert any ancient or arcane format here) compressed
300 data format?
301
302 Probably not. Look in the comp.compression FAQ for pointers to various
303 formats and associated software.
304
305 38. How can I encrypt/decrypt zip files with zlib?
306
307 zlib doesn't support encryption. The original PKZIP encryption is very weak
308 and can be broken with freely available programs. To get strong encryption,
309 use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
310 For PKZIP compatible "encryption", look at http://www.info-zip.org/
311
312 39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
313
314 "gzip" is the gzip format, and "deflate" is the zlib format. They should
315 probably have called the second one "zlib" instead to avoid confusion
316 with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
317 correctly points to the zlib specification in RFC 1950 for the "deflate"
318 transfer encoding, there have been reports of servers and browsers that
319 incorrectly produce or expect raw deflate data per the deflate
320 specficiation in RFC 1951, most notably Microsoft. So even though the
321 "deflate" transfer encoding using the zlib format would be the more
322 efficient approach (and in fact exactly what the zlib format was designed
323 for), using the "gzip" transfer encoding is probably more reliable due to
324 an unfortunate choice of name on the part of the HTTP 1.1 authors.
325
326 Bottom line: use the gzip format for HTTP 1.1 encoding.
327
328 40. Does zlib support the new "Deflate64" format introduced by PKWare?
329
330 No. PKWare has apparently decided to keep that format proprietary, since
331 they have not documented it as they have previous compression formats.
332 In any case, the compression improvements are so modest compared to other
333 more modern approaches, that it's not worth the effort to implement.
334
335 41. Can you please sign these lengthy legal documents and fax them back to us
336 so that we can use your software in our product?
337
338 No. Go away. Shoo.
0 ChangeLog history of changes
1 FAQ Frequently Asked Questions about zlib
2 INDEX this file
3 Makefile makefile for Unix (generated by configure)
4 Makefile.in makefile for Unix (template for configure)
5 README guess what
6 algorithm.txt description of the (de)compression algorithm
7 configure configure script for Unix
8 zconf.in.h template for zconf.h (used by configure)
9
10 amiga/ makefiles for Amiga SAS C
11 as400/ makefiles for IBM AS/400
12 msdos/ makefiles for MSDOS
13 old/ makefiles for various architectures and zlib documentation
14 files that have not yet been updated for zlib 1.2.x
15 projects/ projects for various Integrated Development Environments
16 qnx/ makefiles for QNX
17 win32/ makefiles for Windows
18
19 zlib public header files (must be kept):
20 zconf.h
21 zlib.h
22
23 private source files used to build the zlib library:
24 adler32.c
25 compress.c
26 crc32.c
27 crc32.h
28 deflate.c
29 deflate.h
30 gzio.c
31 infback.c
32 inffast.c
33 inffast.h
34 inffixed.h
35 inflate.c
36 inflate.h
37 inftrees.c
38 inftrees.h
39 trees.c
40 trees.h
41 uncompr.c
42 zutil.c
43 zutil.h
44
45 source files for sample programs:
46 example.c
47 minigzip.c
48
49 unsupported contribution by third parties
50 See contrib/README.contrib
0 # Makefile for zlib
1 # Copyright (C) 1995-2003 Jean-loup Gailly.
2 # For conditions of distribution and use, see copyright notice in zlib.h
3
4 # To compile and test, type:
5 # ./configure; make test
6 # The call of configure is optional if you don't have special requirements
7 # If you wish to build zlib as a shared library, use: ./configure -s
8
9 # To use the asm code, type:
10 # cp contrib/asm?86/match.S ./match.S
11 # make LOC=-DASMV OBJA=match.o
12
13 # To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
14 # make install
15 # To install in $HOME instead of /usr/local, use:
16 # make install prefix=$HOME
17
18 CC=cc
19
20 CFLAGS=-O
21 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
22 #CFLAGS=-g -DDEBUG
23 #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
24 # -Wstrict-prototypes -Wmissing-prototypes
25
26 LDFLAGS=libz.a
27 LDSHARED=$(CC)
28 CPP=$(CC) -E
29
30 LIBS=libz.a
31 SHAREDLIB=libz.so
32 SHAREDLIBV=libz.so.1.2.2.2
33 SHAREDLIBM=libz.so.1
34
35 AR=ar rc
36 RANLIB=ranlib
37 TAR=tar
38 SHELL=/bin/sh
39 EXE=
40
41 prefix = /usr/local
42 exec_prefix = ${prefix}
43 libdir = ${exec_prefix}/lib
44 includedir = ${prefix}/include
45 mandir = ${prefix}/share/man
46 man3dir = ${mandir}/man3
47
48 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
49 zutil.o inflate.o infback.o inftrees.o inffast.o
50
51 OBJA =
52 # to use the asm code: make OBJA=match.o
53
54 TEST_OBJS = example.o minigzip.o
55
56 all: example$(EXE) minigzip$(EXE)
57
58 check: test
59 test: all
60 @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
61 echo hello world | ./minigzip | ./minigzip -d || \
62 echo ' *** minigzip test FAILED ***' ; \
63 if ./example; then \
64 echo ' *** zlib test OK ***'; \
65 else \
66 echo ' *** zlib test FAILED ***'; \
67 fi
68
69 libz.a: $(OBJS) $(OBJA)
70 $(AR) $@ $(OBJS) $(OBJA)
71 -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
72
73 match.o: match.S
74 $(CPP) match.S > _match.s
75 $(CC) -c _match.s
76 mv _match.o match.o
77 rm -f _match.s
78
79 $(SHAREDLIBV): $(OBJS)
80 $(LDSHARED) -o $@ $(OBJS)
81 rm -f $(SHAREDLIB) $(SHAREDLIBM)
82 ln -s $@ $(SHAREDLIB)
83 ln -s $@ $(SHAREDLIBM)
84
85 example$(EXE): example.o $(LIBS)
86 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
87
88 minigzip$(EXE): minigzip.o $(LIBS)
89 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
90
91 install: $(LIBS)
92 -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
93 -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
94 -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
95 -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
96 cp zlib.h zconf.h $(includedir)
97 chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
98 cp $(LIBS) $(libdir)
99 cd $(libdir); chmod 755 $(LIBS)
100 -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
101 cd $(libdir); if test -f $(SHAREDLIBV); then \
102 rm -f $(SHAREDLIB) $(SHAREDLIBM); \
103 ln -s $(SHAREDLIBV) $(SHAREDLIB); \
104 ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
105 (ldconfig || true) >/dev/null 2>&1; \
106 fi
107 cp zlib.3 $(man3dir)
108 chmod 644 $(man3dir)/zlib.3
109 # The ranlib in install is needed on NeXTSTEP which checks file times
110 # ldconfig is for Linux
111
112 uninstall:
113 cd $(includedir); \
114 cd $(libdir); rm -f libz.a; \
115 if test -f $(SHAREDLIBV); then \
116 rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
117 fi
118 cd $(man3dir); rm -f zlib.3
119
120 mostlyclean: clean
121 clean:
122 rm -f *.o *~ example$(EXE) minigzip$(EXE) \
123 libz.* foo.gz so_locations \
124 _match.s maketree contrib/infback9/*.o
125
126 maintainer-clean: distclean
127 distclean: clean
128 cp -p Makefile.in Makefile
129 cp -p zconf.in.h zconf.h
130 rm -f .DS_Store
131
132 tags:
133 etags *.[ch]
134
135 depend:
136 makedepend -- $(CFLAGS) -- *.[ch]
137
138 # DO NOT DELETE THIS LINE -- make depend depends on it.
139
140 adler32.o: zlib.h zconf.h
141 compress.o: zlib.h zconf.h
142 crc32.o: crc32.h zlib.h zconf.h
143 deflate.o: deflate.h zutil.h zlib.h zconf.h
144 example.o: zlib.h zconf.h
145 gzio.o: zutil.h zlib.h zconf.h
146 inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
147 inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
148 infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
149 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
150 minigzip.o: zlib.h zconf.h
151 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
152 uncompr.o: zlib.h zconf.h
153 zutil.o: zutil.h zlib.h zconf.h
0 # Makefile for zlib
1 # Copyright (C) 1995-2003 Jean-loup Gailly.
2 # For conditions of distribution and use, see copyright notice in zlib.h
3
4 # To compile and test, type:
5 # ./configure; make test
6 # The call of configure is optional if you don't have special requirements
7 # If you wish to build zlib as a shared library, use: ./configure -s
8
9 # To use the asm code, type:
10 # cp contrib/asm?86/match.S ./match.S
11 # make LOC=-DASMV OBJA=match.o
12
13 # To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
14 # make install
15 # To install in $HOME instead of /usr/local, use:
16 # make install prefix=$HOME
17
18 CC=cc
19
20 CFLAGS=-O
21 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
22 #CFLAGS=-g -DDEBUG
23 #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
24 # -Wstrict-prototypes -Wmissing-prototypes
25
26 LDFLAGS=libz.a
27 LDSHARED=$(CC)
28 CPP=$(CC) -E
29
30 LIBS=libz.a
31 SHAREDLIB=libz.so
32 SHAREDLIBV=libz.so.1.2.2.2
33 SHAREDLIBM=libz.so.1
34
35 AR=ar rc
36 RANLIB=ranlib
37 TAR=tar
38 SHELL=/bin/sh
39 EXE=
40
41 prefix = /usr/local
42 exec_prefix = ${prefix}
43 libdir = ${exec_prefix}/lib
44 includedir = ${prefix}/include
45 mandir = ${prefix}/share/man
46 man3dir = ${mandir}/man3
47
48 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
49 zutil.o inflate.o infback.o inftrees.o inffast.o
50
51 OBJA =
52 # to use the asm code: make OBJA=match.o
53
54 TEST_OBJS = example.o minigzip.o
55
56 all: example$(EXE) minigzip$(EXE)
57
58 check: test
59 test: all
60 @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
61 echo hello world | ./minigzip | ./minigzip -d || \
62 echo ' *** minigzip test FAILED ***' ; \
63 if ./example; then \
64 echo ' *** zlib test OK ***'; \
65 else \
66 echo ' *** zlib test FAILED ***'; \
67 fi
68
69 libz.a: $(OBJS) $(OBJA)
70 $(AR) $@ $(OBJS) $(OBJA)
71 -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
72
73 match.o: match.S
74 $(CPP) match.S > _match.s
75 $(CC) -c _match.s
76 mv _match.o match.o
77 rm -f _match.s
78
79 $(SHAREDLIBV): $(OBJS)
80 $(LDSHARED) -o $@ $(OBJS)
81 rm -f $(SHAREDLIB) $(SHAREDLIBM)
82 ln -s $@ $(SHAREDLIB)
83 ln -s $@ $(SHAREDLIBM)
84
85 example$(EXE): example.o $(LIBS)
86 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
87
88 minigzip$(EXE): minigzip.o $(LIBS)
89 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
90
91 install: $(LIBS)
92 -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
93 -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
94 -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
95 -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
96 cp zlib.h zconf.h $(includedir)
97 chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
98 cp $(LIBS) $(libdir)
99 cd $(libdir); chmod 755 $(LIBS)
100 -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
101 cd $(libdir); if test -f $(SHAREDLIBV); then \
102 rm -f $(SHAREDLIB) $(SHAREDLIBM); \
103 ln -s $(SHAREDLIBV) $(SHAREDLIB); \
104 ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
105 (ldconfig || true) >/dev/null 2>&1; \
106 fi
107 cp zlib.3 $(man3dir)
108 chmod 644 $(man3dir)/zlib.3
109 # The ranlib in install is needed on NeXTSTEP which checks file times
110 # ldconfig is for Linux
111
112 uninstall:
113 cd $(includedir); \
114 cd $(libdir); rm -f libz.a; \
115 if test -f $(SHAREDLIBV); then \
116 rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
117 fi
118 cd $(man3dir); rm -f zlib.3
119
120 mostlyclean: clean
121 clean:
122 rm -f *.o *~ example$(EXE) minigzip$(EXE) \
123 libz.* foo.gz so_locations \
124 _match.s maketree contrib/infback9/*.o
125
126 maintainer-clean: distclean
127 distclean: clean
128 cp -p Makefile.in Makefile
129 cp -p zconf.in.h zconf.h
130 rm -f .DS_Store
131
132 tags:
133 etags *.[ch]
134
135 depend:
136 makedepend -- $(CFLAGS) -- *.[ch]
137
138 # DO NOT DELETE THIS LINE -- make depend depends on it.
139
140 adler32.o: zlib.h zconf.h
141 compress.o: zlib.h zconf.h
142 crc32.o: crc32.h zlib.h zconf.h
143 deflate.o: deflate.h zutil.h zlib.h zconf.h
144 example.o: zlib.h zconf.h
145 gzio.o: zutil.h zlib.h zconf.h
146 inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
147 inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
148 infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
149 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
150 minigzip.o: zlib.h zconf.h
151 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
152 uncompr.o: zlib.h zconf.h
153 zutil.o: zutil.h zlib.h zconf.h
0 ZLIB DATA COMPRESSION LIBRARY
1
2 zlib 1.2.2.2 is a general purpose data compression library. All the code is
3 thread safe. The data format used by the zlib library is described by RFCs
4 (Request for Comments) 1950 to 1952 in the files
5 http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
6 and rfc1952.txt (gzip format). These documents are also available in other
7 formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
8
9 All functions of the compression library are documented in the file zlib.h
10 (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
11 of the library is given in the file example.c which also tests that the library
12 is working correctly. Another example is given in the file minigzip.c. The
13 compression library itself is composed of all source files except example.c and
14 minigzip.c.
15
16 To compile all files and run the test program, follow the instructions given at
17 the top of Makefile. In short "make test; make install" should work for most
18 machines. For Unix: "./configure; make test; make install". For MSDOS, use one
19 of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
20
21 Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
22 <info@winimage.com> for the Windows DLL version. The zlib home page is
23 http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
24 please check this site to verify that you have the latest version of zlib;
25 otherwise get the latest version and check whether the problem still exists or
26 not.
27
28 PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
29 for help.
30
31 Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
32 issue of Dr. Dobb's Journal; a copy of the article is available in
33 http://dogma.net/markn/articles/zlibtool/zlibtool.htm
34
35 The changes made in version 1.2.2.2 are documented in the file ChangeLog.
36
37 Unsupported third party contributions are provided in directory "contrib".
38
39 A Java implementation of zlib is available in the Java Development Kit
40 http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
41 See the zlib home page http://www.zlib.org for details.
42
43 A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
44 CPAN (Comprehensive Perl Archive Network) sites
45 http://www.cpan.org/modules/by-module/Compress/
46
47 A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
48 available in Python 1.5 and later versions, see
49 http://www.python.org/doc/lib/module-zlib.html
50
51 A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
52 availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
53
54 An experimental package to read and write files in .zip format, written on top
55 of zlib by Gilles Vollant <info@winimage.com>, is available in the
56 contrib/minizip directory of zlib.
57
58
59 Notes for some targets:
60
61 - For Windows DLL versions, please see win32/DLL_FAQ.txt
62
63 - For 64-bit Irix, deflate.c must be compiled without any optimization. With
64 -O, one libpng test fails. The test works in 32 bit mode (with the -n32
65 compiler flag). The compiler bug has been reported to SGI.
66
67 - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
68 when compiled with cc.
69
70 - On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
71 necessary to get gzprintf working correctly. This is done by configure.
72
73 - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
74 other compilers. Use "make test" to check your compiler.
75
76 - gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
77
78 - For PalmOs, see http://palmzlib.sourceforge.net/
79
80 - When building a shared, i.e. dynamic library on Mac OS X, the library must be
81 installed before testing (do "make install" before "make test"), since the
82 library location is specified in the library.
83
84
85 Acknowledgments:
86
87 The deflate format used by zlib was defined by Phil Katz. The deflate
88 and zlib specifications were written by L. Peter Deutsch. Thanks to all the
89 people who reported problems and suggested various improvements in zlib;
90 they are too numerous to cite here.
91
92 Copyright notice:
93
94 (C) 1995-2004 Jean-loup Gailly and Mark Adler
95
96 This software is provided 'as-is', without any express or implied
97 warranty. In no event will the authors be held liable for any damages
98 arising from the use of this software.
99
100 Permission is granted to anyone to use this software for any purpose,
101 including commercial applications, and to alter it and redistribute it
102 freely, subject to the following restrictions:
103
104 1. The origin of this software must not be misrepresented; you must not
105 claim that you wrote the original software. If you use this software
106 in a product, an acknowledgment in the product documentation would be
107 appreciated but is not required.
108 2. Altered source versions must be plainly marked as such, and must not be
109 misrepresented as being the original software.
110 3. This notice may not be removed or altered from any source distribution.
111
112 Jean-loup Gailly Mark Adler
113 jloup@gzip.org madler@alumni.caltech.edu
114
115 If you use the zlib library in a product, we would appreciate *not*
116 receiving lengthy legal documents to sign. The sources are provided
117 for free but without warranty of any kind. The library has been
118 entirely written by Jean-loup Gailly and Mark Adler; it does not
119 include third-party code.
120
121 If you redistribute modified sources, we would appreciate that you include
122 in the file ChangeLog history information documenting your changes. Please
123 read the FAQ for more information on the distribution of modified source
124 versions.
0 /* adler32.c -- compute the Adler-32 checksum of a data stream
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #define ZLIB_INTERNAL
8 #include "zlib.h"
9
10 #define BASE 65521UL /* largest prime smaller than 65536 */
11 #define NMAX 5552
12 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
13
14 #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
15 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
16 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
17 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
18 #define DO16(buf) DO8(buf,0); DO8(buf,8);
19
20 /* use NO_DIVIDE if your processor does not do division in hardware */
21 #ifdef NO_DIVIDE
22 # define MOD(a) \
23 do { \
24 if (a >= (BASE << 16)) a -= (BASE << 16); \
25 if (a >= (BASE << 15)) a -= (BASE << 15); \
26 if (a >= (BASE << 14)) a -= (BASE << 14); \
27 if (a >= (BASE << 13)) a -= (BASE << 13); \
28 if (a >= (BASE << 12)) a -= (BASE << 12); \
29 if (a >= (BASE << 11)) a -= (BASE << 11); \
30 if (a >= (BASE << 10)) a -= (BASE << 10); \
31 if (a >= (BASE << 9)) a -= (BASE << 9); \
32 if (a >= (BASE << 8)) a -= (BASE << 8); \
33 if (a >= (BASE << 7)) a -= (BASE << 7); \
34 if (a >= (BASE << 6)) a -= (BASE << 6); \
35 if (a >= (BASE << 5)) a -= (BASE << 5); \
36 if (a >= (BASE << 4)) a -= (BASE << 4); \
37 if (a >= (BASE << 3)) a -= (BASE << 3); \
38 if (a >= (BASE << 2)) a -= (BASE << 2); \
39 if (a >= (BASE << 1)) a -= (BASE << 1); \
40 if (a >= BASE) a -= BASE; \
41 } while (0)
42 # define MOD4(a) \
43 do { \
44 if (a >= (BASE << 4)) a -= (BASE << 4); \
45 if (a >= (BASE << 3)) a -= (BASE << 3); \
46 if (a >= (BASE << 2)) a -= (BASE << 2); \
47 if (a >= (BASE << 1)) a -= (BASE << 1); \
48 if (a >= BASE) a -= BASE; \
49 } while (0)
50 #else
51 # define MOD(a) a %= BASE
52 # define MOD4(a) a %= BASE
53 #endif
54
55 /* ========================================================================= */
56 uLong ZEXPORT adler32(adler, buf, len)
57 uLong adler;
58 const Bytef *buf;
59 uInt len;
60 {
61 unsigned long sum2;
62 unsigned n;
63
64 /* split Adler-32 into component sums */
65 sum2 = (adler >> 16) & 0xffff;
66 adler &= 0xffff;
67
68 /* in case user likes doing a byte at a time, keep it fast */
69 if (len == 1) {
70 adler += buf[0];
71 if (adler >= BASE)
72 adler -= BASE;
73 sum2 += adler;
74 if (sum2 >= BASE)
75 sum2 -= BASE;
76 return adler | (sum2 << 16);
77 }
78
79 /* initial Adler-32 value (deferred check for len == 1 speed) */
80 if (buf == Z_NULL)
81 return 1L;
82
83 /* in case short lengths are provided, keep it somewhat fast */
84 if (len < 16) {
85 while (len--) {
86 adler += *buf++;
87 sum2 += adler;
88 }
89 if (adler >= BASE)
90 adler -= BASE;
91 MOD4(sum2); /* only added so many BASE's */
92 return adler | (sum2 << 16);
93 }
94
95 /* do length NMAX blocks -- requires just one modulo operation */
96 while (len >= NMAX) {
97 len -= NMAX;
98 n = NMAX / 16; /* NMAX is divisible by 16 */
99 do {
100 DO16(buf); /* 16 sums unrolled */
101 buf += 16;
102 } while (--n);
103 MOD(adler);
104 MOD(sum2);
105 }
106
107 /* do remaining bytes (less than NMAX, still just one modulo) */
108 if (len) { /* avoid modulos if none remaining */
109 while (len >= 16) {
110 len -= 16;
111 DO16(buf);
112 buf += 16;
113 }
114 while (len--) {
115 adler += *buf++;
116 sum2 += adler;
117 }
118 MOD(adler);
119 MOD(sum2);
120 }
121
122 /* return recombined sums */
123 return adler | (sum2 << 16);
124 }
125
126 /* ========================================================================= */
127 uLong ZEXPORT adler32_combine(adler1, adler2, len2)
128 uLong adler1;
129 uLong adler2;
130 z_off_t len2;
131 {
132 unsigned long sum1;
133 unsigned long sum2;
134 unsigned rem;
135
136 /* the derivation of this formula is left as an exercise for the reader */
137 rem = (unsigned)(len2 % BASE);
138 sum1 = adler1 & 0xffff;
139 sum2 = rem * sum1;
140 MOD(sum2);
141 sum1 += (adler2 & 0xffff) + BASE - 1;
142 sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
143 if (sum1 > BASE) sum1 -= BASE;
144 if (sum1 > BASE) sum1 -= BASE;
145 if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
146 if (sum2 > BASE) sum2 -= BASE;
147 return sum1 | (sum2 << 16);
148 }
0 1. Compression algorithm (deflate)
1
2 The deflation algorithm used by gzip (also zip and zlib) is a variation of
3 LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
4 the input data. The second occurrence of a string is replaced by a
5 pointer to the previous string, in the form of a pair (distance,
6 length). Distances are limited to 32K bytes, and lengths are limited
7 to 258 bytes. When a string does not occur anywhere in the previous
8 32K bytes, it is emitted as a sequence of literal bytes. (In this
9 description, `string' must be taken as an arbitrary sequence of bytes,
10 and is not restricted to printable characters.)
11
12 Literals or match lengths are compressed with one Huffman tree, and
13 match distances are compressed with another tree. The trees are stored
14 in a compact form at the start of each block. The blocks can have any
15 size (except that the compressed data for one block must fit in
16 available memory). A block is terminated when deflate() determines that
17 it would be useful to start another block with fresh trees. (This is
18 somewhat similar to the behavior of LZW-based _compress_.)
19
20 Duplicated strings are found using a hash table. All input strings of
21 length 3 are inserted in the hash table. A hash index is computed for
22 the next 3 bytes. If the hash chain for this index is not empty, all
23 strings in the chain are compared with the current input string, and
24 the longest match is selected.
25
26 The hash chains are searched starting with the most recent strings, to
27 favor small distances and thus take advantage of the Huffman encoding.
28 The hash chains are singly linked. There are no deletions from the
29 hash chains, the algorithm simply discards matches that are too old.
30
31 To avoid a worst-case situation, very long hash chains are arbitrarily
32 truncated at a certain length, determined by a runtime option (level
33 parameter of deflateInit). So deflate() does not always find the longest
34 possible match but generally finds a match which is long enough.
35
36 deflate() also defers the selection of matches with a lazy evaluation
37 mechanism. After a match of length N has been found, deflate() searches for
38 a longer match at the next input byte. If a longer match is found, the
39 previous match is truncated to a length of one (thus producing a single
40 literal byte) and the process of lazy evaluation begins again. Otherwise,
41 the original match is kept, and the next match search is attempted only N
42 steps later.
43
44 The lazy match evaluation is also subject to a runtime parameter. If
45 the current match is long enough, deflate() reduces the search for a longer
46 match, thus speeding up the whole process. If compression ratio is more
47 important than speed, deflate() attempts a complete second search even if
48 the first match is already long enough.
49
50 The lazy match evaluation is not performed for the fastest compression
51 modes (level parameter 1 to 3). For these fast modes, new strings
52 are inserted in the hash table only when no match was found, or
53 when the match is not too long. This degrades the compression ratio
54 but saves time since there are both fewer insertions and fewer searches.
55
56
57 2. Decompression algorithm (inflate)
58
59 2.1 Introduction
60
61 The key question is how to represent a Huffman code (or any prefix code) so
62 that you can decode fast. The most important characteristic is that shorter
63 codes are much more common than longer codes, so pay attention to decoding the
64 short codes fast, and let the long codes take longer to decode.
65
66 inflate() sets up a first level table that covers some number of bits of
67 input less than the length of longest code. It gets that many bits from the
68 stream, and looks it up in the table. The table will tell if the next
69 code is that many bits or less and how many, and if it is, it will tell
70 the value, else it will point to the next level table for which inflate()
71 grabs more bits and tries to decode a longer code.
72
73 How many bits to make the first lookup is a tradeoff between the time it
74 takes to decode and the time it takes to build the table. If building the
75 table took no time (and if you had infinite memory), then there would only
76 be a first level table to cover all the way to the longest code. However,
77 building the table ends up taking a lot longer for more bits since short
78 codes are replicated many times in such a table. What inflate() does is
79 simply to make the number of bits in the first table a variable, and then
80 to set that variable for the maximum speed.
81
82 For inflate, which has 286 possible codes for the literal/length tree, the size
83 of the first table is nine bits. Also the distance trees have 30 possible
84 values, and the size of the first table is six bits. Note that for each of
85 those cases, the table ended up one bit longer than the ``average'' code
86 length, i.e. the code length of an approximately flat code which would be a
87 little more than eight bits for 286 symbols and a little less than five bits
88 for 30 symbols.
89
90
91 2.2 More details on the inflate table lookup
92
93 Ok, you want to know what this cleverly obfuscated inflate tree actually
94 looks like. You are correct that it's not a Huffman tree. It is simply a
95 lookup table for the first, let's say, nine bits of a Huffman symbol. The
96 symbol could be as short as one bit or as long as 15 bits. If a particular
97 symbol is shorter than nine bits, then that symbol's translation is duplicated
98 in all those entries that start with that symbol's bits. For example, if the
99 symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
100 symbol is nine bits long, it appears in the table once.
101
102 If the symbol is longer than nine bits, then that entry in the table points
103 to another similar table for the remaining bits. Again, there are duplicated
104 entries as needed. The idea is that most of the time the symbol will be short
105 and there will only be one table look up. (That's whole idea behind data
106 compression in the first place.) For the less frequent long symbols, there
107 will be two lookups. If you had a compression method with really long
108 symbols, you could have as many levels of lookups as is efficient. For
109 inflate, two is enough.
110
111 So a table entry either points to another table (in which case nine bits in
112 the above example are gobbled), or it contains the translation for the symbol
113 and the number of bits to gobble. Then you start again with the next
114 ungobbled bit.
115
116 You may wonder: why not just have one lookup table for how ever many bits the
117 longest symbol is? The reason is that if you do that, you end up spending
118 more time filling in duplicate symbol entries than you do actually decoding.
119 At least for deflate's output that generates new trees every several 10's of
120 kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
121 would take too long if you're only decoding several thousand symbols. At the
122 other extreme, you could make a new table for every bit in the code. In fact,
123 that's essentially a Huffman tree. But then you spend two much time
124 traversing the tree while decoding, even for short symbols.
125
126 So the number of bits for the first lookup table is a trade of the time to
127 fill out the table vs. the time spent looking at the second level and above of
128 the table.
129
130 Here is an example, scaled down:
131
132 The code being decoded, with 10 symbols, from 1 to 6 bits long:
133
134 A: 0
135 B: 10
136 C: 1100
137 D: 11010
138 E: 11011
139 F: 11100
140 G: 11101
141 H: 11110
142 I: 111110
143 J: 111111
144
145 Let's make the first table three bits long (eight entries):
146
147 000: A,1
148 001: A,1
149 010: A,1
150 011: A,1
151 100: B,2
152 101: B,2
153 110: -> table X (gobble 3 bits)
154 111: -> table Y (gobble 3 bits)
155
156 Each entry is what the bits decode as and how many bits that is, i.e. how
157 many bits to gobble. Or the entry points to another table, with the number of
158 bits to gobble implicit in the size of the table.
159
160 Table X is two bits long since the longest code starting with 110 is five bits
161 long:
162
163 00: C,1
164 01: C,1
165 10: D,2
166 11: E,2
167
168 Table Y is three bits long since the longest code starting with 111 is six
169 bits long:
170
171 000: F,2
172 001: F,2
173 010: G,2
174 011: G,2
175 100: H,2
176 101: H,2
177 110: I,3
178 111: J,3
179
180 So what we have here are three tables with a total of 20 entries that had to
181 be constructed. That's compared to 64 entries for a single table. Or
182 compared to 16 entries for a Huffman tree (six two entry tables and one four
183 entry table). Assuming that the code ideally represents the probability of
184 the symbols, it takes on the average 1.25 lookups per symbol. That's compared
185 to one lookup for the single table, or 1.66 lookups per symbol for the
186 Huffman tree.
187
188 There, I think that gives you a picture of what's going on. For inflate, the
189 meaning of a particular symbol is often more than just a letter. It can be a
190 byte (a "literal"), or it can be either a length or a distance which
191 indicates a base value and a number of bits to fetch after the code that is
192 added to the base value. Or it might be the special end-of-block code. The
193 data structures created in inftrees.c try to encode all that information
194 compactly in the tables.
195
196
197 Jean-loup Gailly Mark Adler
198 jloup@gzip.org madler@alumni.caltech.edu
199
200
201 References:
202
203 [LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
204 Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
205 pp. 337-343.
206
207 ``DEFLATE Compressed Data Format Specification'' available in
208 http://www.ietf.org/rfc/rfc1951.txt
0 # Amiga powerUP (TM) Makefile
1 # makefile for libpng and SAS C V6.58/7.00 PPC compiler
2 # Copyright (C) 1998 by Andreas R. Kleinert
3
4 LIBNAME = libzip.a
5
6 CC = scppc
7 CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
8 OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
9 AR = ppc-amigaos-ar cr
10 RANLIB = ppc-amigaos-ranlib
11 LD = ppc-amigaos-ld -r
12 LDFLAGS = -o
13 LDLIBS = LIB:scppc.a LIB:end.o
14 RM = delete quiet
15
16 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
17 zutil.o inflate.o infback.o inftrees.o inffast.o
18
19 TEST_OBJS = example.o minigzip.o
20
21 all: example minigzip
22
23 check: test
24 test: all
25 example
26 echo hello world | minigzip | minigzip -d
27
28 $(LIBNAME): $(OBJS)
29 $(AR) $@ $(OBJS)
30 -$(RANLIB) $@
31
32 example: example.o $(LIBNAME)
33 $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
34
35 minigzip: minigzip.o $(LIBNAME)
36 $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
37
38 mostlyclean: clean
39 clean:
40 $(RM) *.o example minigzip $(LIBNAME) foo.gz
41
42 zip:
43 zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
44 descrip.mms *.[ch]
45
46 tgz:
47 cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
48 zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
49
50 # DO NOT DELETE THIS LINE -- make depend depends on it.
51
52 adler32.o: zlib.h zconf.h
53 compress.o: zlib.h zconf.h
54 crc32.o: crc32.h zlib.h zconf.h
55 deflate.o: deflate.h zutil.h zlib.h zconf.h
56 example.o: zlib.h zconf.h
57 gzio.o: zutil.h zlib.h zconf.h
58 inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
59 inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
60 infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
61 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
62 minigzip.o: zlib.h zconf.h
63 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
64 uncompr.o: zlib.h zconf.h
65 zutil.o: zutil.h zlib.h zconf.h
0 # SMakefile for zlib
1 # Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
2 # Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
3 # Amiga, SAS/C 6.56 & Smake
4
5 CC=sc
6 CFLAGS=OPT
7 #CFLAGS=OPT CPU=68030
8 #CFLAGS=DEBUG=LINE
9 LDFLAGS=LIB z.lib
10
11 SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
12 NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
13 DEF=POSTINC
14
15 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
16 zutil.o inflate.o infback.o inftrees.o inffast.o
17
18 TEST_OBJS = example.o minigzip.o
19
20 all: SCOPTIONS example minigzip
21
22 check: test
23 test: all
24 example
25 echo hello world | minigzip | minigzip -d
26
27 install: z.lib
28 copy clone zlib.h zconf.h INCLUDE:
29 copy clone z.lib LIB:
30
31 z.lib: $(OBJS)
32 oml z.lib r $(OBJS)
33
34 example: example.o z.lib
35 $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
36
37 minigzip: minigzip.o z.lib
38 $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
39
40 mostlyclean: clean
41 clean:
42 -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
43
44 SCOPTIONS: Makefile.sas
45 copy to $@ <from <
46 $(SCOPTIONS)
47 <
48
49 # DO NOT DELETE THIS LINE -- make depend depends on it.
50
51 adler32.o: zlib.h zconf.h
52 compress.o: zlib.h zconf.h
53 crc32.o: crc32.h zlib.h zconf.h
54 deflate.o: deflate.h zutil.h zlib.h zconf.h
55 example.o: zlib.h zconf.h
56 gzio.o: zutil.h zlib.h zconf.h
57 inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
58 inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
59 infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
60 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
61 minigzip.o: zlib.h zconf.h
62 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
63 uncompr.o: zlib.h zconf.h
64 zutil.o: zutil.h zlib.h zconf.h
0 STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
1
2 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
3 /* Version 1.1.3 entry points. */
4 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
5
6 /********************************************************************/
7 /* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */
8 /********************************************************************/
9
10 EXPORT SYMBOL("adler32")
11
12 /********************************************************************/
13 /* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
14 /********************************************************************/
15
16 EXPORT SYMBOL("compress")
17 EXPORT SYMBOL("compress2")
18
19 /********************************************************************/
20 /* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */
21 /********************************************************************/
22
23 EXPORT SYMBOL("crc32")
24 EXPORT SYMBOL("get_crc_table")
25
26 /********************************************************************/
27 /* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
28 /********************************************************************/
29
30 EXPORT SYMBOL("deflate")
31 EXPORT SYMBOL("deflateEnd")
32 EXPORT SYMBOL("deflateSetDictionary")
33 EXPORT SYMBOL("deflateCopy")
34 EXPORT SYMBOL("deflateReset")
35 EXPORT SYMBOL("deflateParams")
36 EXPORT SYMBOL("deflatePrime")
37 EXPORT SYMBOL("deflateInit_")
38 EXPORT SYMBOL("deflateInit2_")
39
40 /********************************************************************/
41 /* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
42 /********************************************************************/
43
44 EXPORT SYMBOL("gzopen")
45 EXPORT SYMBOL("gzdopen")
46 EXPORT SYMBOL("gzsetparams")
47 EXPORT SYMBOL("gzread")
48 EXPORT SYMBOL("gzwrite")
49 EXPORT SYMBOL("gzprintf")
50 EXPORT SYMBOL("gzputs")
51 EXPORT SYMBOL("gzgets")
52 EXPORT SYMBOL("gzputc")
53 EXPORT SYMBOL("gzgetc")
54 EXPORT SYMBOL("gzflush")
55 EXPORT SYMBOL("gzseek")
56 EXPORT SYMBOL("gzrewind")
57 EXPORT SYMBOL("gztell")
58 EXPORT SYMBOL("gzeof")
59 EXPORT SYMBOL("gzclose")
60 EXPORT SYMBOL("gzerror")
61
62 /********************************************************************/
63 /* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
64 /********************************************************************/
65
66 EXPORT SYMBOL("inflate")
67 EXPORT SYMBOL("inflateEnd")
68 EXPORT SYMBOL("inflateSetDictionary")
69 EXPORT SYMBOL("inflateSync")
70 EXPORT SYMBOL("inflateReset")
71 EXPORT SYMBOL("inflateInit_")
72 EXPORT SYMBOL("inflateInit2_")
73 EXPORT SYMBOL("inflateSyncPoint")
74
75 /********************************************************************/
76 /* *MODULE UNCOMPR ZLIB 01/02/01 00:15:09 */
77 /********************************************************************/
78
79 EXPORT SYMBOL("uncompress")
80
81 /********************************************************************/
82 /* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
83 /********************************************************************/
84
85 EXPORT SYMBOL("zlibVersion")
86 EXPORT SYMBOL("zError")
87
88 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
89 /* Version 1.2.1 additional entry points. */
90 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
91
92 /********************************************************************/
93 /* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */
94 /********************************************************************/
95
96 EXPORT SYMBOL("compressBound")
97
98 /********************************************************************/
99 /* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */
100 /********************************************************************/
101
102 EXPORT SYMBOL("deflateBound")
103
104 /********************************************************************/
105 /* *MODULE GZIO ZLIB 01/02/01 00:15:09 */
106 /********************************************************************/
107
108 EXPORT SYMBOL("gzungetc")
109 EXPORT SYMBOL("gzclearerr")
110
111 /********************************************************************/
112 /* *MODULE INFBACK ZLIB 01/02/01 00:15:09 */
113 /********************************************************************/
114
115 EXPORT SYMBOL("inflateBack")
116 EXPORT SYMBOL("inflateBackEnd")
117 EXPORT SYMBOL("inflateBackInit_")
118
119 /********************************************************************/
120 /* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */
121 /********************************************************************/
122
123 EXPORT SYMBOL("inflateCopy")
124
125 /********************************************************************/
126 /* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */
127 /********************************************************************/
128
129 EXPORT SYMBOL("zlibCompileFlags")
130
131 ENDPGMEXP
0 /******************************************************************************/
1 /* */
2 /* ZLIB */
3 /* */
4 /* Compile sources into modules and link them into a service program. */
5 /* */
6 /******************************************************************************/
7
8 PGM
9
10 /* Configuration adjustable parameters. */
11
12 DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
13 VALUE('ZLIB') /* Source library. */
14 DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
15 VALUE('SOURCES') /* Source member file. */
16 DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
17 VALUE('TOOLS') /* Control member file. */
18
19 DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
20 VALUE('ZLIB') /* Module library. */
21
22 DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
23 VALUE('LGPL') /* Service program library. */
24
25 DCL VAR(&CFLAGS) TYPE(*CHAR) +
26 VALUE('OPTIMIZE(40)') /* Compile options. */
27
28
29 /* Working storage. */
30
31 DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */
32 DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
33
34
35 /* Compile sources into modules. */
36
37 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
38 '/ADLER32) SRCFILE(' *TCAT +
39 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
40 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
41 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
42
43 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
44 '/COMPRESS) SRCFILE(' *TCAT +
45 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
46 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
47 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
48
49 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
50 '/CRC32) SRCFILE(' *TCAT +
51 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
52 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
53 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
54
55 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
56 '/DEFLATE) SRCFILE(' *TCAT +
57 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
58 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
59 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
60
61 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
62 '/GZIO) SRCFILE(' *TCAT +
63 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
64 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
65 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
66
67 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
68 '/INFBACK) SRCFILE(' *TCAT +
69 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
70 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
71 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
72
73 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
74 '/INFFAST) SRCFILE(' *TCAT +
75 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
76 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
77 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
78
79 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
80 '/INFLATE) SRCFILE(' *TCAT +
81 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
82 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
83 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
84
85 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
86 '/INFTREES) SRCFILE(' *TCAT +
87 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
88 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
89 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
90
91 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
92 '/TREES) SRCFILE(' *TCAT +
93 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
94 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
95 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
96
97 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
98 '/UNCOMPR) SRCFILE(' *TCAT +
99 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
100 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
101 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
102
103 CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT +
104 '/ZUTIL) SRCFILE(' *TCAT +
105 &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT +
106 ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS)
107 CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN)
108
109
110 /* Link modules into a service program. */
111
112 CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) +
113 MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS +
114 &MODLIB/CRC32 &MODLIB/DEFLATE +
115 &MODLIB/GZIO &MODLIB/INFBACK +
116 &MODLIB/INFFAST &MODLIB/INFLATE +
117 &MODLIB/INFTREES &MODLIB/TREES +
118 &MODLIB/UNCOMPR &MODLIB/ZUTIL) +
119 SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
120 TEXT('ZLIB 1.2.2') TGTRLS(V4R4M0)
121
122 ENDPGM
0 ZLIB version 1.2.2 for AS400 installation instructions
1
2 I) From an AS400 *SAVF file:
3
4 1) Unpacking archive to an AS400 save file
5
6 On the AS400:
7
8 _ Create the ZLIB AS400 library:
9
10 CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
11
12 _ Create a work save file, for example:
13
14 CRTSAVF FILE(ZLIB/ZLIBSAVF)
15
16 On a PC connected to the target AS400:
17
18 _ Unpack the save file image to a PC file "ZLIBSAVF"
19 _ Upload this file into the save file on the AS400, for example
20 using ftp in BINARY mode.
21
22
23 2) Populating the ZLIB AS400 source library
24
25 On the AS400:
26
27 _ Extract the saved objects into the ZLIB AS400 library using:
28
29 RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)
30
31
32 3) Customize installation:
33
34 _ Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,
35 according to the comments.
36
37 _ Compile this member with:
38
39 CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)
40
41
42 4) Compile and generate the service program:
43
44 _ This can now be done by executing:
45
46 CALL PGM(ZLIB/COMPILE)
47
48
49
50 II) From the original source distribution:
51
52 1) On the AS400, create the source library:
53
54 CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library')
55
56 2) Create the source files:
57
58 CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')
59 CRTSRCPF FILE(ZLIB/H) RCDLEN(112) TEXT('ZLIB library includes')
60 CRTSRCPF FILE(ZLIB/TOOLS) RCDLEN(112) TEXT('ZLIB library control utilities')
61
62 3) From the machine hosting the distribution files, upload them (with
63 FTP in text mode, for example) according to the following table:
64
65 Original AS400 AS400 AS400 AS400
66 file file member type description
67 SOURCES Original ZLIB C subprogram sources
68 adler32.c ADLER32 C ZLIB - Compute the Adler-32 checksum of a dta strm
69 compress.c COMPRESS C ZLIB - Compress a memory buffer
70 crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream
71 deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm
72 gzio.c GZIO C ZLIB - IO on .gz files
73 infback.c INFBACK C ZLIB - Inflate using a callback interface
74 inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs
75 inflate.c INFLATE C ZLIB - Interface to inflate modules
76 inftrees.c INFTREES C ZLIB - Generate Huffman trees for efficient decode
77 trees.c TREES C ZLIB - Output deflated data using Huffman coding
78 uncompr.c UNCOMPR C ZLIB - Decompress a memory buffer
79 zutil.c ZUTIL C ZLIB - Target dependent utility functions
80 H Original ZLIB C and ILE/RPG include files
81 crc32.h CRC32 C ZLIB - CRC32 tables
82 deflate.h DEFLATE C ZLIB - Internal compression state
83 inffast.h INFFAST C ZLIB - Header to use inffast.c
84 inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes
85 inflate.h INFLATE C ZLIB - Internal inflate state definitions
86 inftrees.h INFTREES C ZLIB - Header to use inftrees.c
87 trees.h TREES C ZLIB - Created automatically with -DGEN_TREES_H
88 zconf.h ZCONF C ZLIB - Compression library configuration
89 zlib.h ZLIB C ZLIB - Compression library C user interface
90 as400/zlib.inc ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface
91 zutil.h ZUTIL C ZLIB - Internal interface and configuration
92 TOOLS Building source software & AS/400 README
93 as400/bndsrc BNDSRC Entry point exportation list
94 as400/compile.clp COMPILE CLP Compile sources & generate service program
95 as400/readme.txt README TXT Installation instructions
96
97 4) Continue as in I)3).
98
99
100
101
102 Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB
103 API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
104 Please read comments in this member for more information.
105
106 Remember that most foreign textual data are ASCII coded: this
107 implementation does not handle conversion from/to ASCII, so
108 text data code conversions must be done explicitely.
109
110 Always open zipped files in binary mode.
0 * ZLIB.INC - Interface to the general purpose compression library
1 *
2 * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
3 * Version 1.2.2.2
4 *
5 *
6 * WARNING:
7 * Procedures inflateInit(), inflateInit2(), deflateInit(),
8 * deflateInit2() and inflateBackInit() need to be called with
9 * two additional arguments:
10 * the package version string and the stream control structure.
11 * size. This is needed because RPG lacks some macro feature.
12 * Call these procedures as:
13 * inflateInit(...: ZLIB_VERSION: %size(z_stream))
14 *
15 /if not defined(ZLIB_H_)
16 /define ZLIB_H_
17 *
18 **************************************************************************
19 * Constants
20 **************************************************************************
21 *
22 D ZLIB_VERSION C '1.2.2.2' Header's version
23 D ZLIB_VERNUM C X'1222'
24 *
25 D Z_NO_FLUSH C 0
26 D Z_SYNC_FLUSH C 2
27 D Z_FULL_FLUSH C 3
28 D Z_FINISH C 4
29 D Z_BLOCK C 5
30 *
31 D Z_OK C 0
32 D Z_STREAM_END C 1
33 D Z_NEED_DICT C 2
34 D Z_ERRNO C -1
35 D Z_STREAM_ERROR C -2
36 D Z_DATA_ERROR C -3
37 D Z_MEM_ERROR C -4
38 D Z_BUF_ERROR C -5
39 DZ_VERSION_ERROR C -6
40 *
41 D Z_NO_COMPRESSION...
42 D C 0
43 D Z_BEST_SPEED C 1
44 D Z_BEST_COMPRESSION...
45 D C 9
46 D Z_DEFAULT_COMPRESSION...
47 D C -1
48 *
49 D Z_FILTERED C 1
50 D Z_HUFFMAN_ONLY C 2
51 D Z_RLE C 3
52 D Z_DEFAULT_STRATEGY...
53 D C 0
54 *
55 D Z_BINARY C 0
56 D Z_ASCII C 1
57 D Z_UNKNOWN C 2
58 *
59 D Z_DEFLATED C 8
60 *
61 D Z_NULL C 0
62 *
63 **************************************************************************
64 * Types
65 **************************************************************************
66 *
67 D z_streamp S * Stream struct ptr
68 D gzFile S * File pointer
69 D z_off_t S 10i 0 Stream offsets
70 *
71 **************************************************************************
72 * Structures
73 **************************************************************************
74 *
75 * The GZIP encode/decode stream support structure.
76 *
77 D z_stream DS align based(z_streamp)
78 D zs_next_in * Next input byte
79 D zs_avail_in 10U 0 Byte cnt at next_in
80 D zs_total_in 10U 0 Total bytes read
81 D zs_next_out * Output buffer ptr
82 D zs_avail_out 10U 0 Room left @ next_out
83 D zs_total_out 10U 0 Total bytes written
84 D zs_msg * Last errmsg or null
85 D zs_state * Internal state
86 D zs_zalloc * procptr Int. state allocator
87 D zs_free * procptr Int. state dealloc.
88 D zs_opaque * Private alloc. data
89 D zs_data_type 10i 0 ASC/BIN best guess
90 D zs_adler 10u 0 Uncompr. adler32 val
91 D 10U 0 Reserved
92 D 10U 0 Ptr. alignment
93 *
94 **************************************************************************
95 * Utility function prototypes
96 **************************************************************************
97 *
98 D compress PR 10I 0 extproc('compress')
99 D dest 32767 options(*varsize) Destination buffer
100 D destLen 10U 0 Destination length
101 D source 32767 const options(*varsize) Source buffer
102 D sourceLen 10u 0 value Source length
103 *
104 D compress2 PR 10I 0 extproc('compress2')
105 D dest 32767 options(*varsize) Destination buffer
106 D destLen 10U 0 Destination length
107 D source 32767 const options(*varsize) Source buffer
108 D sourceLen 10U 0 value Source length
109 D level 10I 0 value Compression level
110 *
111 D compressBound PR 10U 0 extproc('compressBound')
112 D sourceLen 10U 0 value
113 *
114 D uncompress PR 10I 0 extproc('uncompress')
115 D dest 32767 options(*varsize) Destination buffer
116 D destLen 10U 0 Destination length
117 D source 32767 const options(*varsize) Source buffer
118 D sourceLen 10U 0 value Source length
119 *
120 D gzopen PR extproc('gzopen')
121 D like(gzFile)
122 D path * value options(*string) File pathname
123 D mode * value options(*string) Open mode
124 *
125 D gzdopen PR extproc('gzdopen')
126 D like(gzFile)
127 D fd 10i 0 value File descriptor
128 D mode * value options(*string) Open mode
129 *
130 D gzsetparams PR 10I 0 extproc('gzsetparams')
131 D file value like(gzFile) File pointer
132 D level 10I 0 value
133 D strategy 10i 0 value
134 *
135 D gzread PR 10I 0 extproc('gzread')
136 D file value like(gzFile) File pointer
137 D buf 32767 options(*varsize) Buffer
138 D len 10u 0 value Buffer length
139 *
140 D gzwrite PR 10I 0 extproc('gzwrite')
141 D file value like(gzFile) File pointer
142 D buf 32767 const options(*varsize) Buffer
143 D len 10u 0 value Buffer length
144 *
145 D gzputs PR 10I 0 extproc('gzputs')
146 D file value like(gzFile) File pointer
147 D s * value options(*string) String to output
148 *
149 D gzgets PR * extproc('gzgets')
150 D file value like(gzFile) File pointer
151 D buf 32767 options(*varsize) Read buffer
152 D len 10i 0 value Buffer length
153 *
154 D gzflush PR 10i 0 extproc('gzflush')
155 D file value like(gzFile) File pointer
156 D flush 10I 0 value Type of flush
157 *
158 D gzseek PR extproc('gzseek')
159 D like(z_off_t)
160 D file value like(gzFile) File pointer
161 D offset value like(z_off_t) Offset
162 D whence 10i 0 value Origin
163 *
164 D gzrewind PR 10i 0 extproc('gzrewind')
165 D file value like(gzFile) File pointer
166 *
167 D gztell PR extproc('gztell')
168 D like(z_off_t)
169 D file value like(gzFile) File pointer
170 *
171 D gzeof PR 10i 0 extproc('gzeof')
172 D file value like(gzFile) File pointer
173 *
174 D gzclose PR 10i 0 extproc('gzclose')
175 D file value like(gzFile) File pointer
176 *
177 D gzerror PR * extproc('gzerror') Error string
178 D file value like(gzFile) File pointer
179 D errnum 10I 0 Error code
180 *
181 D gzclearerr PR extproc('gzclearerr')
182 D file value like(gzFile) File pointer
183 *
184 **************************************************************************
185 * Basic function prototypes
186 **************************************************************************
187 *
188 D zlibVersion PR * extproc('zlibVersion') Version string
189 *
190 D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression
191 D strm like(z_stream) Compression stream
192 D level 10I 0 value Compression level
193 D version * value options(*string) Version string
194 D stream_size 10i 0 value Stream struct. size
195 *
196 D deflate PR 10I 0 extproc('deflate') Compress data
197 D strm like(z_stream) Compression stream
198 D flush 10I 0 value Flush type required
199 *
200 D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression
201 D strm like(z_stream) Compression stream
202 *
203 D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion
204 D strm like(z_stream) Expansion stream
205 D version * value options(*string) Version string
206 D stream_size 10i 0 value Stream struct. size
207 *
208 D inflate PR 10I 0 extproc('inflate') Expand data
209 D strm like(z_stream) Expansion stream
210 D flush 10I 0 value Flush type required
211 *
212 D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion
213 D strm like(z_stream) Expansion stream
214 *
215 **************************************************************************
216 * Advanced function prototypes
217 **************************************************************************
218 *
219 D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression
220 D strm like(z_stream) Compression stream
221 D level 10I 0 value Compression level
222 D method 10I 0 value Compression method
223 D windowBits 10I 0 value log2(window size)
224 D memLevel 10I 0 value Mem/cmpress tradeoff
225 D strategy 10I 0 value Compression stategy
226 D version * value options(*string) Version string
227 D stream_size 10i 0 value Stream struct. size
228 *
229 D deflateSetDictionary...
230 D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary
231 D strm like(z_stream) Compression stream
232 D dictionary 32767 const options(*varsize) Dictionary bytes
233 D dictLength 10U 0 value Dictionary length
234 *
235 D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm
236 D dest like(z_stream) Destination stream
237 D source like(z_stream) Source stream
238 *
239 D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream
240 D strm like(z_stream) Compression stream
241 *
242 D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat
243 D strm like(z_stream) Compression stream
244 D level 10I 0 value Compression level
245 D strategy 10I 0 value Compression stategy
246 *
247 D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat
248 D strm like(z_stream) Compression stream
249 D sourcelen 10U 0 value Compression level
250 *
251 D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat
252 D strm like(z_stream) Compression stream
253 D bits 10I 0 value Number of bits to insert
254 D value 10I 0 value Bits to insert
255 *
256 D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion
257 D strm like(z_stream) Expansion stream
258 D windowBits 10I 0 value log2(window size)
259 D version * value options(*string) Version string
260 D stream_size 10i 0 value Stream struct. size
261 *
262 D inflateSetDictionary...
263 D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary
264 D strm like(z_stream) Expansion stream
265 D dictionary 32767 const options(*varsize) Dictionary bytes
266 D dictLength 10U 0 value Dictionary length
267 *
268 D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion
269 D strm like(z_stream) Expansion stream
270 *
271 D inflateCopy PR 10I 0 extproc('inflateCopy')
272 D dest like(z_stream) Destination stream
273 D source like(z_stream) Source stream
274 *
275 D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream
276 D strm like(z_stream) Expansion stream
277 *
278 D inflateBackInit...
279 D PR 10I 0 extproc('inflateBackInit_')
280 D strm like(z_stream) Expansion stream
281 D windowBits 10I 0 value Log2(buffer size)
282 D window 32767 options(*varsize) Buffer
283 D version * value options(*string) Version string
284 D stream_size 10i 0 value Stream struct. size
285 *
286 D inflateBack PR 10I 0 extproc('inflateBack')
287 D strm like(z_stream) Expansion stream
288 D in * value procptr Input function
289 D in_desc * value Input descriptor
290 D out * value procptr Output function
291 D out_desc * value Output descriptor
292 *
293 D inflateBackEnd PR 10I 0 extproc('inflateBackEnd')
294 D strm like(z_stream) Expansion stream
295 *
296 D zlibCompileFlags...
297 D PR 10U 0 extproc('zlibCompileFlags')
298 *
299 **************************************************************************
300 * Checksum function prototypes
301 **************************************************************************
302 *
303 D adler32 PR 10U 0 extproc('adler32') New checksum
304 D adler 10U 0 value Old checksum
305 D buf 32767 const options(*varsize) Bytes to accumulate
306 D len 10U 0 value Buffer length
307 *
308 D crc32 PR 10U 0 extproc('crc32') New checksum
309 D crc 10U 0 value Old checksum
310 D buf 32767 const options(*varsize) Bytes to accumulate
311 D len 10U 0 value Buffer length
312 *
313 **************************************************************************
314 * Miscellaneous function prototypes
315 **************************************************************************
316 *
317 D zError PR * extproc('zError') Error string
318 D err 10I 0 value Error code
319 *
320 D inflateSyncPoint...
321 D PR 10I 0 extproc('inflateSyncPoint')
322 D strm like(z_stream) Expansion stream
323 *
324 D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs
325 *
326 /endif
0 /* compress.c -- compress a memory buffer
1 * Copyright (C) 1995-2003 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #define ZLIB_INTERNAL
8 #include "zlib.h"
9
10 /* ===========================================================================
11 Compresses the source buffer into the destination buffer. The level
12 parameter has the same meaning as in deflateInit. sourceLen is the byte
13 length of the source buffer. Upon entry, destLen is the total size of the
14 destination buffer, which must be at least 0.1% larger than sourceLen plus
15 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
16
17 compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
18 memory, Z_BUF_ERROR if there was not enough room in the output buffer,
19 Z_STREAM_ERROR if the level parameter is invalid.
20 */
21 int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
22 Bytef *dest;
23 uLongf *destLen;
24 const Bytef *source;
25 uLong sourceLen;
26 int level;
27 {
28 z_stream stream;
29 int err;
30
31 stream.next_in = (Bytef*)source;
32 stream.avail_in = (uInt)sourceLen;
33 #ifdef MAXSEG_64K
34 /* Check for source > 64K on 16-bit machine: */
35 if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
36 #endif
37 stream.next_out = dest;
38 stream.avail_out = (uInt)*destLen;
39 if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
40
41 stream.zalloc = (alloc_func)0;
42 stream.zfree = (free_func)0;
43 stream.opaque = (voidpf)0;
44
45 err = deflateInit(&stream, level);
46 if (err != Z_OK) return err;
47
48 err = deflate(&stream, Z_FINISH);
49 if (err != Z_STREAM_END) {
50 deflateEnd(&stream);
51 return err == Z_OK ? Z_BUF_ERROR : err;
52 }
53 *destLen = stream.total_out;
54
55 err = deflateEnd(&stream);
56 return err;
57 }
58
59 /* ===========================================================================
60 */
61 int ZEXPORT compress (dest, destLen, source, sourceLen)
62 Bytef *dest;
63 uLongf *destLen;
64 const Bytef *source;
65 uLong sourceLen;
66 {
67 return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
68 }
69
70 /* ===========================================================================
71 If the default memLevel or windowBits for deflateInit() is changed, then
72 this function needs to be updated.
73 */
74 uLong ZEXPORT compressBound (sourceLen)
75 uLong sourceLen;
76 {
77 return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
78 }
0 #!/bin/sh
1 # configure script for zlib. This script is needed only if
2 # you wish to build a shared library and your system supports them,
3 # of if you need special compiler, flags or install directory.
4 # Otherwise, you can just use directly "make test; make install"
5 #
6 # To create a shared library, use "configure --shared"; by default a static
7 # library is created. If the primitive shared library support provided here
8 # does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
9 #
10 # To impose specific compiler or flags or install directory, use for example:
11 # prefix=$HOME CC=cc CFLAGS="-O4" ./configure
12 # or for csh/tcsh users:
13 # (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
14 # LDSHARED is the command to be used to create a shared library
15
16 # Incorrect settings of CC or CFLAGS may prevent creating a shared library.
17 # If you have problems, try without defining CC and CFLAGS before reporting
18 # an error.
19
20 LIBS=libz.a
21 LDFLAGS="-L. ${LIBS}"
22 VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
23 VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
24 VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
25 AR=${AR-"ar rc"}
26 RANLIB=${RANLIB-"ranlib"}
27 prefix=${prefix-/usr/local}
28 exec_prefix=${exec_prefix-'${prefix}'}
29 libdir=${libdir-'${exec_prefix}/lib'}
30 includedir=${includedir-'${prefix}/include'}
31 mandir=${mandir-'${prefix}/share/man'}
32 shared_ext='.so'
33 shared=0
34 gcc=0
35 old_cc="$CC"
36 old_cflags="$CFLAGS"
37
38 while test $# -ge 1
39 do
40 case "$1" in
41 -h* | --h*)
42 echo 'usage:'
43 echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
44 echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]'
45 exit 0;;
46 -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
47 -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
48 -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
49 -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;;
50 -p* | --p*) prefix="$2"; shift; shift;;
51 -e* | --e*) exec_prefix="$2"; shift; shift;;
52 -l* | --l*) libdir="$2"; shift; shift;;
53 -i* | --i*) includedir="$2"; shift; shift;;
54 -s* | --s*) shared=1; shift;;
55 *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;;
56 esac
57 done
58
59 test=ztest$$
60 cat > $test.c <<EOF
61 extern int getchar();
62 int hello() {return getchar();}
63 EOF
64
65 test -z "$CC" && echo Checking for gcc...
66 cc=${CC-gcc}
67 cflags=${CFLAGS-"-O3"}
68 # to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
69 case "$cc" in
70 *gcc*) gcc=1;;
71 esac
72
73 if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
74 CC="$cc"
75 SFLAGS=${CFLAGS-"-fPIC -O3"}
76 CFLAGS="$cflags"
77 case `(uname -s || echo unknown) 2>/dev/null` in
78 Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
79 CYGWIN* | Cygwin* | cygwin* | OS/2* )
80 EXE='.exe';;
81 QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
82 # (alain.bonnefoy@icbt.com)
83 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};;
84 HP-UX*) LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
85 shared_ext='.sl'
86 SHAREDLIB='libz.sl';;
87 Darwin*) shared_ext='.dylib'
88 SHAREDLIB=libz$shared_ext
89 SHAREDLIBV=libz.$VER$shared_ext
90 SHAREDLIBM=libz.$VER1$shared_ext
91 LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
92 *) LDSHARED=${LDSHARED-"$cc -shared"};;
93 esac
94 else
95 # find system name and corresponding cc options
96 CC=${CC-cc}
97 case `(uname -sr || echo unknown) 2>/dev/null` in
98 HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
99 CFLAGS=${CFLAGS-"-O"}
100 # LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
101 LDSHARED=${LDSHARED-"ld -b"}
102 shared_ext='.sl'
103 SHAREDLIB='libz.sl';;
104 IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
105 CFLAGS=${CFLAGS-"-ansi -O2"}
106 LDSHARED=${LDSHARED-"cc -shared"};;
107 OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
108 CFLAGS=${CFLAGS-"-O -std1"}
109 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};;
110 OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
111 CFLAGS=${CFLAGS-"-O -std1"}
112 LDSHARED=${LDSHARED-"cc -shared"};;
113 QNX*) SFLAGS=${CFLAGS-"-4 -O"}
114 CFLAGS=${CFLAGS-"-4 -O"}
115 LDSHARED=${LDSHARED-"cc"}
116 RANLIB=${RANLIB-"true"}
117 AR="cc -A";;
118 SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
119 CFLAGS=${CFLAGS-"-O3"}
120 LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
121 SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
122 CFLAGS=${CFLAGS-"-fast -xcg89"}
123 LDSHARED=${LDSHARED-"cc -G"};;
124 SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
125 CFLAGS=${CFLAGS-"-O2"}
126 LDSHARED=${LDSHARED-"ld"};;
127 SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
128 CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
129 LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
130 UNIX_System_V\ 4.2.0)
131 SFLAGS=${CFLAGS-"-KPIC -O"}
132 CFLAGS=${CFLAGS-"-O"}
133 LDSHARED=${LDSHARED-"cc -G"};;
134 UNIX_SV\ 4.2MP)
135 SFLAGS=${CFLAGS-"-Kconform_pic -O"}
136 CFLAGS=${CFLAGS-"-O"}
137 LDSHARED=${LDSHARED-"cc -G"};;
138 OpenUNIX\ 5)
139 SFLAGS=${CFLAGS-"-KPIC -O"}
140 CFLAGS=${CFLAGS-"-O"}
141 LDSHARED=${LDSHARED-"cc -G"};;
142 AIX*) # Courtesy of dbakker@arrayasolutions.com
143 SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
144 CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
145 LDSHARED=${LDSHARED-"xlc -G"};;
146 # send working options for other systems to support@gzip.org
147 *) SFLAGS=${CFLAGS-"-O"}
148 CFLAGS=${CFLAGS-"-O"}
149 LDSHARED=${LDSHARED-"cc -shared"};;
150 esac
151 fi
152
153 SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
154 SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
155 SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
156
157 if test $shared -eq 1; then
158 echo Checking for shared library support...
159 # we must test in two steps (cc then ld), required at least on SunOS 4.x
160 if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
161 test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
162 CFLAGS="$SFLAGS"
163 LIBS="$SHAREDLIBV"
164 echo Building shared library $SHAREDLIBV with $CC.
165 elif test -z "$old_cc" -a -z "$old_cflags"; then
166 echo No shared library support.
167 shared=0;
168 else
169 echo 'No shared library support; try without defining CC and CFLAGS'
170 shared=0;
171 fi
172 fi
173 if test $shared -eq 0; then
174 LDSHARED="$CC"
175 echo Building static library $LIBS version $VER with $CC.
176 else
177 LDFLAGS="-L. ${SHAREDLIBV}"
178 fi
179
180 cat > $test.c <<EOF
181 #include <unistd.h>
182 int main() { return 0; }
183 EOF
184 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
185 sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h
186 echo "Checking for unistd.h... Yes."
187 else
188 cp -p zconf.in.h zconf.h
189 echo "Checking for unistd.h... No."
190 fi
191
192 cat > $test.c <<EOF
193 #include <stdio.h>
194 #include <stdarg.h>
195 #include "zconf.h"
196
197 int main()
198 {
199 #ifndef STDC
200 choke me
201 #endif
202
203 return 0;
204 }
205 EOF
206
207 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
208 echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()"
209
210 cat > $test.c <<EOF
211 #include <stdio.h>
212 #include <stdarg.h>
213
214 int mytest(char *fmt, ...)
215 {
216 char buf[20];
217 va_list ap;
218
219 va_start(ap, fmt);
220 vsnprintf(buf, sizeof(buf), fmt, ap);
221 va_end(ap);
222 return 0;
223 }
224
225 int main()
226 {
227 return (mytest("Hello%d\n", 1));
228 }
229 EOF
230
231 if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
232 echo "Checking for vsnprintf() in stdio.h... Yes."
233
234 cat >$test.c <<EOF
235 #include <stdio.h>
236 #include <stdarg.h>
237
238 int mytest(char *fmt, ...)
239 {
240 int n;
241 char buf[20];
242 va_list ap;
243
244 va_start(ap, fmt);
245 n = vsnprintf(buf, sizeof(buf), fmt, ap);
246 va_end(ap);
247 return n;
248 }
249
250 int main()
251 {
252 return (mytest("Hello%d\n", 1));
253 }
254 EOF
255
256 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
257 echo "Checking for return value of vsnprintf()... Yes."
258 else
259 CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
260 echo "Checking for return value of vsnprintf()... No."
261 echo " WARNING: apparently vsnprintf() does not return a value. zlib"
262 echo " can build but will be open to possible string-format security"
263 echo " vulnerabilities."
264 fi
265 else
266 CFLAGS="$CFLAGS -DNO_vsnprintf"
267 echo "Checking for vsnprintf() in stdio.h... No."
268 echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
269 echo " can build but will be open to possible buffer-overflow security"
270 echo " vulnerabilities."
271
272 cat >$test.c <<EOF
273 #include <stdio.h>
274 #include <stdarg.h>
275
276 int mytest(char *fmt, ...)
277 {
278 int n;
279 char buf[20];
280 va_list ap;
281
282 va_start(ap, fmt);
283 n = vsprintf(buf, fmt, ap);
284 va_end(ap);
285 return n;
286 }
287
288 int main()
289 {
290 return (mytest("Hello%d\n", 1));
291 }
292 EOF
293
294 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
295 echo "Checking for return value of vsprintf()... Yes."
296 else
297 CFLAGS="$CFLAGS -DHAS_vsprintf_void"
298 echo "Checking for return value of vsprintf()... No."
299 echo " WARNING: apparently vsprintf() does not return a value. zlib"
300 echo " can build but will be open to possible string-format security"
301 echo " vulnerabilities."
302 fi
303 fi
304 else
305 echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()"
306
307 cat >$test.c <<EOF
308 #include <stdio.h>
309
310 int mytest()
311 {
312 char buf[20];
313
314 snprintf(buf, sizeof(buf), "%s", "foo");
315 return 0;
316 }
317
318 int main()
319 {
320 return (mytest());
321 }
322 EOF
323
324 if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
325 echo "Checking for snprintf() in stdio.h... Yes."
326
327 cat >$test.c <<EOF
328 #include <stdio.h>
329
330 int mytest()
331 {
332 char buf[20];
333
334 return snprintf(buf, sizeof(buf), "%s", "foo");
335 }
336
337 int main()
338 {
339 return (mytest());
340 }
341 EOF
342
343 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
344 echo "Checking for return value of snprintf()... Yes."
345 else
346 CFLAGS="$CFLAGS -DHAS_snprintf_void"
347 echo "Checking for return value of snprintf()... No."
348 echo " WARNING: apparently snprintf() does not return a value. zlib"
349 echo " can build but will be open to possible string-format security"
350 echo " vulnerabilities."
351 fi
352 else
353 CFLAGS="$CFLAGS -DNO_snprintf"
354 echo "Checking for snprintf() in stdio.h... No."
355 echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
356 echo " can build but will be open to possible buffer-overflow security"
357 echo " vulnerabilities."
358
359 cat >$test.c <<EOF
360 #include <stdio.h>
361
362 int mytest()
363 {
364 char buf[20];
365
366 return sprintf(buf, "%s", "foo");
367 }
368
369 int main()
370 {
371 return (mytest());
372 }
373 EOF
374
375 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
376 echo "Checking for return value of sprintf()... Yes."
377 else
378 CFLAGS="$CFLAGS -DHAS_sprintf_void"
379 echo "Checking for return value of sprintf()... No."
380 echo " WARNING: apparently sprintf() does not return a value. zlib"
381 echo " can build but will be open to possible string-format security"
382 echo " vulnerabilities."
383 fi
384 fi
385 fi
386
387 cat >$test.c <<EOF
388 #include <errno.h>
389 int main() { return 0; }
390 EOF
391 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
392 echo "Checking for errno.h... Yes."
393 else
394 echo "Checking for errno.h... No."
395 CFLAGS="$CFLAGS -DNO_ERRNO_H"
396 fi
397
398 cat > $test.c <<EOF
399 #include <sys/types.h>
400 #include <sys/mman.h>
401 #include <sys/stat.h>
402 caddr_t hello() {
403 return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0);
404 }
405 EOF
406 if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
407 CFLAGS="$CFLAGS -DUSE_MMAP"
408 echo Checking for mmap support... Yes.
409 else
410 echo Checking for mmap support... No.
411 fi
412
413 CPP=${CPP-"$CC -E"}
414 case $CFLAGS in
415 *ASMV*)
416 if test "`nm $test.o | grep _hello`" = ""; then
417 CPP="$CPP -DNO_UNDERLINE"
418 echo Checking for underline in external names... No.
419 else
420 echo Checking for underline in external names... Yes.
421 fi;;
422 esac
423
424 rm -f $test.[co] $test $test$shared_ext
425
426 # udpate Makefile
427 sed < Makefile.in "
428 /^CC *=/s#=.*#=$CC#
429 /^CFLAGS *=/s#=.*#=$CFLAGS#
430 /^CPP *=/s#=.*#=$CPP#
431 /^LDSHARED *=/s#=.*#=$LDSHARED#
432 /^LIBS *=/s#=.*#=$LIBS#
433 /^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
434 /^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
435 /^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
436 /^AR *=/s#=.*#=$AR#
437 /^RANLIB *=/s#=.*#=$RANLIB#
438 /^EXE *=/s#=.*#=$EXE#
439 /^prefix *=/s#=.*#=$prefix#
440 /^exec_prefix *=/s#=.*#=$exec_prefix#
441 /^libdir *=/s#=.*#=$libdir#
442 /^includedir *=/s#=.*#=$includedir#
443 /^mandir *=/s#=.*#=$mandir#
444 /^LDFLAGS *=/s#=.*#=$LDFLAGS#
445 " > Makefile
0 All files under this contrib directory are UNSUPPORTED. There were
1 provided by users of zlib and were not tested by the authors of zlib.
2 Use at your own risk. Please contact the authors of the contributions
3 for help about these, not the zlib authors. Thanks.
4
5
6 ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
7 Support for Ada
8 See http://zlib-ada.sourceforge.net/
9
10 asm586/
11 asm686/ by Brian Raiter <breadbox@muppetlabs.com>
12 asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
13 See http://www.muppetlabs.com/~breadbox/software/assembly.html
14
15 blast/ by Mark Adler <madler@alumni.caltech.edu>
16 Decompressor for output of PKWare Data Compression Library (DCL)
17
18 delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
19 Support for Delphi and C++ Builder
20
21 dotzlib/ by Henrik Ravn <henrik@ravn.com>
22 Support for Microsoft .Net and Visual C++ .Net
23
24 infback9/ by Mark Adler <madler@alumni.caltech.edu>
25 Unsupported diffs to infback to decode the deflate64 format
26
27 inflate86/ by Chris Anderson <christop@charm.net>
28 Tuned x86 gcc asm code to replace inflate_fast()
29
30 iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
31 A C++ I/O streams interface to the zlib gz* functions
32
33 iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
34 Another C++ I/O streams interface
35
36 iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
37 and Kevin Ruland <kevin@rodin.wustl.edu>
38 Yet another C++ I/O streams interface
39
40 masm686/ by Dan Higdon <hdan@kinesoft.com>
41 and Chuck Walbourn <chuckw@kinesoft.com>
42 asm code for Pentium Pro/PII, using the MASM syntax
43
44 masmx86/ by Gilles Vollant <info@winimage.com>
45 x86 asm code to replace longest_match() and inflate_fast(),
46 for Visual C++ and MASM
47
48 minizip/ by Gilles Vollant <info@winimage.com>
49 Mini zip and unzip based on zlib
50 See http://www.winimage.com/zLibDll/unzip.html
51
52 pascal/ by Bob Dellaca <bobdl@xtra.co.nz> et al.
53 Support for Pascal
54
55 puff/ by Mark Adler <madler@alumni.caltech.edu>
56 Small, low memory usage inflate. Also serves to provide an
57 unambiguous description of the deflate format.
58
59 testzlib/ by Gilles Vollant <info@winimage.com>
60 Example of the use of zlib
61
62 untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
63 A very simple tar.gz file extractor using zlib
64
65 vstudio/ by Gilles Vollant <info@winimage.com>
66 Building a minizip-enhanced zlib with Microsoft Visual Studio
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7 --
8 -- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
9
10 -- This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
11 --
12 -- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
13 -- of exactly the correct size is used for decompressed data, and the last
14 -- few bytes passed in to Zlib are checksum bytes.
15
16 -- This program compresses a string of text, and then decompresses the
17 -- compressed text into a buffer of the same size as the original text.
18
19 with Ada.Streams; use Ada.Streams;
20 with Ada.Text_IO;
21
22 with ZLib; use ZLib;
23
24 procedure Buffer_Demo is
25 EOL : Character renames ASCII.LF;
26 Text : constant String
27 := "Four score and seven years ago our fathers brought forth," & EOL &
28 "upon this continent, a new nation, conceived in liberty," & EOL &
29 "and dedicated to the proposition that `all men are created equal'.";
30
31 Source : Stream_Element_Array (1 .. Text'Length);
32 for Source'Address use Text'Address;
33
34 begin
35 Ada.Text_IO.Put (Text);
36 Ada.Text_IO.New_Line;
37 Ada.Text_IO.Put_Line
38 ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
39
40 declare
41 Compressed_Data : Stream_Element_Array (1 .. Text'Length);
42 L : Stream_Element_Offset;
43 begin
44 Compress : declare
45 Compressor : Filter_Type;
46 I : Stream_Element_Offset;
47 begin
48 Deflate_Init (Compressor);
49
50 -- Compress the whole of T at once.
51
52 Translate (Compressor, Source, I, Compressed_Data, L, Finish);
53 pragma Assert (I = Source'Last);
54
55 Close (Compressor);
56
57 Ada.Text_IO.Put_Line
58 ("Compressed size : "
59 & Stream_Element_Offset'Image (L) & " bytes");
60 end Compress;
61
62 -- Now we decompress the data, passing short blocks of data to Zlib
63 -- (because this demonstrates the problem - the last block passed will
64 -- contain checksum information and there will be no output, only a
65 -- check inside Zlib that the checksum is correct).
66
67 Decompress : declare
68 Decompressor : Filter_Type;
69
70 Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
71
72 Block_Size : constant := 4;
73 -- This makes sure that the last block contains
74 -- only Adler checksum data.
75
76 P : Stream_Element_Offset := Compressed_Data'First - 1;
77 O : Stream_Element_Offset;
78 begin
79 Inflate_Init (Decompressor);
80
81 loop
82 Translate
83 (Decompressor,
84 Compressed_Data
85 (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
86 P,
87 Uncompressed_Data
88 (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
89 O,
90 No_Flush);
91
92 Ada.Text_IO.Put_Line
93 ("Total in : " & Count'Image (Total_In (Decompressor)) &
94 ", out : " & Count'Image (Total_Out (Decompressor)));
95
96 exit when P = L;
97 end loop;
98
99 Ada.Text_IO.New_Line;
100 Ada.Text_IO.Put_Line
101 ("Decompressed text matches original text : "
102 & Boolean'Image (Uncompressed_Data = Source));
103 end Decompress;
104 end;
105 end Buffer_Demo;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7 -- Continuous test for ZLib multithreading. If the test would fail
8 -- we should provide thread safe allocation routines for the Z_Stream.
9 --
10 -- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
11
12 with ZLib;
13 with Ada.Streams;
14 with Ada.Numerics.Discrete_Random;
15 with Ada.Text_IO;
16 with Ada.Exceptions;
17 with Ada.Task_Identification;
18
19 procedure MTest is
20 use Ada.Streams;
21 use ZLib;
22
23 Stop : Boolean := False;
24
25 pragma Atomic (Stop);
26
27 subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
28
29 package Random_Elements is
30 new Ada.Numerics.Discrete_Random (Visible_Symbols);
31
32 task type Test_Task;
33
34 task body Test_Task is
35 Buffer : Stream_Element_Array (1 .. 100_000);
36 Gen : Random_Elements.Generator;
37
38 Buffer_First : Stream_Element_Offset;
39 Compare_First : Stream_Element_Offset;
40
41 Deflate : Filter_Type;
42 Inflate : Filter_Type;
43
44 procedure Further (Item : in Stream_Element_Array);
45
46 procedure Read_Buffer
47 (Item : out Ada.Streams.Stream_Element_Array;
48 Last : out Ada.Streams.Stream_Element_Offset);
49
50 -------------
51 -- Further --
52 -------------
53
54 procedure Further (Item : in Stream_Element_Array) is
55
56 procedure Compare (Item : in Stream_Element_Array);
57
58 -------------
59 -- Compare --
60 -------------
61
62 procedure Compare (Item : in Stream_Element_Array) is
63 Next_First : Stream_Element_Offset := Compare_First + Item'Length;
64 begin
65 if Buffer (Compare_First .. Next_First - 1) /= Item then
66 raise Program_Error;
67 end if;
68
69 Compare_First := Next_First;
70 end Compare;
71
72 procedure Compare_Write is new ZLib.Write (Write => Compare);
73 begin
74 Compare_Write (Inflate, Item, No_Flush);
75 end Further;
76
77 -----------------
78 -- Read_Buffer --
79 -----------------
80
81 procedure Read_Buffer
82 (Item : out Ada.Streams.Stream_Element_Array;
83 Last : out Ada.Streams.Stream_Element_Offset)
84 is
85 Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First;
86 Next_First : Stream_Element_Offset;
87 begin
88 if Item'Length <= Buff_Diff then
89 Last := Item'Last;
90
91 Next_First := Buffer_First + Item'Length;
92
93 Item := Buffer (Buffer_First .. Next_First - 1);
94
95 Buffer_First := Next_First;
96 else
97 Last := Item'First + Buff_Diff;
98 Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
99 Buffer_First := Buffer'Last + 1;
100 end if;
101 end Read_Buffer;
102
103 procedure Translate is new Generic_Translate
104 (Data_In => Read_Buffer,
105 Data_Out => Further);
106
107 begin
108 Random_Elements.Reset (Gen);
109
110 Buffer := (others => 20);
111
112 Main : loop
113 for J in Buffer'Range loop
114 Buffer (J) := Random_Elements.Random (Gen);
115
116 Deflate_Init (Deflate);
117 Inflate_Init (Inflate);
118
119 Buffer_First := Buffer'First;
120 Compare_First := Buffer'First;
121
122 Translate (Deflate);
123
124 if Compare_First /= Buffer'Last + 1 then
125 raise Program_Error;
126 end if;
127
128 Ada.Text_IO.Put_Line
129 (Ada.Task_Identification.Image
130 (Ada.Task_Identification.Current_Task)
131 & Stream_Element_Offset'Image (J)
132 & ZLib.Count'Image (Total_Out (Deflate)));
133
134 Close (Deflate);
135 Close (Inflate);
136
137 exit Main when Stop;
138 end loop;
139 end loop Main;
140 exception
141 when E : others =>
142 Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
143 Stop := True;
144 end Test_Task;
145
146 Test : array (1 .. 4) of Test_Task;
147
148 pragma Unreferenced (Test);
149
150 Dummy : Character;
151
152 begin
153 Ada.Text_IO.Get_Immediate (Dummy);
154 Stop := True;
155 end MTest;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
9
10 -- Test/demo program for the generic read interface.
11
12 with Ada.Numerics.Discrete_Random;
13 with Ada.Streams;
14 with Ada.Text_IO;
15
16 with ZLib;
17
18 procedure Read is
19
20 use Ada.Streams;
21
22 ------------------------------------
23 -- Test configuration parameters --
24 ------------------------------------
25
26 File_Size : Stream_Element_Offset := 100_000;
27
28 Continuous : constant Boolean := False;
29 -- If this constant is True, the test would be repeated again and again,
30 -- with increment File_Size for every iteration.
31
32 Header : constant ZLib.Header_Type := ZLib.Default;
33 -- Do not use Header other than Default in ZLib versions 1.1.4 and older.
34
35 Init_Random : constant := 8;
36 -- We are using the same random sequence, in case of we catch bug,
37 -- so we would be able to reproduce it.
38
39 -- End --
40
41 Pack_Size : Stream_Element_Offset;
42 Offset : Stream_Element_Offset;
43
44 Filter : ZLib.Filter_Type;
45
46 subtype Visible_Symbols
47 is Stream_Element range 16#20# .. 16#7E#;
48
49 package Random_Elements is new
50 Ada.Numerics.Discrete_Random (Visible_Symbols);
51
52 Gen : Random_Elements.Generator;
53 Period : constant Stream_Element_Offset := 200;
54 -- Period constant variable for random generator not to be very random.
55 -- Bigger period, harder random.
56
57 Read_Buffer : Stream_Element_Array (1 .. 2048);
58 Read_First : Stream_Element_Offset;
59 Read_Last : Stream_Element_Offset;
60
61 procedure Reset;
62
63 procedure Read
64 (Item : out Stream_Element_Array;
65 Last : out Stream_Element_Offset);
66 -- this procedure is for generic instantiation of
67 -- ZLib.Read
68 -- reading data from the File_In.
69
70 procedure Read is new ZLib.Read
71 (Read,
72 Read_Buffer,
73 Rest_First => Read_First,
74 Rest_Last => Read_Last);
75
76 ----------
77 -- Read --
78 ----------
79
80 procedure Read
81 (Item : out Stream_Element_Array;
82 Last : out Stream_Element_Offset) is
83 begin
84 Last := Stream_Element_Offset'Min
85 (Item'Last,
86 Item'First + File_Size - Offset);
87
88 for J in Item'First .. Last loop
89 if J < Item'First + Period then
90 Item (J) := Random_Elements.Random (Gen);
91 else
92 Item (J) := Item (J - Period);
93 end if;
94
95 Offset := Offset + 1;
96 end loop;
97 end Read;
98
99 -----------
100 -- Reset --
101 -----------
102
103 procedure Reset is
104 begin
105 Random_Elements.Reset (Gen, Init_Random);
106 Pack_Size := 0;
107 Offset := 1;
108 Read_First := Read_Buffer'Last + 1;
109 Read_Last := Read_Buffer'Last;
110 end Reset;
111
112 begin
113 Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
114
115 loop
116 for Level in ZLib.Compression_Level'Range loop
117
118 Ada.Text_IO.Put ("Level ="
119 & ZLib.Compression_Level'Image (Level));
120
121 -- Deflate using generic instantiation.
122
123 ZLib.Deflate_Init
124 (Filter,
125 Level,
126 Header => Header);
127
128 Reset;
129
130 Ada.Text_IO.Put
131 (Stream_Element_Offset'Image (File_Size) & " ->");
132
133 loop
134 declare
135 Buffer : Stream_Element_Array (1 .. 1024);
136 Last : Stream_Element_Offset;
137 begin
138 Read (Filter, Buffer, Last);
139
140 Pack_Size := Pack_Size + Last - Buffer'First + 1;
141
142 exit when Last < Buffer'Last;
143 end;
144 end loop;
145
146 Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
147
148 ZLib.Close (Filter);
149 end loop;
150
151 exit when not Continuous;
152
153 File_Size := File_Size + 1;
154 end loop;
155 end Read;
0 ZLib for Ada thick binding (ZLib.Ada)
1 Release 1.3
2
3 ZLib.Ada is a thick binding interface to the popular ZLib data
4 compression library, available at http://www.gzip.org/zlib/.
5 It provides Ada-style access to the ZLib C library.
6
7
8 Here are the main changes since ZLib.Ada 1.2:
9
10 - Attension: ZLib.Read generic routine have a initialization requirement
11 for Read_Last parameter now. It is a bit incompartible with previous version,
12 but extends functionality, we could use new parameters Allow_Read_Some and
13 Flush now.
14
15 - Added Is_Open routines to ZLib and ZLib.Streams packages.
16
17 - Add pragma Assert to check Stream_Element is 8 bit.
18
19 - Fix extraction to buffer with exact known decompressed size. Error reported by
20 Steve Sangwine.
21
22 - Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
23 computers. Patch provided by Pascal Obry.
24
25 - Add Status_Error exception definition.
26
27 - Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
28
29
30 How to build ZLib.Ada under GNAT
31
32 You should have the ZLib library already build on your computer, before
33 building ZLib.Ada. Make the directory of ZLib.Ada sources current and
34 issue the command:
35
36 gnatmake test -largs -L<directory where libz.a is> -lz
37
38 Or use the GNAT project file build for GNAT 3.15 or later:
39
40 gnatmake -Pzlib.gpr -L<directory where libz.a is>
41
42
43 How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
44
45 1. Make a project with all *.ads and *.adb files from the distribution.
46 2. Build the libz.a library from the ZLib C sources.
47 3. Rename libz.a to z.lib.
48 4. Add the library z.lib to the project.
49 5. Add the libc.lib library from the ObjectAda distribution to the project.
50 6. Build the executable using test.adb as a main procedure.
51
52
53 How to use ZLib.Ada
54
55 The source files test.adb and read.adb are small demo programs that show
56 the main functionality of ZLib.Ada.
57
58 The routines from the package specifications are commented.
59
60
61 Homepage: http://zlib-ada.sourceforge.net/
62 Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
63
64 Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
9
10 -- The program has a few aims.
11 -- 1. Test ZLib.Ada95 thick binding functionality.
12 -- 2. Show the example of use main functionality of the ZLib.Ada95 binding.
13 -- 3. Build this program automatically compile all ZLib.Ada95 packages under
14 -- GNAT Ada95 compiler.
15
16 with ZLib.Streams;
17 with Ada.Streams.Stream_IO;
18 with Ada.Numerics.Discrete_Random;
19
20 with Ada.Text_IO;
21
22 with Ada.Calendar;
23
24 procedure Test is
25
26 use Ada.Streams;
27 use Stream_IO;
28
29 ------------------------------------
30 -- Test configuration parameters --
31 ------------------------------------
32
33 File_Size : Count := 100_000;
34 Continuous : constant Boolean := False;
35
36 Header : constant ZLib.Header_Type := ZLib.Default;
37 -- ZLib.None;
38 -- ZLib.Auto;
39 -- ZLib.GZip;
40 -- Do not use Header other then Default in ZLib versions 1.1.4
41 -- and older.
42
43 Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
44 Init_Random : constant := 10;
45
46 -- End --
47
48 In_File_Name : constant String := "testzlib.in";
49 -- Name of the input file
50
51 Z_File_Name : constant String := "testzlib.zlb";
52 -- Name of the compressed file.
53
54 Out_File_Name : constant String := "testzlib.out";
55 -- Name of the decompressed file.
56
57 File_In : File_Type;
58 File_Out : File_Type;
59 File_Back : File_Type;
60 File_Z : ZLib.Streams.Stream_Type;
61
62 Filter : ZLib.Filter_Type;
63
64 Time_Stamp : Ada.Calendar.Time;
65
66 procedure Generate_File;
67 -- Generate file of spetsified size with some random data.
68 -- The random data is repeatable, for the good compression.
69
70 procedure Compare_Streams
71 (Left, Right : in out Root_Stream_Type'Class);
72 -- The procedure compearing data in 2 streams.
73 -- It is for compare data before and after compression/decompression.
74
75 procedure Compare_Files (Left, Right : String);
76 -- Compare files. Based on the Compare_Streams.
77
78 procedure Copy_Streams
79 (Source, Target : in out Root_Stream_Type'Class;
80 Buffer_Size : in Stream_Element_Offset := 1024);
81 -- Copying data from one stream to another. It is for test stream
82 -- interface of the library.
83
84 procedure Data_In
85 (Item : out Stream_Element_Array;
86 Last : out Stream_Element_Offset);
87 -- this procedure is for generic instantiation of
88 -- ZLib.Generic_Translate.
89 -- reading data from the File_In.
90
91 procedure Data_Out (Item : in Stream_Element_Array);
92 -- this procedure is for generic instantiation of
93 -- ZLib.Generic_Translate.
94 -- writing data to the File_Out.
95
96 procedure Stamp;
97 -- Store the timestamp to the local variable.
98
99 procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
100 -- Print the time statistic with the message.
101
102 procedure Translate is new ZLib.Generic_Translate
103 (Data_In => Data_In,
104 Data_Out => Data_Out);
105 -- This procedure is moving data from File_In to File_Out
106 -- with compression or decompression, depend on initialization of
107 -- Filter parameter.
108
109 -------------------
110 -- Compare_Files --
111 -------------------
112
113 procedure Compare_Files (Left, Right : String) is
114 Left_File, Right_File : File_Type;
115 begin
116 Open (Left_File, In_File, Left);
117 Open (Right_File, In_File, Right);
118 Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
119 Close (Left_File);
120 Close (Right_File);
121 end Compare_Files;
122
123 ---------------------
124 -- Compare_Streams --
125 ---------------------
126
127 procedure Compare_Streams
128 (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
129 is
130 Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
131 Left_Last, Right_Last : Stream_Element_Offset;
132 begin
133 loop
134 Read (Left, Left_Buffer, Left_Last);
135 Read (Right, Right_Buffer, Right_Last);
136
137 if Left_Last /= Right_Last then
138 Ada.Text_IO.Put_Line ("Compare error :"
139 & Stream_Element_Offset'Image (Left_Last)
140 & " /= "
141 & Stream_Element_Offset'Image (Right_Last));
142
143 raise Constraint_Error;
144
145 elsif Left_Buffer (0 .. Left_Last)
146 /= Right_Buffer (0 .. Right_Last)
147 then
148 Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
149 raise Constraint_Error;
150
151 end if;
152
153 exit when Left_Last < Left_Buffer'Last;
154 end loop;
155 end Compare_Streams;
156
157 ------------------
158 -- Copy_Streams --
159 ------------------
160
161 procedure Copy_Streams
162 (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
163 Buffer_Size : in Stream_Element_Offset := 1024)
164 is
165 Buffer : Stream_Element_Array (1 .. Buffer_Size);
166 Last : Stream_Element_Offset;
167 begin
168 loop
169 Read (Source, Buffer, Last);
170 Write (Target, Buffer (1 .. Last));
171
172 exit when Last < Buffer'Last;
173 end loop;
174 end Copy_Streams;
175
176 -------------
177 -- Data_In --
178 -------------
179
180 procedure Data_In
181 (Item : out Stream_Element_Array;
182 Last : out Stream_Element_Offset) is
183 begin
184 Read (File_In, Item, Last);
185 end Data_In;
186
187 --------------
188 -- Data_Out --
189 --------------
190
191 procedure Data_Out (Item : in Stream_Element_Array) is
192 begin
193 Write (File_Out, Item);
194 end Data_Out;
195
196 -------------------
197 -- Generate_File --
198 -------------------
199
200 procedure Generate_File is
201 subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
202
203 package Random_Elements is
204 new Ada.Numerics.Discrete_Random (Visible_Symbols);
205
206 Gen : Random_Elements.Generator;
207 Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
208
209 Buffer_Count : constant Count := File_Size / Buffer'Length;
210 -- Number of same buffers in the packet.
211
212 Density : constant Count := 30; -- from 0 to Buffer'Length - 2;
213
214 procedure Fill_Buffer (J, D : in Count);
215 -- Change the part of the buffer.
216
217 -----------------
218 -- Fill_Buffer --
219 -----------------
220
221 procedure Fill_Buffer (J, D : in Count) is
222 begin
223 for K in 0 .. D loop
224 Buffer
225 (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
226 := Random_Elements.Random (Gen);
227
228 end loop;
229 end Fill_Buffer;
230
231 begin
232 Random_Elements.Reset (Gen, Init_Random);
233
234 Create (File_In, Out_File, In_File_Name);
235
236 Fill_Buffer (1, Buffer'Length - 2);
237
238 for J in 1 .. Buffer_Count loop
239 Write (File_In, Buffer);
240
241 Fill_Buffer (J, Density);
242 end loop;
243
244 -- fill remain size.
245
246 Write
247 (File_In,
248 Buffer
249 (1 .. Stream_Element_Offset
250 (File_Size - Buffer'Length * Buffer_Count)));
251
252 Flush (File_In);
253 Close (File_In);
254 end Generate_File;
255
256 ---------------------
257 -- Print_Statistic --
258 ---------------------
259
260 procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
261 use Ada.Calendar;
262 use Ada.Text_IO;
263
264 package Count_IO is new Integer_IO (ZLib.Count);
265
266 Curr_Dur : Duration := Clock - Time_Stamp;
267 begin
268 Put (Msg);
269
270 Set_Col (20);
271 Ada.Text_IO.Put ("size =");
272
273 Count_IO.Put
274 (Data_Size,
275 Width => Stream_IO.Count'Image (File_Size)'Length);
276
277 Put_Line (" duration =" & Duration'Image (Curr_Dur));
278 end Print_Statistic;
279
280 -----------
281 -- Stamp --
282 -----------
283
284 procedure Stamp is
285 begin
286 Time_Stamp := Ada.Calendar.Clock;
287 end Stamp;
288
289 begin
290 Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
291
292 loop
293 Generate_File;
294
295 for Level in ZLib.Compression_Level'Range loop
296
297 Ada.Text_IO.Put_Line ("Level ="
298 & ZLib.Compression_Level'Image (Level));
299
300 -- Test generic interface.
301 Open (File_In, In_File, In_File_Name);
302 Create (File_Out, Out_File, Z_File_Name);
303
304 Stamp;
305
306 -- Deflate using generic instantiation.
307
308 ZLib.Deflate_Init
309 (Filter => Filter,
310 Level => Level,
311 Strategy => Strategy,
312 Header => Header);
313
314 Translate (Filter);
315 Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
316 ZLib.Close (Filter);
317
318 Close (File_In);
319 Close (File_Out);
320
321 Open (File_In, In_File, Z_File_Name);
322 Create (File_Out, Out_File, Out_File_Name);
323
324 Stamp;
325
326 -- Inflate using generic instantiation.
327
328 ZLib.Inflate_Init (Filter, Header => Header);
329
330 Translate (Filter);
331 Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
332
333 ZLib.Close (Filter);
334
335 Close (File_In);
336 Close (File_Out);
337
338 Compare_Files (In_File_Name, Out_File_Name);
339
340 -- Test stream interface.
341
342 -- Compress to the back stream.
343
344 Open (File_In, In_File, In_File_Name);
345 Create (File_Back, Out_File, Z_File_Name);
346
347 Stamp;
348
349 ZLib.Streams.Create
350 (Stream => File_Z,
351 Mode => ZLib.Streams.Out_Stream,
352 Back => ZLib.Streams.Stream_Access
353 (Stream (File_Back)),
354 Back_Compressed => True,
355 Level => Level,
356 Strategy => Strategy,
357 Header => Header);
358
359 Copy_Streams
360 (Source => Stream (File_In).all,
361 Target => File_Z);
362
363 -- Flushing internal buffers to the back stream.
364
365 ZLib.Streams.Flush (File_Z, ZLib.Finish);
366
367 Print_Statistic ("Write compress",
368 ZLib.Streams.Write_Total_Out (File_Z));
369
370 ZLib.Streams.Close (File_Z);
371
372 Close (File_In);
373 Close (File_Back);
374
375 -- Compare reading from original file and from
376 -- decompression stream.
377
378 Open (File_In, In_File, In_File_Name);
379 Open (File_Back, In_File, Z_File_Name);
380
381 ZLib.Streams.Create
382 (Stream => File_Z,
383 Mode => ZLib.Streams.In_Stream,
384 Back => ZLib.Streams.Stream_Access
385 (Stream (File_Back)),
386 Back_Compressed => True,
387 Header => Header);
388
389 Stamp;
390 Compare_Streams (Stream (File_In).all, File_Z);
391
392 Print_Statistic ("Read decompress",
393 ZLib.Streams.Read_Total_Out (File_Z));
394
395 ZLib.Streams.Close (File_Z);
396 Close (File_In);
397 Close (File_Back);
398
399 -- Compress by reading from compression stream.
400
401 Open (File_Back, In_File, In_File_Name);
402 Create (File_Out, Out_File, Z_File_Name);
403
404 ZLib.Streams.Create
405 (Stream => File_Z,
406 Mode => ZLib.Streams.In_Stream,
407 Back => ZLib.Streams.Stream_Access
408 (Stream (File_Back)),
409 Back_Compressed => False,
410 Level => Level,
411 Strategy => Strategy,
412 Header => Header);
413
414 Stamp;
415 Copy_Streams
416 (Source => File_Z,
417 Target => Stream (File_Out).all);
418
419 Print_Statistic ("Read compress",
420 ZLib.Streams.Read_Total_Out (File_Z));
421
422 ZLib.Streams.Close (File_Z);
423
424 Close (File_Out);
425 Close (File_Back);
426
427 -- Decompress to decompression stream.
428
429 Open (File_In, In_File, Z_File_Name);
430 Create (File_Back, Out_File, Out_File_Name);
431
432 ZLib.Streams.Create
433 (Stream => File_Z,
434 Mode => ZLib.Streams.Out_Stream,
435 Back => ZLib.Streams.Stream_Access
436 (Stream (File_Back)),
437 Back_Compressed => False,
438 Header => Header);
439
440 Stamp;
441
442 Copy_Streams
443 (Source => Stream (File_In).all,
444 Target => File_Z);
445
446 Print_Statistic ("Write decompress",
447 ZLib.Streams.Write_Total_Out (File_Z));
448
449 ZLib.Streams.Close (File_Z);
450 Close (File_In);
451 Close (File_Back);
452
453 Compare_Files (In_File_Name, Out_File_Name);
454 end loop;
455
456 Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
457
458 exit when not Continuous;
459
460 File_Size := File_Size + 1;
461 end loop;
462 end Test;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
9
10 with Ada.Unchecked_Deallocation;
11
12 package body ZLib.Streams is
13
14 -----------
15 -- Close --
16 -----------
17
18 procedure Close (Stream : in out Stream_Type) is
19 procedure Free is new Ada.Unchecked_Deallocation
20 (Stream_Element_Array, Buffer_Access);
21 begin
22 if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
23 -- We should flush the data written by the writer.
24
25 Flush (Stream, Finish);
26
27 Close (Stream.Writer);
28 end if;
29
30 if Stream.Mode = In_Stream or Stream.Mode = Duplex then
31 Close (Stream.Reader);
32 Free (Stream.Buffer);
33 end if;
34 end Close;
35
36 ------------
37 -- Create --
38 ------------
39
40 procedure Create
41 (Stream : out Stream_Type;
42 Mode : in Stream_Mode;
43 Back : in Stream_Access;
44 Back_Compressed : in Boolean;
45 Level : in Compression_Level := Default_Compression;
46 Strategy : in Strategy_Type := Default_Strategy;
47 Header : in Header_Type := Default;
48 Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
49 := Default_Buffer_Size;
50 Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
51 := Default_Buffer_Size)
52 is
53
54 subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
55
56 procedure Init_Filter
57 (Filter : in out Filter_Type;
58 Compress : in Boolean);
59
60 -----------------
61 -- Init_Filter --
62 -----------------
63
64 procedure Init_Filter
65 (Filter : in out Filter_Type;
66 Compress : in Boolean) is
67 begin
68 if Compress then
69 Deflate_Init
70 (Filter, Level, Strategy, Header => Header);
71 else
72 Inflate_Init (Filter, Header => Header);
73 end if;
74 end Init_Filter;
75
76 begin
77 Stream.Back := Back;
78 Stream.Mode := Mode;
79
80 if Mode = Out_Stream or Mode = Duplex then
81 Init_Filter (Stream.Writer, Back_Compressed);
82 Stream.Buffer_Size := Write_Buffer_Size;
83 else
84 Stream.Buffer_Size := 0;
85 end if;
86
87 if Mode = In_Stream or Mode = Duplex then
88 Init_Filter (Stream.Reader, not Back_Compressed);
89
90 Stream.Buffer := new Buffer_Subtype;
91 Stream.Rest_First := Stream.Buffer'Last + 1;
92 Stream.Rest_Last := Stream.Buffer'Last;
93 end if;
94 end Create;
95
96 -----------
97 -- Flush --
98 -----------
99
100 procedure Flush
101 (Stream : in out Stream_Type;
102 Mode : in Flush_Mode := Sync_Flush)
103 is
104 Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
105 Last : Stream_Element_Offset;
106 begin
107 loop
108 Flush (Stream.Writer, Buffer, Last, Mode);
109
110 Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
111
112 exit when Last < Buffer'Last;
113 end loop;
114 end Flush;
115
116 -------------
117 -- Is_Open --
118 -------------
119
120 function Is_Open (Stream : Stream_Type) return Boolean is
121 begin
122 return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
123 end Is_Open;
124
125 ----------
126 -- Read --
127 ----------
128
129 procedure Read
130 (Stream : in out Stream_Type;
131 Item : out Stream_Element_Array;
132 Last : out Stream_Element_Offset)
133 is
134
135 procedure Read
136 (Item : out Stream_Element_Array;
137 Last : out Stream_Element_Offset);
138
139 ----------
140 -- Read --
141 ----------
142
143 procedure Read
144 (Item : out Stream_Element_Array;
145 Last : out Stream_Element_Offset) is
146 begin
147 Ada.Streams.Read (Stream.Back.all, Item, Last);
148 end Read;
149
150 procedure Read is new ZLib.Read
151 (Read => Read,
152 Buffer => Stream.Buffer.all,
153 Rest_First => Stream.Rest_First,
154 Rest_Last => Stream.Rest_Last);
155
156 begin
157 Read (Stream.Reader, Item, Last);
158 end Read;
159
160 -------------------
161 -- Read_Total_In --
162 -------------------
163
164 function Read_Total_In (Stream : in Stream_Type) return Count is
165 begin
166 return Total_In (Stream.Reader);
167 end Read_Total_In;
168
169 --------------------
170 -- Read_Total_Out --
171 --------------------
172
173 function Read_Total_Out (Stream : in Stream_Type) return Count is
174 begin
175 return Total_Out (Stream.Reader);
176 end Read_Total_Out;
177
178 -----------
179 -- Write --
180 -----------
181
182 procedure Write
183 (Stream : in out Stream_Type;
184 Item : in Stream_Element_Array)
185 is
186
187 procedure Write (Item : in Stream_Element_Array);
188
189 -----------
190 -- Write --
191 -----------
192
193 procedure Write (Item : in Stream_Element_Array) is
194 begin
195 Ada.Streams.Write (Stream.Back.all, Item);
196 end Write;
197
198 procedure Write is new ZLib.Write
199 (Write => Write,
200 Buffer_Size => Stream.Buffer_Size);
201
202 begin
203 Write (Stream.Writer, Item, No_Flush);
204 end Write;
205
206 --------------------
207 -- Write_Total_In --
208 --------------------
209
210 function Write_Total_In (Stream : in Stream_Type) return Count is
211 begin
212 return Total_In (Stream.Writer);
213 end Write_Total_In;
214
215 ---------------------
216 -- Write_Total_Out --
217 ---------------------
218
219 function Write_Total_Out (Stream : in Stream_Type) return Count is
220 begin
221 return Total_Out (Stream.Writer);
222 end Write_Total_Out;
223
224 end ZLib.Streams;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
9
10 package ZLib.Streams is
11
12 type Stream_Mode is (In_Stream, Out_Stream, Duplex);
13
14 type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
15
16 type Stream_Type is
17 new Ada.Streams.Root_Stream_Type with private;
18
19 procedure Read
20 (Stream : in out Stream_Type;
21 Item : out Ada.Streams.Stream_Element_Array;
22 Last : out Ada.Streams.Stream_Element_Offset);
23
24 procedure Write
25 (Stream : in out Stream_Type;
26 Item : in Ada.Streams.Stream_Element_Array);
27
28 procedure Flush
29 (Stream : in out Stream_Type;
30 Mode : in Flush_Mode := Sync_Flush);
31 -- Flush the written data to the back stream,
32 -- all data placed to the compressor is flushing to the Back stream.
33 -- Should not be used untill necessary, becouse it is decreasing
34 -- compression.
35
36 function Read_Total_In (Stream : in Stream_Type) return Count;
37 pragma Inline (Read_Total_In);
38 -- Return total number of bytes read from back stream so far.
39
40 function Read_Total_Out (Stream : in Stream_Type) return Count;
41 pragma Inline (Read_Total_Out);
42 -- Return total number of bytes read so far.
43
44 function Write_Total_In (Stream : in Stream_Type) return Count;
45 pragma Inline (Write_Total_In);
46 -- Return total number of bytes written so far.
47
48 function Write_Total_Out (Stream : in Stream_Type) return Count;
49 pragma Inline (Write_Total_Out);
50 -- Return total number of bytes written to the back stream.
51
52 procedure Create
53 (Stream : out Stream_Type;
54 Mode : in Stream_Mode;
55 Back : in Stream_Access;
56 Back_Compressed : in Boolean;
57 Level : in Compression_Level := Default_Compression;
58 Strategy : in Strategy_Type := Default_Strategy;
59 Header : in Header_Type := Default;
60 Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
61 := Default_Buffer_Size;
62 Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
63 := Default_Buffer_Size);
64 -- Create the Comression/Decompression stream.
65 -- If mode is In_Stream then Write operation is disabled.
66 -- If mode is Out_Stream then Read operation is disabled.
67
68 -- If Back_Compressed is true then
69 -- Data written to the Stream is compressing to the Back stream
70 -- and data read from the Stream is decompressed data from the Back stream.
71
72 -- If Back_Compressed is false then
73 -- Data written to the Stream is decompressing to the Back stream
74 -- and data read from the Stream is compressed data from the Back stream.
75
76 -- !!! When the Need_Header is False ZLib-Ada is using undocumented
77 -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
78
79 function Is_Open (Stream : Stream_Type) return Boolean;
80
81 procedure Close (Stream : in out Stream_Type);
82
83 private
84
85 use Ada.Streams;
86
87 type Buffer_Access is access all Stream_Element_Array;
88
89 type Stream_Type
90 is new Root_Stream_Type with
91 record
92 Mode : Stream_Mode;
93
94 Buffer : Buffer_Access;
95 Rest_First : Stream_Element_Offset;
96 Rest_Last : Stream_Element_Offset;
97 -- Buffer for Read operation.
98 -- We need to have this buffer in the record
99 -- becouse not all read data from back stream
100 -- could be processed during the read operation.
101
102 Buffer_Size : Stream_Element_Offset;
103 -- Buffer size for write operation.
104 -- We do not need to have this buffer
105 -- in the record becouse all data could be
106 -- processed in the write operation.
107
108 Back : Stream_Access;
109 Reader : Filter_Type;
110 Writer : Filter_Type;
111 end record;
112
113 end ZLib.Streams;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
9
10 package body ZLib.Thin is
11
12 ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
13
14 Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
15
16 --------------
17 -- Avail_In --
18 --------------
19
20 function Avail_In (Strm : in Z_Stream) return UInt is
21 begin
22 return Strm.Avail_In;
23 end Avail_In;
24
25 ---------------
26 -- Avail_Out --
27 ---------------
28
29 function Avail_Out (Strm : in Z_Stream) return UInt is
30 begin
31 return Strm.Avail_Out;
32 end Avail_Out;
33
34 ------------------
35 -- Deflate_Init --
36 ------------------
37
38 function Deflate_Init
39 (strm : Z_Streamp;
40 level : Int;
41 method : Int;
42 windowBits : Int;
43 memLevel : Int;
44 strategy : Int)
45 return Int is
46 begin
47 return deflateInit2
48 (strm,
49 level,
50 method,
51 windowBits,
52 memLevel,
53 strategy,
54 ZLIB_VERSION,
55 Z_Stream_Size);
56 end Deflate_Init;
57
58 ------------------
59 -- Inflate_Init --
60 ------------------
61
62 function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
63 begin
64 return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
65 end Inflate_Init;
66
67 ------------------------
68 -- Last_Error_Message --
69 ------------------------
70
71 function Last_Error_Message (Strm : in Z_Stream) return String is
72 use Interfaces.C.Strings;
73 begin
74 if Strm.msg = Null_Ptr then
75 return "";
76 else
77 return Value (Strm.msg);
78 end if;
79 end Last_Error_Message;
80
81 ------------
82 -- Set_In --
83 ------------
84
85 procedure Set_In
86 (Strm : in out Z_Stream;
87 Buffer : in Voidp;
88 Size : in UInt) is
89 begin
90 Strm.Next_In := Buffer;
91 Strm.Avail_In := Size;
92 end Set_In;
93
94 ------------------
95 -- Set_Mem_Func --
96 ------------------
97
98 procedure Set_Mem_Func
99 (Strm : in out Z_Stream;
100 Opaque : in Voidp;
101 Alloc : in alloc_func;
102 Free : in free_func) is
103 begin
104 Strm.opaque := Opaque;
105 Strm.zalloc := Alloc;
106 Strm.zfree := Free;
107 end Set_Mem_Func;
108
109 -------------
110 -- Set_Out --
111 -------------
112
113 procedure Set_Out
114 (Strm : in out Z_Stream;
115 Buffer : in Voidp;
116 Size : in UInt) is
117 begin
118 Strm.Next_Out := Buffer;
119 Strm.Avail_Out := Size;
120 end Set_Out;
121
122 --------------
123 -- Total_In --
124 --------------
125
126 function Total_In (Strm : in Z_Stream) return ULong is
127 begin
128 return Strm.Total_In;
129 end Total_In;
130
131 ---------------
132 -- Total_Out --
133 ---------------
134
135 function Total_Out (Strm : in Z_Stream) return ULong is
136 begin
137 return Strm.Total_Out;
138 end Total_Out;
139
140 end ZLib.Thin;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2003 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
9
10 with Interfaces.C.Strings;
11
12 with System;
13
14 private package ZLib.Thin is
15
16 -- From zconf.h
17
18 MAX_MEM_LEVEL : constant := 9; -- zconf.h:105
19 -- zconf.h:105
20 MAX_WBITS : constant := 15; -- zconf.h:115
21 -- 32K LZ77 window
22 -- zconf.h:115
23 SEEK_SET : constant := 8#0000#; -- zconf.h:244
24 -- Seek from beginning of file.
25 -- zconf.h:244
26 SEEK_CUR : constant := 1; -- zconf.h:245
27 -- Seek from current position.
28 -- zconf.h:245
29 SEEK_END : constant := 2; -- zconf.h:246
30 -- Set file pointer to EOF plus "offset"
31 -- zconf.h:246
32
33 type Byte is new Interfaces.C.unsigned_char; -- 8 bits
34 -- zconf.h:214
35 type UInt is new Interfaces.C.unsigned; -- 16 bits or more
36 -- zconf.h:216
37 type Int is new Interfaces.C.int;
38
39 type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
40 -- zconf.h:217
41 subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
42
43 type ULong_Access is access ULong;
44 type Int_Access is access Int;
45
46 subtype Voidp is System.Address; -- zconf.h:232
47
48 subtype Byte_Access is Voidp;
49
50 Nul : constant Voidp := System.Null_Address;
51 -- end from zconf
52
53 Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
54 -- zlib.h:125
55 Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126
56 -- will be removed, use
57 -- Z_SYNC_FLUSH instead
58 -- zlib.h:126
59 Z_SYNC_FLUSH : constant := 2; -- zlib.h:127
60 -- zlib.h:127
61 Z_FULL_FLUSH : constant := 3; -- zlib.h:128
62 -- zlib.h:128
63 Z_FINISH : constant := 4; -- zlib.h:129
64 -- zlib.h:129
65 Z_OK : constant := 8#0000#; -- zlib.h:132
66 -- zlib.h:132
67 Z_STREAM_END : constant := 1; -- zlib.h:133
68 -- zlib.h:133
69 Z_NEED_DICT : constant := 2; -- zlib.h:134
70 -- zlib.h:134
71 Z_ERRNO : constant := -1; -- zlib.h:135
72 -- zlib.h:135
73 Z_STREAM_ERROR : constant := -2; -- zlib.h:136
74 -- zlib.h:136
75 Z_DATA_ERROR : constant := -3; -- zlib.h:137
76 -- zlib.h:137
77 Z_MEM_ERROR : constant := -4; -- zlib.h:138
78 -- zlib.h:138
79 Z_BUF_ERROR : constant := -5; -- zlib.h:139
80 -- zlib.h:139
81 Z_VERSION_ERROR : constant := -6; -- zlib.h:140
82 -- zlib.h:140
83 Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145
84 -- zlib.h:145
85 Z_BEST_SPEED : constant := 1; -- zlib.h:146
86 -- zlib.h:146
87 Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147
88 -- zlib.h:147
89 Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148
90 -- zlib.h:148
91 Z_FILTERED : constant := 1; -- zlib.h:151
92 -- zlib.h:151
93 Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152
94 -- zlib.h:152
95 Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153
96 -- zlib.h:153
97 Z_BINARY : constant := 8#0000#; -- zlib.h:156
98 -- zlib.h:156
99 Z_ASCII : constant := 1; -- zlib.h:157
100 -- zlib.h:157
101 Z_UNKNOWN : constant := 2; -- zlib.h:158
102 -- zlib.h:158
103 Z_DEFLATED : constant := 8; -- zlib.h:161
104 -- zlib.h:161
105 Z_NULL : constant := 8#0000#; -- zlib.h:164
106 -- for initializing zalloc, zfree, opaque
107 -- zlib.h:164
108 type gzFile is new Voidp; -- zlib.h:646
109
110 type Z_Stream is private;
111
112 type Z_Streamp is access all Z_Stream; -- zlib.h:89
113
114 type alloc_func is access function
115 (Opaque : Voidp;
116 Items : UInt;
117 Size : UInt)
118 return Voidp; -- zlib.h:63
119
120 type free_func is access procedure (opaque : Voidp; address : Voidp);
121
122 function zlibVersion return Chars_Ptr;
123
124 function Deflate (strm : Z_Streamp; flush : Int) return Int;
125
126 function DeflateEnd (strm : Z_Streamp) return Int;
127
128 function Inflate (strm : Z_Streamp; flush : Int) return Int;
129
130 function InflateEnd (strm : Z_Streamp) return Int;
131
132 function deflateSetDictionary
133 (strm : Z_Streamp;
134 dictionary : Byte_Access;
135 dictLength : UInt)
136 return Int;
137
138 function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
139 -- zlib.h:478
140
141 function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
142
143 function deflateParams
144 (strm : Z_Streamp;
145 level : Int;
146 strategy : Int)
147 return Int; -- zlib.h:506
148
149 function inflateSetDictionary
150 (strm : Z_Streamp;
151 dictionary : Byte_Access;
152 dictLength : UInt)
153 return Int; -- zlib.h:548
154
155 function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565
156
157 function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580
158
159 function compress
160 (dest : Byte_Access;
161 destLen : ULong_Access;
162 source : Byte_Access;
163 sourceLen : ULong)
164 return Int; -- zlib.h:601
165
166 function compress2
167 (dest : Byte_Access;
168 destLen : ULong_Access;
169 source : Byte_Access;
170 sourceLen : ULong;
171 level : Int)
172 return Int; -- zlib.h:615
173
174 function uncompress
175 (dest : Byte_Access;
176 destLen : ULong_Access;
177 source : Byte_Access;
178 sourceLen : ULong)
179 return Int;
180
181 function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
182
183 function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
184
185 function gzsetparams
186 (file : gzFile;
187 level : Int;
188 strategy : Int)
189 return Int;
190
191 function gzread
192 (file : gzFile;
193 buf : Voidp;
194 len : UInt)
195 return Int;
196
197 function gzwrite
198 (file : in gzFile;
199 buf : in Voidp;
200 len : in UInt)
201 return Int;
202
203 function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
204
205 function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
206
207 function gzgets
208 (file : gzFile;
209 buf : Chars_Ptr;
210 len : Int)
211 return Chars_Ptr;
212
213 function gzputc (file : gzFile; char : Int) return Int;
214
215 function gzgetc (file : gzFile) return Int;
216
217 function gzflush (file : gzFile; flush : Int) return Int;
218
219 function gzseek
220 (file : gzFile;
221 offset : Int;
222 whence : Int)
223 return Int;
224
225 function gzrewind (file : gzFile) return Int;
226
227 function gztell (file : gzFile) return Int;
228
229 function gzeof (file : gzFile) return Int;
230
231 function gzclose (file : gzFile) return Int;
232
233 function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
234
235 function adler32
236 (adler : ULong;
237 buf : Byte_Access;
238 len : UInt)
239 return ULong;
240
241 function crc32
242 (crc : ULong;
243 buf : Byte_Access;
244 len : UInt)
245 return ULong;
246
247 function deflateInit
248 (strm : Z_Streamp;
249 level : Int;
250 version : Chars_Ptr;
251 stream_size : Int)
252 return Int;
253
254 function deflateInit2
255 (strm : Z_Streamp;
256 level : Int;
257 method : Int;
258 windowBits : Int;
259 memLevel : Int;
260 strategy : Int;
261 version : Chars_Ptr;
262 stream_size : Int)
263 return Int;
264
265 function Deflate_Init
266 (strm : Z_Streamp;
267 level : Int;
268 method : Int;
269 windowBits : Int;
270 memLevel : Int;
271 strategy : Int)
272 return Int;
273 pragma Inline (Deflate_Init);
274
275 function inflateInit
276 (strm : Z_Streamp;
277 version : Chars_Ptr;
278 stream_size : Int)
279 return Int;
280
281 function inflateInit2
282 (strm : in Z_Streamp;
283 windowBits : in Int;
284 version : in Chars_Ptr;
285 stream_size : in Int)
286 return Int;
287
288 function inflateBackInit
289 (strm : in Z_Streamp;
290 windowBits : in Int;
291 window : in Byte_Access;
292 version : in Chars_Ptr;
293 stream_size : in Int)
294 return Int;
295 -- Size of window have to be 2**windowBits.
296
297 function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
298 pragma Inline (Inflate_Init);
299
300 function zError (err : Int) return Chars_Ptr;
301
302 function inflateSyncPoint (z : Z_Streamp) return Int;
303
304 function get_crc_table return ULong_Access;
305
306 -- Interface to the available fields of the z_stream structure.
307 -- The application must update next_in and avail_in when avail_in has
308 -- dropped to zero. It must update next_out and avail_out when avail_out
309 -- has dropped to zero. The application must initialize zalloc, zfree and
310 -- opaque before calling the init function.
311
312 procedure Set_In
313 (Strm : in out Z_Stream;
314 Buffer : in Voidp;
315 Size : in UInt);
316 pragma Inline (Set_In);
317
318 procedure Set_Out
319 (Strm : in out Z_Stream;
320 Buffer : in Voidp;
321 Size : in UInt);
322 pragma Inline (Set_Out);
323
324 procedure Set_Mem_Func
325 (Strm : in out Z_Stream;
326 Opaque : in Voidp;
327 Alloc : in alloc_func;
328 Free : in free_func);
329 pragma Inline (Set_Mem_Func);
330
331 function Last_Error_Message (Strm : in Z_Stream) return String;
332 pragma Inline (Last_Error_Message);
333
334 function Avail_Out (Strm : in Z_Stream) return UInt;
335 pragma Inline (Avail_Out);
336
337 function Avail_In (Strm : in Z_Stream) return UInt;
338 pragma Inline (Avail_In);
339
340 function Total_In (Strm : in Z_Stream) return ULong;
341 pragma Inline (Total_In);
342
343 function Total_Out (Strm : in Z_Stream) return ULong;
344 pragma Inline (Total_Out);
345
346 function inflateCopy
347 (dest : in Z_Streamp;
348 Source : in Z_Streamp)
349 return Int;
350
351 function compressBound (Source_Len : in ULong) return ULong;
352
353 function deflateBound
354 (Strm : in Z_Streamp;
355 Source_Len : in ULong)
356 return ULong;
357
358 function gzungetc (C : in Int; File : in gzFile) return Int;
359
360 function zlibCompileFlags return ULong;
361
362 private
363
364 type Z_Stream is record -- zlib.h:68
365 Next_In : Voidp := Nul; -- next input byte
366 Avail_In : UInt := 0; -- number of bytes available at next_in
367 Total_In : ULong := 0; -- total nb of input bytes read so far
368 Next_Out : Voidp := Nul; -- next output byte should be put there
369 Avail_Out : UInt := 0; -- remaining free space at next_out
370 Total_Out : ULong := 0; -- total nb of bytes output so far
371 msg : Chars_Ptr; -- last error message, NULL if no error
372 state : Voidp; -- not visible by applications
373 zalloc : alloc_func := null; -- used to allocate the internal state
374 zfree : free_func := null; -- used to free the internal state
375 opaque : Voidp; -- private data object passed to
376 -- zalloc and zfree
377 data_type : Int; -- best guess about the data type:
378 -- ascii or binary
379 adler : ULong; -- adler32 value of the uncompressed
380 -- data
381 reserved : ULong; -- reserved for future use
382 end record;
383
384 pragma Convention (C, Z_Stream);
385
386 pragma Import (C, zlibVersion, "zlibVersion");
387 pragma Import (C, Deflate, "deflate");
388 pragma Import (C, DeflateEnd, "deflateEnd");
389 pragma Import (C, Inflate, "inflate");
390 pragma Import (C, InflateEnd, "inflateEnd");
391 pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
392 pragma Import (C, deflateCopy, "deflateCopy");
393 pragma Import (C, deflateReset, "deflateReset");
394 pragma Import (C, deflateParams, "deflateParams");
395 pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
396 pragma Import (C, inflateSync, "inflateSync");
397 pragma Import (C, inflateReset, "inflateReset");
398 pragma Import (C, compress, "compress");
399 pragma Import (C, compress2, "compress2");
400 pragma Import (C, uncompress, "uncompress");
401 pragma Import (C, gzopen, "gzopen");
402 pragma Import (C, gzdopen, "gzdopen");
403 pragma Import (C, gzsetparams, "gzsetparams");
404 pragma Import (C, gzread, "gzread");
405 pragma Import (C, gzwrite, "gzwrite");
406 pragma Import (C, gzprintf, "gzprintf");
407 pragma Import (C, gzputs, "gzputs");
408 pragma Import (C, gzgets, "gzgets");
409 pragma Import (C, gzputc, "gzputc");
410 pragma Import (C, gzgetc, "gzgetc");
411 pragma Import (C, gzflush, "gzflush");
412 pragma Import (C, gzseek, "gzseek");
413 pragma Import (C, gzrewind, "gzrewind");
414 pragma Import (C, gztell, "gztell");
415 pragma Import (C, gzeof, "gzeof");
416 pragma Import (C, gzclose, "gzclose");
417 pragma Import (C, gzerror, "gzerror");
418 pragma Import (C, adler32, "adler32");
419 pragma Import (C, crc32, "crc32");
420 pragma Import (C, deflateInit, "deflateInit_");
421 pragma Import (C, inflateInit, "inflateInit_");
422 pragma Import (C, deflateInit2, "deflateInit2_");
423 pragma Import (C, inflateInit2, "inflateInit2_");
424 pragma Import (C, zError, "zError");
425 pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
426 pragma Import (C, get_crc_table, "get_crc_table");
427
428 -- since zlib 1.2.0:
429
430 pragma Import (C, inflateCopy, "inflateCopy");
431 pragma Import (C, compressBound, "compressBound");
432 pragma Import (C, deflateBound, "deflateBound");
433 pragma Import (C, gzungetc, "gzungetc");
434 pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
435
436 pragma Import (C, inflateBackInit, "inflateBackInit_");
437
438 -- I stopped binding the inflateBack routines, becouse realize that
439 -- it does not support zlib and gzip headers for now, and have no
440 -- symmetric deflateBack routines.
441 -- ZLib-Ada is symmetric regarding deflate/inflate data transformation
442 -- and has a similar generic callback interface for the
443 -- deflate/inflate transformation based on the regular Deflate/Inflate
444 -- routines.
445
446 -- pragma Import (C, inflateBack, "inflateBack");
447 -- pragma Import (C, inflateBackEnd, "inflateBackEnd");
448
449 end ZLib.Thin;
0 ----------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
4 -- --
5 -- Open source license information is in the zlib.ads file. --
6 ----------------------------------------------------------------
7
8 -- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
9
10 with Ada.Exceptions;
11 with Ada.Unchecked_Conversion;
12 with Ada.Unchecked_Deallocation;
13
14 with Interfaces.C.Strings;
15
16 with ZLib.Thin;
17
18 package body ZLib is
19
20 use type Thin.Int;
21
22 type Z_Stream is new Thin.Z_Stream;
23
24 type Return_Code_Enum is
25 (OK,
26 STREAM_END,
27 NEED_DICT,
28 ERRNO,
29 STREAM_ERROR,
30 DATA_ERROR,
31 MEM_ERROR,
32 BUF_ERROR,
33 VERSION_ERROR);
34
35 type Flate_Step_Function is access
36 function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
37 pragma Convention (C, Flate_Step_Function);
38
39 type Flate_End_Function is access
40 function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
41 pragma Convention (C, Flate_End_Function);
42
43 type Flate_Type is record
44 Step : Flate_Step_Function;
45 Done : Flate_End_Function;
46 end record;
47
48 subtype Footer_Array is Stream_Element_Array (1 .. 8);
49
50 Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
51 := (16#1f#, 16#8b#, -- Magic header
52 16#08#, -- Z_DEFLATED
53 16#00#, -- Flags
54 16#00#, 16#00#, 16#00#, 16#00#, -- Time
55 16#00#, -- XFlags
56 16#03# -- OS code
57 );
58 -- The simplest gzip header is not for informational, but just for
59 -- gzip format compatibility.
60 -- Note that some code below is using assumption
61 -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make
62 -- Simple_GZip_Header'Last <= Footer_Array'Last.
63
64 Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
65 := (0 => OK,
66 1 => STREAM_END,
67 2 => NEED_DICT,
68 -1 => ERRNO,
69 -2 => STREAM_ERROR,
70 -3 => DATA_ERROR,
71 -4 => MEM_ERROR,
72 -5 => BUF_ERROR,
73 -6 => VERSION_ERROR);
74
75 Flate : constant array (Boolean) of Flate_Type
76 := (True => (Step => Thin.Deflate'Access,
77 Done => Thin.DeflateEnd'Access),
78 False => (Step => Thin.Inflate'Access,
79 Done => Thin.InflateEnd'Access));
80
81 Flush_Finish : constant array (Boolean) of Flush_Mode
82 := (True => Finish, False => No_Flush);
83
84 procedure Raise_Error (Stream : in Z_Stream);
85 pragma Inline (Raise_Error);
86
87 procedure Raise_Error (Message : in String);
88 pragma Inline (Raise_Error);
89
90 procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
91
92 procedure Free is new Ada.Unchecked_Deallocation
93 (Z_Stream, Z_Stream_Access);
94
95 function To_Thin_Access is new Ada.Unchecked_Conversion
96 (Z_Stream_Access, Thin.Z_Streamp);
97
98 procedure Translate_GZip
99 (Filter : in out Filter_Type;
100 In_Data : in Ada.Streams.Stream_Element_Array;
101 In_Last : out Ada.Streams.Stream_Element_Offset;
102 Out_Data : out Ada.Streams.Stream_Element_Array;
103 Out_Last : out Ada.Streams.Stream_Element_Offset;
104 Flush : in Flush_Mode);
105 -- Separate translate routine for make gzip header.
106
107 procedure Translate_Auto
108 (Filter : in out Filter_Type;
109 In_Data : in Ada.Streams.Stream_Element_Array;
110 In_Last : out Ada.Streams.Stream_Element_Offset;
111 Out_Data : out Ada.Streams.Stream_Element_Array;
112 Out_Last : out Ada.Streams.Stream_Element_Offset;
113 Flush : in Flush_Mode);
114 -- translate routine without additional headers.
115
116 -----------------
117 -- Check_Error --
118 -----------------
119
120 procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
121 use type Thin.Int;
122 begin
123 if Code /= Thin.Z_OK then
124 Raise_Error
125 (Return_Code_Enum'Image (Return_Code (Code))
126 & ": " & Last_Error_Message (Stream));
127 end if;
128 end Check_Error;
129
130 -----------
131 -- Close --
132 -----------
133
134 procedure Close
135 (Filter : in out Filter_Type;
136 Ignore_Error : in Boolean := False)
137 is
138 Code : Thin.Int;
139 begin
140 if not Ignore_Error and then not Is_Open (Filter) then
141 raise Status_Error;
142 end if;
143
144 Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
145
146 if Ignore_Error or else Code = Thin.Z_OK then
147 Free (Filter.Strm);
148 else
149 declare
150 Error_Message : constant String
151 := Last_Error_Message (Filter.Strm.all);
152 begin
153 Free (Filter.Strm);
154 Ada.Exceptions.Raise_Exception
155 (ZLib_Error'Identity,
156 Return_Code_Enum'Image (Return_Code (Code))
157 & ": " & Error_Message);
158 end;
159 end if;
160 end Close;
161
162 -----------
163 -- CRC32 --
164 -----------
165
166 function CRC32
167 (CRC : in Unsigned_32;
168 Data : in Ada.Streams.Stream_Element_Array)
169 return Unsigned_32
170 is
171 use Thin;
172 begin
173 return Unsigned_32 (crc32 (ULong (CRC),
174 Data'Address,
175 Data'Length));
176 end CRC32;
177
178 procedure CRC32
179 (CRC : in out Unsigned_32;
180 Data : in Ada.Streams.Stream_Element_Array) is
181 begin
182 CRC := CRC32 (CRC, Data);
183 end CRC32;
184
185 ------------------
186 -- Deflate_Init --
187 ------------------
188
189 procedure Deflate_Init
190 (Filter : in out Filter_Type;
191 Level : in Compression_Level := Default_Compression;
192 Strategy : in Strategy_Type := Default_Strategy;
193 Method : in Compression_Method := Deflated;
194 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
195 Memory_Level : in Memory_Level_Type := Default_Memory_Level;
196 Header : in Header_Type := Default)
197 is
198 use type Thin.Int;
199 Win_Bits : Thin.Int := Thin.Int (Window_Bits);
200 begin
201 if Is_Open (Filter) then
202 raise Status_Error;
203 end if;
204
205 -- We allow ZLib to make header only in case of default header type.
206 -- Otherwise we would either do header by ourselfs, or do not do
207 -- header at all.
208
209 if Header = None or else Header = GZip then
210 Win_Bits := -Win_Bits;
211 end if;
212
213 -- For the GZip CRC calculation and make headers.
214
215 if Header = GZip then
216 Filter.CRC := 0;
217 Filter.Offset := Simple_GZip_Header'First;
218 else
219 Filter.Offset := Simple_GZip_Header'Last + 1;
220 end if;
221
222 Filter.Strm := new Z_Stream;
223 Filter.Compression := True;
224 Filter.Stream_End := False;
225 Filter.Header := Header;
226
227 if Thin.Deflate_Init
228 (To_Thin_Access (Filter.Strm),
229 Level => Thin.Int (Level),
230 method => Thin.Int (Method),
231 windowBits => Win_Bits,
232 memLevel => Thin.Int (Memory_Level),
233 strategy => Thin.Int (Strategy)) /= Thin.Z_OK
234 then
235 Raise_Error (Filter.Strm.all);
236 end if;
237 end Deflate_Init;
238
239 -----------
240 -- Flush --
241 -----------
242
243 procedure Flush
244 (Filter : in out Filter_Type;
245 Out_Data : out Ada.Streams.Stream_Element_Array;
246 Out_Last : out Ada.Streams.Stream_Element_Offset;
247 Flush : in Flush_Mode)
248 is
249 No_Data : Stream_Element_Array := (1 .. 0 => 0);
250 Last : Stream_Element_Offset;
251 begin
252 Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
253 end Flush;
254
255 -----------------------
256 -- Generic_Translate --
257 -----------------------
258
259 procedure Generic_Translate
260 (Filter : in out ZLib.Filter_Type;
261 In_Buffer_Size : in Integer := Default_Buffer_Size;
262 Out_Buffer_Size : in Integer := Default_Buffer_Size)
263 is
264 In_Buffer : Stream_Element_Array
265 (1 .. Stream_Element_Offset (In_Buffer_Size));
266 Out_Buffer : Stream_Element_Array
267 (1 .. Stream_Element_Offset (Out_Buffer_Size));
268 Last : Stream_Element_Offset;
269 In_Last : Stream_Element_Offset;
270 In_First : Stream_Element_Offset;
271 Out_Last : Stream_Element_Offset;
272 begin
273 Main : loop
274 Data_In (In_Buffer, Last);
275
276 In_First := In_Buffer'First;
277
278 loop
279 Translate
280 (Filter => Filter,
281 In_Data => In_Buffer (In_First .. Last),
282 In_Last => In_Last,
283 Out_Data => Out_Buffer,
284 Out_Last => Out_Last,
285 Flush => Flush_Finish (Last < In_Buffer'First));
286
287 if Out_Buffer'First <= Out_Last then
288 Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
289 end if;
290
291 exit Main when Stream_End (Filter);
292
293 -- The end of in buffer.
294
295 exit when In_Last = Last;
296
297 In_First := In_Last + 1;
298 end loop;
299 end loop Main;
300
301 end Generic_Translate;
302
303 ------------------
304 -- Inflate_Init --
305 ------------------
306
307 procedure Inflate_Init
308 (Filter : in out Filter_Type;
309 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
310 Header : in Header_Type := Default)
311 is
312 use type Thin.Int;
313 Win_Bits : Thin.Int := Thin.Int (Window_Bits);
314
315 procedure Check_Version;
316 -- Check the latest header types compatibility.
317
318 procedure Check_Version is
319 begin
320 if Version <= "1.1.4" then
321 Raise_Error
322 ("Inflate header type " & Header_Type'Image (Header)
323 & " incompatible with ZLib version " & Version);
324 end if;
325 end Check_Version;
326
327 begin
328 if Is_Open (Filter) then
329 raise Status_Error;
330 end if;
331
332 case Header is
333 when None =>
334 Check_Version;
335
336 -- Inflate data without headers determined
337 -- by negative Win_Bits.
338
339 Win_Bits := -Win_Bits;
340 when GZip =>
341 Check_Version;
342
343 -- Inflate gzip data defined by flag 16.
344
345 Win_Bits := Win_Bits + 16;
346 when Auto =>
347 Check_Version;
348
349 -- Inflate with automatic detection
350 -- of gzip or native header defined by flag 32.
351
352 Win_Bits := Win_Bits + 32;
353 when Default => null;
354 end case;
355
356 Filter.Strm := new Z_Stream;
357 Filter.Compression := False;
358 Filter.Stream_End := False;
359 Filter.Header := Header;
360
361 if Thin.Inflate_Init
362 (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
363 then
364 Raise_Error (Filter.Strm.all);
365 end if;
366 end Inflate_Init;
367
368 -------------
369 -- Is_Open --
370 -------------
371
372 function Is_Open (Filter : in Filter_Type) return Boolean is
373 begin
374 return Filter.Strm /= null;
375 end Is_Open;
376
377 -----------------
378 -- Raise_Error --
379 -----------------
380
381 procedure Raise_Error (Message : in String) is
382 begin
383 Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
384 end Raise_Error;
385
386 procedure Raise_Error (Stream : in Z_Stream) is
387 begin
388 Raise_Error (Last_Error_Message (Stream));
389 end Raise_Error;
390
391 ----------
392 -- Read --
393 ----------
394
395 procedure Read
396 (Filter : in out Filter_Type;
397 Item : out Ada.Streams.Stream_Element_Array;
398 Last : out Ada.Streams.Stream_Element_Offset;
399 Flush : in Flush_Mode := No_Flush)
400 is
401 In_Last : Stream_Element_Offset;
402 Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
403 V_Flush : Flush_Mode := Flush;
404
405 begin
406 pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
407 pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
408
409 loop
410 if Rest_Last = Buffer'First - 1 then
411 V_Flush := Finish;
412
413 elsif Rest_First > Rest_Last then
414 Read (Buffer, Rest_Last);
415 Rest_First := Buffer'First;
416
417 if Rest_Last < Buffer'First then
418 V_Flush := Finish;
419 end if;
420 end if;
421
422 Translate
423 (Filter => Filter,
424 In_Data => Buffer (Rest_First .. Rest_Last),
425 In_Last => In_Last,
426 Out_Data => Item (Item_First .. Item'Last),
427 Out_Last => Last,
428 Flush => V_Flush);
429
430 Rest_First := In_Last + 1;
431
432 exit when Stream_End (Filter)
433 or else Last = Item'Last
434 or else (Last >= Item'First and then Allow_Read_Some);
435
436 Item_First := Last + 1;
437 end loop;
438 end Read;
439
440 ----------------
441 -- Stream_End --
442 ----------------
443
444 function Stream_End (Filter : in Filter_Type) return Boolean is
445 begin
446 if Filter.Header = GZip and Filter.Compression then
447 return Filter.Stream_End
448 and then Filter.Offset = Footer_Array'Last + 1;
449 else
450 return Filter.Stream_End;
451 end if;
452 end Stream_End;
453
454 --------------
455 -- Total_In --
456 --------------
457
458 function Total_In (Filter : in Filter_Type) return Count is
459 begin
460 return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
461 end Total_In;
462
463 ---------------
464 -- Total_Out --
465 ---------------
466
467 function Total_Out (Filter : in Filter_Type) return Count is
468 begin
469 return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
470 end Total_Out;
471
472 ---------------
473 -- Translate --
474 ---------------
475
476 procedure Translate
477 (Filter : in out Filter_Type;
478 In_Data : in Ada.Streams.Stream_Element_Array;
479 In_Last : out Ada.Streams.Stream_Element_Offset;
480 Out_Data : out Ada.Streams.Stream_Element_Array;
481 Out_Last : out Ada.Streams.Stream_Element_Offset;
482 Flush : in Flush_Mode) is
483 begin
484 if Filter.Header = GZip and then Filter.Compression then
485 Translate_GZip
486 (Filter => Filter,
487 In_Data => In_Data,
488 In_Last => In_Last,
489 Out_Data => Out_Data,
490 Out_Last => Out_Last,
491 Flush => Flush);
492 else
493 Translate_Auto
494 (Filter => Filter,
495 In_Data => In_Data,
496 In_Last => In_Last,
497 Out_Data => Out_Data,
498 Out_Last => Out_Last,
499 Flush => Flush);
500 end if;
501 end Translate;
502
503 --------------------
504 -- Translate_Auto --
505 --------------------
506
507 procedure Translate_Auto
508 (Filter : in out Filter_Type;
509 In_Data : in Ada.Streams.Stream_Element_Array;
510 In_Last : out Ada.Streams.Stream_Element_Offset;
511 Out_Data : out Ada.Streams.Stream_Element_Array;
512 Out_Last : out Ada.Streams.Stream_Element_Offset;
513 Flush : in Flush_Mode)
514 is
515 use type Thin.Int;
516 Code : Thin.Int;
517
518 begin
519 if not Is_Open (Filter) then
520 raise Status_Error;
521 end if;
522
523 if Out_Data'Length = 0 and then In_Data'Length = 0 then
524 raise Constraint_Error;
525 end if;
526
527 Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
528 Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length);
529
530 Code := Flate (Filter.Compression).Step
531 (To_Thin_Access (Filter.Strm),
532 Thin.Int (Flush));
533
534 if Code = Thin.Z_STREAM_END then
535 Filter.Stream_End := True;
536 else
537 Check_Error (Filter.Strm.all, Code);
538 end if;
539
540 In_Last := In_Data'Last
541 - Stream_Element_Offset (Avail_In (Filter.Strm.all));
542 Out_Last := Out_Data'Last
543 - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
544 end Translate_Auto;
545
546 --------------------
547 -- Translate_GZip --
548 --------------------
549
550 procedure Translate_GZip
551 (Filter : in out Filter_Type;
552 In_Data : in Ada.Streams.Stream_Element_Array;
553 In_Last : out Ada.Streams.Stream_Element_Offset;
554 Out_Data : out Ada.Streams.Stream_Element_Array;
555 Out_Last : out Ada.Streams.Stream_Element_Offset;
556 Flush : in Flush_Mode)
557 is
558 Out_First : Stream_Element_Offset;
559
560 procedure Add_Data (Data : in Stream_Element_Array);
561 -- Add data to stream from the Filter.Offset till necessary,
562 -- used for add gzip headr/footer.
563
564 procedure Put_32
565 (Item : in out Stream_Element_Array;
566 Data : in Unsigned_32);
567 pragma Inline (Put_32);
568
569 --------------
570 -- Add_Data --
571 --------------
572
573 procedure Add_Data (Data : in Stream_Element_Array) is
574 Data_First : Stream_Element_Offset renames Filter.Offset;
575 Data_Last : Stream_Element_Offset;
576 Data_Len : Stream_Element_Offset; -- -1
577 Out_Len : Stream_Element_Offset; -- -1
578 begin
579 Out_First := Out_Last + 1;
580
581 if Data_First > Data'Last then
582 return;
583 end if;
584
585 Data_Len := Data'Last - Data_First;
586 Out_Len := Out_Data'Last - Out_First;
587
588 if Data_Len <= Out_Len then
589 Out_Last := Out_First + Data_Len;
590 Data_Last := Data'Last;
591 else
592 Out_Last := Out_Data'Last;
593 Data_Last := Data_First + Out_Len;
594 end if;
595
596 Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
597
598 Data_First := Data_Last + 1;
599 Out_First := Out_Last + 1;
600 end Add_Data;
601
602 ------------
603 -- Put_32 --
604 ------------
605
606 procedure Put_32
607 (Item : in out Stream_Element_Array;
608 Data : in Unsigned_32)
609 is
610 D : Unsigned_32 := Data;
611 begin
612 for J in Item'First .. Item'First + 3 loop
613 Item (J) := Stream_Element (D and 16#FF#);
614 D := Shift_Right (D, 8);
615 end loop;
616 end Put_32;
617
618 begin
619 Out_Last := Out_Data'First - 1;
620
621 if not Filter.Stream_End then
622 Add_Data (Simple_GZip_Header);
623
624 Translate_Auto
625 (Filter => Filter,
626 In_Data => In_Data,
627 In_Last => In_Last,
628 Out_Data => Out_Data (Out_First .. Out_Data'Last),
629 Out_Last => Out_Last,
630 Flush => Flush);
631
632 CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
633 end if;
634
635 if Filter.Stream_End and then Out_Last <= Out_Data'Last then
636 -- This detection method would work only when
637 -- Simple_GZip_Header'Last > Footer_Array'Last
638
639 if Filter.Offset = Simple_GZip_Header'Last + 1 then
640 Filter.Offset := Footer_Array'First;
641 end if;
642
643 declare
644 Footer : Footer_Array;
645 begin
646 Put_32 (Footer, Filter.CRC);
647 Put_32 (Footer (Footer'First + 4 .. Footer'Last),
648 Unsigned_32 (Total_In (Filter)));
649 Add_Data (Footer);
650 end;
651 end if;
652 end Translate_GZip;
653
654 -------------
655 -- Version --
656 -------------
657
658 function Version return String is
659 begin
660 return Interfaces.C.Strings.Value (Thin.zlibVersion);
661 end Version;
662
663 -----------
664 -- Write --
665 -----------
666
667 procedure Write
668 (Filter : in out Filter_Type;
669 Item : in Ada.Streams.Stream_Element_Array;
670 Flush : in Flush_Mode := No_Flush)
671 is
672 Buffer : Stream_Element_Array (1 .. Buffer_Size);
673 In_Last : Stream_Element_Offset;
674 Out_Last : Stream_Element_Offset;
675 In_First : Stream_Element_Offset := Item'First;
676 begin
677 if Item'Length = 0 and Flush = No_Flush then
678 return;
679 end if;
680
681 loop
682 Translate
683 (Filter => Filter,
684 In_Data => Item (In_First .. Item'Last),
685 In_Last => In_Last,
686 Out_Data => Buffer,
687 Out_Last => Out_Last,
688 Flush => Flush);
689
690 if Out_Last >= Buffer'First then
691 Write (Buffer (1 .. Out_Last));
692 end if;
693
694 exit when In_Last = Item'Last or Stream_End (Filter);
695
696 In_First := In_Last + 1;
697 end loop;
698 end Write;
699
700 end ZLib;
0 ------------------------------------------------------------------------------
1 -- ZLib for Ada thick binding. --
2 -- --
3 -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
4 -- --
5 -- This library is free software; you can redistribute it and/or modify --
6 -- it under the terms of the GNU General Public License as published by --
7 -- the Free Software Foundation; either version 2 of the License, or (at --
8 -- your option) any later version. --
9 -- --
10 -- This library is distributed in the hope that it will be useful, but --
11 -- WITHOUT ANY WARRANTY; without even the implied warranty of --
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
13 -- General Public License for more details. --
14 -- --
15 -- You should have received a copy of the GNU General Public License --
16 -- along with this library; if not, write to the Free Software Foundation, --
17 -- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
18 -- --
19 -- As a special exception, if other files instantiate generics from this --
20 -- unit, or you link this unit with other files to produce an executable, --
21 -- this unit does not by itself cause the resulting executable to be --
22 -- covered by the GNU General Public License. This exception does not --
23 -- however invalidate any other reasons why the executable file might be --
24 -- covered by the GNU Public License. --
25 ------------------------------------------------------------------------------
26
27 -- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
28
29 with Ada.Streams;
30
31 with Interfaces;
32
33 package ZLib is
34
35 ZLib_Error : exception;
36 Status_Error : exception;
37
38 type Compression_Level is new Integer range -1 .. 9;
39
40 type Flush_Mode is private;
41
42 type Compression_Method is private;
43
44 type Window_Bits_Type is new Integer range 8 .. 15;
45
46 type Memory_Level_Type is new Integer range 1 .. 9;
47
48 type Unsigned_32 is new Interfaces.Unsigned_32;
49
50 type Strategy_Type is private;
51
52 type Header_Type is (None, Auto, Default, GZip);
53 -- Header type usage have a some limitation for inflate.
54 -- See comment for Inflate_Init.
55
56 subtype Count is Ada.Streams.Stream_Element_Count;
57
58 Default_Memory_Level : constant Memory_Level_Type := 8;
59 Default_Window_Bits : constant Window_Bits_Type := 15;
60
61 ----------------------------------
62 -- Compression method constants --
63 ----------------------------------
64
65 Deflated : constant Compression_Method;
66 -- Only one method allowed in this ZLib version
67
68 ---------------------------------
69 -- Compression level constants --
70 ---------------------------------
71
72 No_Compression : constant Compression_Level := 0;
73 Best_Speed : constant Compression_Level := 1;
74 Best_Compression : constant Compression_Level := 9;
75 Default_Compression : constant Compression_Level := -1;
76
77 --------------------------
78 -- Flush mode constants --
79 --------------------------
80
81 No_Flush : constant Flush_Mode;
82 -- Regular way for compression, no flush
83
84 Partial_Flush : constant Flush_Mode;
85 -- Will be removed, use Z_SYNC_FLUSH instead
86
87 Sync_Flush : constant Flush_Mode;
88 -- All pending output is flushed to the output buffer and the output
89 -- is aligned on a byte boundary, so that the decompressor can get all
90 -- input data available so far. (In particular avail_in is zero after the
91 -- call if enough output space has been provided before the call.)
92 -- Flushing may degrade compression for some compression algorithms and so
93 -- it should be used only when necessary.
94
95 Block_Flush : constant Flush_Mode;
96 -- Z_BLOCK requests that inflate() stop
97 -- if and when it get to the next deflate block boundary. When decoding the
98 -- zlib or gzip format, this will cause inflate() to return immediately
99 -- after the header and before the first block. When doing a raw inflate,
100 -- inflate() will go ahead and process the first block, and will return
101 -- when it gets to the end of that block, or when it runs out of data.
102
103 Full_Flush : constant Flush_Mode;
104 -- All output is flushed as with SYNC_FLUSH, and the compression state
105 -- is reset so that decompression can restart from this point if previous
106 -- compressed data has been damaged or if random access is desired. Using
107 -- Full_Flush too often can seriously degrade the compression.
108
109 Finish : constant Flush_Mode;
110 -- Just for tell the compressor that input data is complete.
111
112 ------------------------------------
113 -- Compression strategy constants --
114 ------------------------------------
115
116 -- RLE stategy could be used only in version 1.2.0 and later.
117
118 Filtered : constant Strategy_Type;
119 Huffman_Only : constant Strategy_Type;
120 RLE : constant Strategy_Type;
121 Default_Strategy : constant Strategy_Type;
122
123 Default_Buffer_Size : constant := 4096;
124
125 type Filter_Type is tagged limited private;
126 -- The filter is for compression and for decompression.
127 -- The usage of the type is depend of its initialization.
128
129 function Version return String;
130 pragma Inline (Version);
131 -- Return string representation of the ZLib version.
132
133 procedure Deflate_Init
134 (Filter : in out Filter_Type;
135 Level : in Compression_Level := Default_Compression;
136 Strategy : in Strategy_Type := Default_Strategy;
137 Method : in Compression_Method := Deflated;
138 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
139 Memory_Level : in Memory_Level_Type := Default_Memory_Level;
140 Header : in Header_Type := Default);
141 -- Compressor initialization.
142 -- When Header parameter is Auto or Default, then default zlib header
143 -- would be provided for compressed data.
144 -- When Header is GZip, then gzip header would be set instead of
145 -- default header.
146 -- When Header is None, no header would be set for compressed data.
147
148 procedure Inflate_Init
149 (Filter : in out Filter_Type;
150 Window_Bits : in Window_Bits_Type := Default_Window_Bits;
151 Header : in Header_Type := Default);
152 -- Decompressor initialization.
153 -- Default header type mean that ZLib default header is expecting in the
154 -- input compressed stream.
155 -- Header type None mean that no header is expecting in the input stream.
156 -- GZip header type mean that GZip header is expecting in the
157 -- input compressed stream.
158 -- Auto header type mean that header type (GZip or Native) would be
159 -- detected automatically in the input stream.
160 -- Note that header types parameter values None, GZip and Auto are
161 -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
162 -- Deflate_Init is supporting all header types.
163
164 function Is_Open (Filter : in Filter_Type) return Boolean;
165 pragma Inline (Is_Open);
166 -- Is the filter opened for compression or decompression.
167
168 procedure Close
169 (Filter : in out Filter_Type;
170 Ignore_Error : in Boolean := False);
171 -- Closing the compression or decompressor.
172 -- If stream is closing before the complete and Ignore_Error is False,
173 -- The exception would be raised.
174
175 generic
176 with procedure Data_In
177 (Item : out Ada.Streams.Stream_Element_Array;
178 Last : out Ada.Streams.Stream_Element_Offset);
179 with procedure Data_Out
180 (Item : in Ada.Streams.Stream_Element_Array);
181 procedure Generic_Translate
182 (Filter : in out Filter_Type;
183 In_Buffer_Size : in Integer := Default_Buffer_Size;
184 Out_Buffer_Size : in Integer := Default_Buffer_Size);
185 -- Compress/decompress data fetch from Data_In routine and pass the result
186 -- to the Data_Out routine. User should provide Data_In and Data_Out
187 -- for compression/decompression data flow.
188 -- Compression or decompression depend on Filter initialization.
189
190 function Total_In (Filter : in Filter_Type) return Count;
191 pragma Inline (Total_In);
192 -- Returns total number of input bytes read so far
193
194 function Total_Out (Filter : in Filter_Type) return Count;
195 pragma Inline (Total_Out);
196 -- Returns total number of bytes output so far
197
198 function CRC32
199 (CRC : in Unsigned_32;
200 Data : in Ada.Streams.Stream_Element_Array)
201 return Unsigned_32;
202 pragma Inline (CRC32);
203 -- Compute CRC32, it could be necessary for make gzip format
204
205 procedure CRC32
206 (CRC : in out Unsigned_32;
207 Data : in Ada.Streams.Stream_Element_Array);
208 pragma Inline (CRC32);
209 -- Compute CRC32, it could be necessary for make gzip format
210
211 -------------------------------------------------
212 -- Below is more complex low level routines. --
213 -------------------------------------------------
214
215 procedure Translate
216 (Filter : in out Filter_Type;
217 In_Data : in Ada.Streams.Stream_Element_Array;
218 In_Last : out Ada.Streams.Stream_Element_Offset;
219 Out_Data : out Ada.Streams.Stream_Element_Array;
220 Out_Last : out Ada.Streams.Stream_Element_Offset;
221 Flush : in Flush_Mode);
222 -- Compress/decompress the In_Data buffer and place the result into
223 -- Out_Data. In_Last is the index of last element from In_Data accepted by
224 -- the Filter. Out_Last is the last element of the received data from
225 -- Filter. To tell the filter that incoming data are complete put the
226 -- Flush parameter to Finish.
227
228 function Stream_End (Filter : in Filter_Type) return Boolean;
229 pragma Inline (Stream_End);
230 -- Return the true when the stream is complete.
231
232 procedure Flush
233 (Filter : in out Filter_Type;
234 Out_Data : out Ada.Streams.Stream_Element_Array;
235 Out_Last : out Ada.Streams.Stream_Element_Offset;
236 Flush : in Flush_Mode);
237 pragma Inline (Flush);
238 -- Flushing the data from the compressor.
239
240 generic
241 with procedure Write
242 (Item : in Ada.Streams.Stream_Element_Array);
243 -- User should provide this routine for accept
244 -- compressed/decompressed data.
245
246 Buffer_Size : in Ada.Streams.Stream_Element_Offset
247 := Default_Buffer_Size;
248 -- Buffer size for Write user routine.
249
250 procedure Write
251 (Filter : in out Filter_Type;
252 Item : in Ada.Streams.Stream_Element_Array;
253 Flush : in Flush_Mode := No_Flush);
254 -- Compress/Decompress data from Item to the generic parameter procedure
255 -- Write. Output buffer size could be set in Buffer_Size generic parameter.
256
257 generic
258 with procedure Read
259 (Item : out Ada.Streams.Stream_Element_Array;
260 Last : out Ada.Streams.Stream_Element_Offset);
261 -- User should provide data for compression/decompression
262 -- thru this routine.
263
264 Buffer : in out Ada.Streams.Stream_Element_Array;
265 -- Buffer for keep remaining data from the previous
266 -- back read.
267
268 Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
269 -- Rest_First have to be initialized to Buffer'Last + 1
270 -- Rest_Last have to be initialized to Buffer'Last
271 -- before usage.
272
273 Allow_Read_Some : in Boolean := False;
274 -- Is it allowed to return Last < Item'Last before end of data.
275
276 procedure Read
277 (Filter : in out Filter_Type;
278 Item : out Ada.Streams.Stream_Element_Array;
279 Last : out Ada.Streams.Stream_Element_Offset;
280 Flush : in Flush_Mode := No_Flush);
281 -- Compress/Decompress data from generic parameter procedure Read to the
282 -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
283 -- indicators. If Allow_Read_Some is True, Read routines could return
284 -- Last < Item'Last only at end of stream.
285
286 private
287
288 use Ada.Streams;
289
290 pragma Assert (Ada.Streams.Stream_Element'Size = 8);
291 pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
292
293 type Flush_Mode is new Integer range 0 .. 5;
294
295 type Compression_Method is new Integer range 8 .. 8;
296
297 type Strategy_Type is new Integer range 0 .. 3;
298
299 No_Flush : constant Flush_Mode := 0;
300 Partial_Flush : constant Flush_Mode := 1;
301 Sync_Flush : constant Flush_Mode := 2;
302 Full_Flush : constant Flush_Mode := 3;
303 Finish : constant Flush_Mode := 4;
304 Block_Flush : constant Flush_Mode := 5;
305
306 Filtered : constant Strategy_Type := 1;
307 Huffman_Only : constant Strategy_Type := 2;
308 RLE : constant Strategy_Type := 3;
309 Default_Strategy : constant Strategy_Type := 0;
310
311 Deflated : constant Compression_Method := 8;
312
313 type Z_Stream;
314
315 type Z_Stream_Access is access all Z_Stream;
316
317 type Filter_Type is tagged limited record
318 Strm : Z_Stream_Access;
319 Compression : Boolean;
320 Stream_End : Boolean;
321 Header : Header_Type;
322 CRC : Unsigned_32;
323 Offset : Stream_Element_Offset;
324 -- Offset for gzip header/footer output.
325 end record;
326
327 end ZLib;
0 project Zlib is
1
2 for Languages use ("Ada");
3 for Source_Dirs use (".");
4 for Object_Dir use ".";
5 for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
6
7 package Compiler is
8 for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
9 end Compiler;
10
11 package Linker is
12 for Default_Switches ("ada") use ("-lz");
13 end Linker;
14
15 package Builder is
16 for Default_Switches ("ada") use ("-s", "-gnatQ");
17 end Builder;
18
19 end Zlib;
0 This is a patched version of zlib modified to use
1 Pentium-optimized assembly code in the deflation algorithm. The files
2 changed/added by this patch are:
3
4 README.586
5 match.S
6
7 The effectiveness of these modifications is a bit marginal, as the the
8 program's bottleneck seems to be mostly L1-cache contention, for which
9 there is no real way to work around without rewriting the basic
10 algorithm. The speedup on average is around 5-10% (which is generally
11 less than the amount of variance between subsequent executions).
12 However, when used at level 9 compression, the cache contention can
13 drop enough for the assembly version to achieve 10-20% speedup (and
14 sometimes more, depending on the amount of overall redundancy in the
15 files). Even here, though, cache contention can still be the limiting
16 factor, depending on the nature of the program using the zlib library.
17 This may also mean that better improvements will be seen on a Pentium
18 with MMX, which suffers much less from L1-cache contention, but I have
19 not yet verified this.
20
21 Note that this code has been tailored for the Pentium in particular,
22 and will not perform well on the Pentium Pro (due to the use of a
23 partial register in the inner loop).
24
25 If you are using an assembler other than GNU as, you will have to
26 translate match.S to use your assembler's syntax. (Have fun.)
27
28 Brian Raiter
29 breadbox@muppetlabs.com
30 April, 1998
31
32
33 Added for zlib 1.1.3:
34
35 The patches come from
36 http://www.muppetlabs.com/~breadbox/software/assembly.html
37
38 To compile zlib with this asm file, copy match.S to the zlib directory
39 then do:
40
41 CFLAGS="-O3 -DASMV" ./configure
42 make OBJA=match.o
0 /* match.s -- Pentium-optimized version of longest_match()
1 * Written for zlib 1.1.2
2 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
3 *
4 * This is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License.
6 */
7
8 #ifndef NO_UNDERLINE
9 #define match_init _match_init
10 #define longest_match _longest_match
11 #endif
12
13 #define MAX_MATCH (258)
14 #define MIN_MATCH (3)
15 #define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
16 #define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
17
18 /* stack frame offsets */
19
20 #define wmask 0 /* local copy of s->wmask */
21 #define window 4 /* local copy of s->window */
22 #define windowbestlen 8 /* s->window + bestlen */
23 #define chainlenscanend 12 /* high word: current chain len */
24 /* low word: last bytes sought */
25 #define scanstart 16 /* first two bytes of string */
26 #define scanalign 20 /* dword-misalignment of string */
27 #define nicematch 24 /* a good enough match size */
28 #define bestlen 28 /* size of best match so far */
29 #define scan 32 /* ptr to string wanting match */
30
31 #define LocalVarsSize (36)
32 /* saved ebx 36 */
33 /* saved edi 40 */
34 /* saved esi 44 */
35 /* saved ebp 48 */
36 /* return address 52 */
37 #define deflatestate 56 /* the function arguments */
38 #define curmatch 60
39
40 /* Offsets for fields in the deflate_state structure. These numbers
41 * are calculated from the definition of deflate_state, with the
42 * assumption that the compiler will dword-align the fields. (Thus,
43 * changing the definition of deflate_state could easily cause this
44 * program to crash horribly, without so much as a warning at
45 * compile time. Sigh.)
46 */
47 #define dsWSize 36
48 #define dsWMask 44
49 #define dsWindow 48
50 #define dsPrev 56
51 #define dsMatchLen 88
52 #define dsPrevMatch 92
53 #define dsStrStart 100
54 #define dsMatchStart 104
55 #define dsLookahead 108
56 #define dsPrevLen 112
57 #define dsMaxChainLen 116
58 #define dsGoodMatch 132
59 #define dsNiceMatch 136
60
61
62 .file "match.S"
63
64 .globl match_init, longest_match
65
66 .text
67
68 /* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
69
70 longest_match:
71
72 /* Save registers that the compiler may be using, and adjust %esp to */
73 /* make room for our stack frame. */
74
75 pushl %ebp
76 pushl %edi
77 pushl %esi
78 pushl %ebx
79 subl $LocalVarsSize, %esp
80
81 /* Retrieve the function arguments. %ecx will hold cur_match */
82 /* throughout the entire function. %edx will hold the pointer to the */
83 /* deflate_state structure during the function's setup (before */
84 /* entering the main loop). */
85
86 movl deflatestate(%esp), %edx
87 movl curmatch(%esp), %ecx
88
89 /* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
90
91 movl dsNiceMatch(%edx), %eax
92 movl dsLookahead(%edx), %ebx
93 cmpl %eax, %ebx
94 jl LookaheadLess
95 movl %eax, %ebx
96 LookaheadLess: movl %ebx, nicematch(%esp)
97
98 /* register Bytef *scan = s->window + s->strstart; */
99
100 movl dsWindow(%edx), %esi
101 movl %esi, window(%esp)
102 movl dsStrStart(%edx), %ebp
103 lea (%esi,%ebp), %edi
104 movl %edi, scan(%esp)
105
106 /* Determine how many bytes the scan ptr is off from being */
107 /* dword-aligned. */
108
109 movl %edi, %eax
110 negl %eax
111 andl $3, %eax
112 movl %eax, scanalign(%esp)
113
114 /* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
115 /* s->strstart - (IPos)MAX_DIST(s) : NIL; */
116
117 movl dsWSize(%edx), %eax
118 subl $MIN_LOOKAHEAD, %eax
119 subl %eax, %ebp
120 jg LimitPositive
121 xorl %ebp, %ebp
122 LimitPositive:
123
124 /* unsigned chain_length = s->max_chain_length; */
125 /* if (s->prev_length >= s->good_match) { */
126 /* chain_length >>= 2; */
127 /* } */
128
129 movl dsPrevLen(%edx), %eax
130 movl dsGoodMatch(%edx), %ebx
131 cmpl %ebx, %eax
132 movl dsMaxChainLen(%edx), %ebx
133 jl LastMatchGood
134 shrl $2, %ebx
135 LastMatchGood:
136
137 /* chainlen is decremented once beforehand so that the function can */
138 /* use the sign flag instead of the zero flag for the exit test. */
139 /* It is then shifted into the high word, to make room for the scanend */
140 /* scanend value, which it will always accompany. */
141
142 decl %ebx
143 shll $16, %ebx
144
145 /* int best_len = s->prev_length; */
146
147 movl dsPrevLen(%edx), %eax
148 movl %eax, bestlen(%esp)
149
150 /* Store the sum of s->window + best_len in %esi locally, and in %esi. */
151
152 addl %eax, %esi
153 movl %esi, windowbestlen(%esp)
154
155 /* register ush scan_start = *(ushf*)scan; */
156 /* register ush scan_end = *(ushf*)(scan+best_len-1); */
157
158 movw (%edi), %bx
159 movw %bx, scanstart(%esp)
160 movw -1(%edi,%eax), %bx
161 movl %ebx, chainlenscanend(%esp)
162
163 /* Posf *prev = s->prev; */
164 /* uInt wmask = s->w_mask; */
165
166 movl dsPrev(%edx), %edi
167 movl dsWMask(%edx), %edx
168 mov %edx, wmask(%esp)
169
170 /* Jump into the main loop. */
171
172 jmp LoopEntry
173
174 .balign 16
175
176 /* do {
177 * match = s->window + cur_match;
178 * if (*(ushf*)(match+best_len-1) != scan_end ||
179 * *(ushf*)match != scan_start) continue;
180 * [...]
181 * } while ((cur_match = prev[cur_match & wmask]) > limit
182 * && --chain_length != 0);
183 *
184 * Here is the inner loop of the function. The function will spend the
185 * majority of its time in this loop, and majority of that time will
186 * be spent in the first ten instructions.
187 *
188 * Within this loop:
189 * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
190 * %ecx = curmatch
191 * %edx = curmatch & wmask
192 * %esi = windowbestlen - i.e., (window + bestlen)
193 * %edi = prev
194 * %ebp = limit
195 *
196 * Two optimization notes on the choice of instructions:
197 *
198 * The first instruction uses a 16-bit address, which costs an extra,
199 * unpairable cycle. This is cheaper than doing a 32-bit access and
200 * zeroing the high word, due to the 3-cycle misalignment penalty which
201 * would occur half the time. This also turns out to be cheaper than
202 * doing two separate 8-bit accesses, as the memory is so rarely in the
203 * L1 cache.
204 *
205 * The window buffer, however, apparently spends a lot of time in the
206 * cache, and so it is faster to retrieve the word at the end of the
207 * match string with two 8-bit loads. The instructions that test the
208 * word at the beginning of the match string, however, are executed
209 * much less frequently, and there it was cheaper to use 16-bit
210 * instructions, which avoided the necessity of saving off and
211 * subsequently reloading one of the other registers.
212 */
213 LookupLoop:
214 /* 1 U & V */
215 movw (%edi,%edx,2), %cx /* 2 U pipe */
216 movl wmask(%esp), %edx /* 2 V pipe */
217 cmpl %ebp, %ecx /* 3 U pipe */
218 jbe LeaveNow /* 3 V pipe */
219 subl $0x00010000, %ebx /* 4 U pipe */
220 js LeaveNow /* 4 V pipe */
221 LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
222 andl %ecx, %edx /* 5 V pipe */
223 cmpb %bl, %al /* 6 U pipe */
224 jnz LookupLoop /* 6 V pipe */
225 movb (%esi,%ecx), %ah
226 cmpb %bh, %ah
227 jnz LookupLoop
228 movl window(%esp), %eax
229 movw (%eax,%ecx), %ax
230 cmpw scanstart(%esp), %ax
231 jnz LookupLoop
232
233 /* Store the current value of chainlen. */
234
235 movl %ebx, chainlenscanend(%esp)
236
237 /* Point %edi to the string under scrutiny, and %esi to the string we */
238 /* are hoping to match it up with. In actuality, %esi and %edi are */
239 /* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
240 /* initialized to -(MAX_MATCH_8 - scanalign). */
241
242 movl window(%esp), %esi
243 movl scan(%esp), %edi
244 addl %ecx, %esi
245 movl scanalign(%esp), %eax
246 movl $(-MAX_MATCH_8), %edx
247 lea MAX_MATCH_8(%edi,%eax), %edi
248 lea MAX_MATCH_8(%esi,%eax), %esi
249
250 /* Test the strings for equality, 8 bytes at a time. At the end,
251 * adjust %edx so that it is offset to the exact byte that mismatched.
252 *
253 * We already know at this point that the first three bytes of the
254 * strings match each other, and they can be safely passed over before
255 * starting the compare loop. So what this code does is skip over 0-3
256 * bytes, as much as necessary in order to dword-align the %edi
257 * pointer. (%esi will still be misaligned three times out of four.)
258 *
259 * It should be confessed that this loop usually does not represent
260 * much of the total running time. Replacing it with a more
261 * straightforward "rep cmpsb" would not drastically degrade
262 * performance.
263 */
264 LoopCmps:
265 movl (%esi,%edx), %eax
266 movl (%edi,%edx), %ebx
267 xorl %ebx, %eax
268 jnz LeaveLoopCmps
269 movl 4(%esi,%edx), %eax
270 movl 4(%edi,%edx), %ebx
271 xorl %ebx, %eax
272 jnz LeaveLoopCmps4
273 addl $8, %edx
274 jnz LoopCmps
275 jmp LenMaximum
276 LeaveLoopCmps4: addl $4, %edx
277 LeaveLoopCmps: testl $0x0000FFFF, %eax
278 jnz LenLower
279 addl $2, %edx
280 shrl $16, %eax
281 LenLower: subb $1, %al
282 adcl $0, %edx
283
284 /* Calculate the length of the match. If it is longer than MAX_MATCH, */
285 /* then automatically accept it as the best possible match and leave. */
286
287 lea (%edi,%edx), %eax
288 movl scan(%esp), %edi
289 subl %edi, %eax
290 cmpl $MAX_MATCH, %eax
291 jge LenMaximum
292
293 /* If the length of the match is not longer than the best match we */
294 /* have so far, then forget it and return to the lookup loop. */
295
296 movl deflatestate(%esp), %edx
297 movl bestlen(%esp), %ebx
298 cmpl %ebx, %eax
299 jg LongerMatch
300 movl chainlenscanend(%esp), %ebx
301 movl windowbestlen(%esp), %esi
302 movl dsPrev(%edx), %edi
303 movl wmask(%esp), %edx
304 andl %ecx, %edx
305 jmp LookupLoop
306
307 /* s->match_start = cur_match; */
308 /* best_len = len; */
309 /* if (len >= nice_match) break; */
310 /* scan_end = *(ushf*)(scan+best_len-1); */
311
312 LongerMatch: movl nicematch(%esp), %ebx
313 movl %eax, bestlen(%esp)
314 movl %ecx, dsMatchStart(%edx)
315 cmpl %ebx, %eax
316 jge LeaveNow
317 movl window(%esp), %esi
318 addl %eax, %esi
319 movl %esi, windowbestlen(%esp)
320 movl chainlenscanend(%esp), %ebx
321 movw -1(%edi,%eax), %bx
322 movl dsPrev(%edx), %edi
323 movl %ebx, chainlenscanend(%esp)
324 movl wmask(%esp), %edx
325 andl %ecx, %edx
326 jmp LookupLoop
327
328 /* Accept the current string, with the maximum possible length. */
329
330 LenMaximum: movl deflatestate(%esp), %edx
331 movl $MAX_MATCH, bestlen(%esp)
332 movl %ecx, dsMatchStart(%edx)
333
334 /* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
335 /* return s->lookahead; */
336
337 LeaveNow:
338 movl deflatestate(%esp), %edx
339 movl bestlen(%esp), %ebx
340 movl dsLookahead(%edx), %eax
341 cmpl %eax, %ebx
342 jg LookaheadRet
343 movl %ebx, %eax
344 LookaheadRet:
345
346 /* Restore the stack and return from whence we came. */
347
348 addl $LocalVarsSize, %esp
349 popl %ebx
350 popl %esi
351 popl %edi
352 popl %ebp
353 match_init: ret
0 This is a patched version of zlib, modified to use
1 Pentium-Pro-optimized assembly code in the deflation algorithm. The
2 files changed/added by this patch are:
3
4 README.686
5 match.S
6
7 The speedup that this patch provides varies, depending on whether the
8 compiler used to build the original version of zlib falls afoul of the
9 PPro's speed traps. My own tests show a speedup of around 10-20% at
10 the default compression level, and 20-30% using -9, against a version
11 compiled using gcc 2.7.2.3. Your mileage may vary.
12
13 Note that this code has been tailored for the PPro/PII in particular,
14 and will not perform particuarly well on a Pentium.
15
16 If you are using an assembler other than GNU as, you will have to
17 translate match.S to use your assembler's syntax. (Have fun.)
18
19 Brian Raiter
20 breadbox@muppetlabs.com
21 April, 1998
22
23
24 Added for zlib 1.1.3:
25
26 The patches come from
27 http://www.muppetlabs.com/~breadbox/software/assembly.html
28
29 To compile zlib with this asm file, copy match.S to the zlib directory
30 then do:
31
32 CFLAGS="-O3 -DASMV" ./configure
33 make OBJA=match.o
0 /* match.s -- Pentium-Pro-optimized version of longest_match()
1 * Written for zlib 1.1.2
2 * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
3 *
4 * This is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License.
6 */
7
8 #ifndef NO_UNDERLINE
9 #define match_init _match_init
10 #define longest_match _longest_match
11 #endif
12
13 #define MAX_MATCH (258)
14 #define MIN_MATCH (3)
15 #define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
16 #define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
17
18 /* stack frame offsets */
19
20 #define chainlenwmask 0 /* high word: current chain len */
21 /* low word: s->wmask */
22 #define window 4 /* local copy of s->window */
23 #define windowbestlen 8 /* s->window + bestlen */
24 #define scanstart 16 /* first two bytes of string */
25 #define scanend 12 /* last two bytes of string */
26 #define scanalign 20 /* dword-misalignment of string */
27 #define nicematch 24 /* a good enough match size */
28 #define bestlen 28 /* size of best match so far */
29 #define scan 32 /* ptr to string wanting match */
30
31 #define LocalVarsSize (36)
32 /* saved ebx 36 */
33 /* saved edi 40 */
34 /* saved esi 44 */
35 /* saved ebp 48 */
36 /* return address 52 */
37 #define deflatestate 56 /* the function arguments */
38 #define curmatch 60
39
40 /* Offsets for fields in the deflate_state structure. These numbers
41 * are calculated from the definition of deflate_state, with the
42 * assumption that the compiler will dword-align the fields. (Thus,
43 * changing the definition of deflate_state could easily cause this
44 * program to crash horribly, without so much as a warning at
45 * compile time. Sigh.)
46 */
47 #define dsWSize 36
48 #define dsWMask 44
49 #define dsWindow 48
50 #define dsPrev 56
51 #define dsMatchLen 88
52 #define dsPrevMatch 92
53 #define dsStrStart 100
54 #define dsMatchStart 104
55 #define dsLookahead 108
56 #define dsPrevLen 112
57 #define dsMaxChainLen 116
58 #define dsGoodMatch 132
59 #define dsNiceMatch 136
60
61
62 .file "match.S"
63
64 .globl match_init, longest_match
65
66 .text
67
68 /* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
69
70 longest_match:
71
72 /* Save registers that the compiler may be using, and adjust %esp to */
73 /* make room for our stack frame. */
74
75 pushl %ebp
76 pushl %edi
77 pushl %esi
78 pushl %ebx
79 subl $LocalVarsSize, %esp
80
81 /* Retrieve the function arguments. %ecx will hold cur_match */
82 /* throughout the entire function. %edx will hold the pointer to the */
83 /* deflate_state structure during the function's setup (before */
84 /* entering the main loop). */
85
86 movl deflatestate(%esp), %edx
87 movl curmatch(%esp), %ecx
88
89 /* uInt wmask = s->w_mask; */
90 /* unsigned chain_length = s->max_chain_length; */
91 /* if (s->prev_length >= s->good_match) { */
92 /* chain_length >>= 2; */
93 /* } */
94
95 movl dsPrevLen(%edx), %eax
96 movl dsGoodMatch(%edx), %ebx
97 cmpl %ebx, %eax
98 movl dsWMask(%edx), %eax
99 movl dsMaxChainLen(%edx), %ebx
100 jl LastMatchGood
101 shrl $2, %ebx
102 LastMatchGood:
103
104 /* chainlen is decremented once beforehand so that the function can */
105 /* use the sign flag instead of the zero flag for the exit test. */
106 /* It is then shifted into the high word, to make room for the wmask */
107 /* value, which it will always accompany. */
108
109 decl %ebx
110 shll $16, %ebx
111 orl %eax, %ebx
112 movl %ebx, chainlenwmask(%esp)
113
114 /* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
115
116 movl dsNiceMatch(%edx), %eax
117 movl dsLookahead(%edx), %ebx
118 cmpl %eax, %ebx
119 jl LookaheadLess
120 movl %eax, %ebx
121 LookaheadLess: movl %ebx, nicematch(%esp)
122
123 /* register Bytef *scan = s->window + s->strstart; */
124
125 movl dsWindow(%edx), %esi
126 movl %esi, window(%esp)
127 movl dsStrStart(%edx), %ebp
128 lea (%esi,%ebp), %edi
129 movl %edi, scan(%esp)
130
131 /* Determine how many bytes the scan ptr is off from being */
132 /* dword-aligned. */
133
134 movl %edi, %eax
135 negl %eax
136 andl $3, %eax
137 movl %eax, scanalign(%esp)
138
139 /* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
140 /* s->strstart - (IPos)MAX_DIST(s) : NIL; */
141
142 movl dsWSize(%edx), %eax
143 subl $MIN_LOOKAHEAD, %eax
144 subl %eax, %ebp
145 jg LimitPositive
146 xorl %ebp, %ebp
147 LimitPositive:
148
149 /* int best_len = s->prev_length; */
150
151 movl dsPrevLen(%edx), %eax
152 movl %eax, bestlen(%esp)
153
154 /* Store the sum of s->window + best_len in %esi locally, and in %esi. */
155
156 addl %eax, %esi
157 movl %esi, windowbestlen(%esp)
158
159 /* register ush scan_start = *(ushf*)scan; */
160 /* register ush scan_end = *(ushf*)(scan+best_len-1); */
161 /* Posf *prev = s->prev; */
162
163 movzwl (%edi), %ebx
164 movl %ebx, scanstart(%esp)
165 movzwl -1(%edi,%eax), %ebx
166 movl %ebx, scanend(%esp)
167 movl dsPrev(%edx), %edi
168
169 /* Jump into the main loop. */
170
171 movl chainlenwmask(%esp), %edx
172 jmp LoopEntry
173
174 .balign 16
175
176 /* do {
177 * match = s->window + cur_match;
178 * if (*(ushf*)(match+best_len-1) != scan_end ||
179 * *(ushf*)match != scan_start) continue;
180 * [...]
181 * } while ((cur_match = prev[cur_match & wmask]) > limit
182 * && --chain_length != 0);
183 *
184 * Here is the inner loop of the function. The function will spend the
185 * majority of its time in this loop, and majority of that time will
186 * be spent in the first ten instructions.
187 *
188 * Within this loop:
189 * %ebx = scanend
190 * %ecx = curmatch
191 * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
192 * %esi = windowbestlen - i.e., (window + bestlen)
193 * %edi = prev
194 * %ebp = limit
195 */
196 LookupLoop:
197 andl %edx, %ecx
198 movzwl (%edi,%ecx,2), %ecx
199 cmpl %ebp, %ecx
200 jbe LeaveNow
201 subl $0x00010000, %edx
202 js LeaveNow
203 LoopEntry: movzwl -1(%esi,%ecx), %eax
204 cmpl %ebx, %eax
205 jnz LookupLoop
206 movl window(%esp), %eax
207 movzwl (%eax,%ecx), %eax
208 cmpl scanstart(%esp), %eax
209 jnz LookupLoop
210
211 /* Store the current value of chainlen. */
212
213 movl %edx, chainlenwmask(%esp)
214
215 /* Point %edi to the string under scrutiny, and %esi to the string we */
216 /* are hoping to match it up with. In actuality, %esi and %edi are */
217 /* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
218 /* initialized to -(MAX_MATCH_8 - scanalign). */
219
220 movl window(%esp), %esi
221 movl scan(%esp), %edi
222 addl %ecx, %esi
223 movl scanalign(%esp), %eax
224 movl $(-MAX_MATCH_8), %edx
225 lea MAX_MATCH_8(%edi,%eax), %edi
226 lea MAX_MATCH_8(%esi,%eax), %esi
227
228 /* Test the strings for equality, 8 bytes at a time. At the end,
229 * adjust %edx so that it is offset to the exact byte that mismatched.
230 *
231 * We already know at this point that the first three bytes of the
232 * strings match each other, and they can be safely passed over before
233 * starting the compare loop. So what this code does is skip over 0-3
234 * bytes, as much as necessary in order to dword-align the %edi
235 * pointer. (%esi will still be misaligned three times out of four.)
236 *
237 * It should be confessed that this loop usually does not represent
238 * much of the total running time. Replacing it with a more
239 * straightforward "rep cmpsb" would not drastically degrade
240 * performance.
241 */
242 LoopCmps:
243 movl (%esi,%edx), %eax
244 xorl (%edi,%edx), %eax
245 jnz LeaveLoopCmps
246 movl 4(%esi,%edx), %eax
247 xorl 4(%edi,%edx), %eax
248 jnz LeaveLoopCmps4
249 addl $8, %edx
250 jnz LoopCmps
251 jmp LenMaximum
252 LeaveLoopCmps4: addl $4, %edx
253 LeaveLoopCmps: testl $0x0000FFFF, %eax
254 jnz LenLower
255 addl $2, %edx
256 shrl $16, %eax
257 LenLower: subb $1, %al
258 adcl $0, %edx
259
260 /* Calculate the length of the match. If it is longer than MAX_MATCH, */
261 /* then automatically accept it as the best possible match and leave. */
262
263 lea (%edi,%edx), %eax
264 movl scan(%esp), %edi
265 subl %edi, %eax
266 cmpl $MAX_MATCH, %eax
267 jge LenMaximum
268
269 /* If the length of the match is not longer than the best match we */
270 /* have so far, then forget it and return to the lookup loop. */
271
272 movl deflatestate(%esp), %edx
273 movl bestlen(%esp), %ebx
274 cmpl %ebx, %eax
275 jg LongerMatch
276 movl windowbestlen(%esp), %esi
277 movl dsPrev(%edx), %edi
278 movl scanend(%esp), %ebx
279 movl chainlenwmask(%esp), %edx
280 jmp LookupLoop
281
282 /* s->match_start = cur_match; */
283 /* best_len = len; */
284 /* if (len >= nice_match) break; */
285 /* scan_end = *(ushf*)(scan+best_len-1); */
286
287 LongerMatch: movl nicematch(%esp), %ebx
288 movl %eax, bestlen(%esp)
289 movl %ecx, dsMatchStart(%edx)
290 cmpl %ebx, %eax
291 jge LeaveNow
292 movl window(%esp), %esi
293 addl %eax, %esi
294 movl %esi, windowbestlen(%esp)
295 movzwl -1(%edi,%eax), %ebx
296 movl dsPrev(%edx), %edi
297 movl %ebx, scanend(%esp)
298 movl chainlenwmask(%esp), %edx
299 jmp LookupLoop
300
301 /* Accept the current string, with the maximum possible length. */
302
303 LenMaximum: movl deflatestate(%esp), %edx
304 movl $MAX_MATCH, bestlen(%esp)
305 movl %ecx, dsMatchStart(%edx)
306
307 /* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
308 /* return s->lookahead; */
309
310 LeaveNow:
311 movl deflatestate(%esp), %edx
312 movl bestlen(%esp), %ebx
313 movl dsLookahead(%edx), %eax
314 cmpl %eax, %ebx
315 jg LookaheadRet
316 movl %ebx, %eax
317 LookaheadRet:
318
319 /* Restore the stack and return from whence we came. */
320
321 addl $LocalVarsSize, %esp
322 popl %ebx
323 popl %esi
324 popl %edi
325 popl %ebp
326 match_init: ret
0 blast: blast.c blast.h
1 cc -DTEST -o blast blast.c
2
3 test: blast
4 blast < test.pk | cmp - test.txt
5
6 clean:
7 rm -f blast blast.o
0 Read blast.h for purpose and usage.
1
2 Mark Adler
3 madler@alumni.caltech.edu
0 /* blast.c
1 * Copyright (C) 2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in blast.h
3 * version 1.1, 16 Feb 2003
4 *
5 * blast.c decompresses data compressed by the PKWare Compression Library.
6 * This function provides functionality similar to the explode() function of
7 * the PKWare library, hence the name "blast".
8 *
9 * This decompressor is based on the excellent format description provided by
10 * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
11 * example Ben provided in the post is incorrect. The distance 110001 should
12 * instead be 111000. When corrected, the example byte stream becomes:
13 *
14 * 00 04 82 24 25 8f 80 7f
15 *
16 * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
17 */
18
19 /*
20 * Change history:
21 *
22 * 1.0 12 Feb 2003 - First version
23 * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
24 */
25
26 #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
27 #include "blast.h" /* prototype for blast() */
28
29 #define local static /* for local function definitions */
30 #define MAXBITS 13 /* maximum code length */
31 #define MAXWIN 4096 /* maximum window size */
32
33 /* input and output state */
34 struct state {
35 /* input state */
36 blast_in infun; /* input function provided by user */
37 void *inhow; /* opaque information passed to infun() */
38 unsigned char *in; /* next input location */
39 unsigned left; /* available input at in */
40 int bitbuf; /* bit buffer */
41 int bitcnt; /* number of bits in bit buffer */
42
43 /* input limit error return state for bits() and decode() */
44 jmp_buf env;
45
46 /* output state */
47 blast_out outfun; /* output function provided by user */
48 void *outhow; /* opaque information passed to outfun() */
49 unsigned next; /* index of next write location in out[] */
50 int first; /* true to check distances (for first 4K) */
51 unsigned char out[MAXWIN]; /* output buffer and sliding window */
52 };
53
54 /*
55 * Return need bits from the input stream. This always leaves less than
56 * eight bits in the buffer. bits() works properly for need == 0.
57 *
58 * Format notes:
59 *
60 * - Bits are stored in bytes from the least significant bit to the most
61 * significant bit. Therefore bits are dropped from the bottom of the bit
62 * buffer, using shift right, and new bytes are appended to the top of the
63 * bit buffer, using shift left.
64 */
65 local int bits(struct state *s, int need)
66 {
67 int val; /* bit accumulator */
68
69 /* load at least need bits into val */
70 val = s->bitbuf;
71 while (s->bitcnt < need) {
72 if (s->left == 0) {
73 s->left = s->infun(s->inhow, &(s->in));
74 if (s->left == 0) longjmp(s->env, 1); /* out of input */
75 }
76 val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
77 s->left--;
78 s->bitcnt += 8;
79 }
80
81 /* drop need bits and update buffer, always zero to seven bits left */
82 s->bitbuf = val >> need;
83 s->bitcnt -= need;
84
85 /* return need bits, zeroing the bits above that */
86 return val & ((1 << need) - 1);
87 }
88
89 /*
90 * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
91 * each length, which for a canonical code are stepped through in order.
92 * symbol[] are the symbol values in canonical order, where the number of
93 * entries is the sum of the counts in count[]. The decoding process can be
94 * seen in the function decode() below.
95 */
96 struct huffman {
97 short *count; /* number of symbols of each length */
98 short *symbol; /* canonically ordered symbols */
99 };
100
101 /*
102 * Decode a code from the stream s using huffman table h. Return the symbol or
103 * a negative value if there is an error. If all of the lengths are zero, i.e.
104 * an empty code, or if the code is incomplete and an invalid code is received,
105 * then -9 is returned after reading MAXBITS bits.
106 *
107 * Format notes:
108 *
109 * - The codes as stored in the compressed data are bit-reversed relative to
110 * a simple integer ordering of codes of the same lengths. Hence below the
111 * bits are pulled from the compressed data one at a time and used to
112 * build the code value reversed from what is in the stream in order to
113 * permit simple integer comparisons for decoding.
114 *
115 * - The first code for the shortest length is all ones. Subsequent codes of
116 * the same length are simply integer decrements of the previous code. When
117 * moving up a length, a one bit is appended to the code. For a complete
118 * code, the last code of the longest length will be all zeros. To support
119 * this ordering, the bits pulled during decoding are inverted to apply the
120 * more "natural" ordering starting with all zeros and incrementing.
121 */
122 local int decode(struct state *s, struct huffman *h)
123 {
124 int len; /* current number of bits in code */
125 int code; /* len bits being decoded */
126 int first; /* first code of length len */
127 int count; /* number of codes of length len */
128 int index; /* index of first code of length len in symbol table */
129 int bitbuf; /* bits from stream */
130 int left; /* bits left in next or left to process */
131 short *next; /* next number of codes */
132
133 bitbuf = s->bitbuf;
134 left = s->bitcnt;
135 code = first = index = 0;
136 len = 1;
137 next = h->count + 1;
138 while (1) {
139 while (left--) {
140 code |= (bitbuf & 1) ^ 1; /* invert code */
141 bitbuf >>= 1;
142 count = *next++;
143 if (code < first + count) { /* if length len, return symbol */
144 s->bitbuf = bitbuf;
145 s->bitcnt = (s->bitcnt - len) & 7;
146 return h->symbol[index + (code - first)];
147 }
148 index += count; /* else update for next length */
149 first += count;
150 first <<= 1;
151 code <<= 1;
152 len++;
153 }
154 left = (MAXBITS+1) - len;
155 if (left == 0) break;
156 if (s->left == 0) {
157 s->left = s->infun(s->inhow, &(s->in));
158 if (s->left == 0) longjmp(s->env, 1); /* out of input */
159 }
160 bitbuf = *(s->in)++;
161 s->left--;
162 if (left > 8) left = 8;
163 }
164 return -9; /* ran out of codes */
165 }
166
167 /*
168 * Given a list of repeated code lengths rep[0..n-1], where each byte is a
169 * count (high four bits + 1) and a code length (low four bits), generate the
170 * list of code lengths. This compaction reduces the size of the object code.
171 * Then given the list of code lengths length[0..n-1] representing a canonical
172 * Huffman code for n symbols, construct the tables required to decode those
173 * codes. Those tables are the number of codes of each length, and the symbols
174 * sorted by length, retaining their original order within each length. The
175 * return value is zero for a complete code set, negative for an over-
176 * subscribed code set, and positive for an incomplete code set. The tables
177 * can be used if the return value is zero or positive, but they cannot be used
178 * if the return value is negative. If the return value is zero, it is not
179 * possible for decode() using that table to return an error--any stream of
180 * enough bits will resolve to a symbol. If the return value is positive, then
181 * it is possible for decode() using that table to return an error for received
182 * codes past the end of the incomplete lengths.
183 */
184 local int construct(struct huffman *h, const unsigned char *rep, int n)
185 {
186 int symbol; /* current symbol when stepping through length[] */
187 int len; /* current length when stepping through h->count[] */
188 int left; /* number of possible codes left of current length */
189 short offs[MAXBITS+1]; /* offsets in symbol table for each length */
190 short length[256]; /* code lengths */
191
192 /* convert compact repeat counts into symbol bit length list */
193 symbol = 0;
194 do {
195 len = *rep++;
196 left = (len >> 4) + 1;
197 len &= 15;
198 do {
199 length[symbol++] = len;
200 } while (--left);
201 } while (--n);
202 n = symbol;
203
204 /* count number of codes of each length */
205 for (len = 0; len <= MAXBITS; len++)
206 h->count[len] = 0;
207 for (symbol = 0; symbol < n; symbol++)
208 (h->count[length[symbol]])++; /* assumes lengths are within bounds */
209 if (h->count[0] == n) /* no codes! */
210 return 0; /* complete, but decode() will fail */
211
212 /* check for an over-subscribed or incomplete set of lengths */
213 left = 1; /* one possible code of zero length */
214 for (len = 1; len <= MAXBITS; len++) {
215 left <<= 1; /* one more bit, double codes left */
216 left -= h->count[len]; /* deduct count from possible codes */
217 if (left < 0) return left; /* over-subscribed--return negative */
218 } /* left > 0 means incomplete */
219
220 /* generate offsets into symbol table for each length for sorting */
221 offs[1] = 0;
222 for (len = 1; len < MAXBITS; len++)
223 offs[len + 1] = offs[len] + h->count[len];
224
225 /*
226 * put symbols in table sorted by length, by symbol order within each
227 * length
228 */
229 for (symbol = 0; symbol < n; symbol++)
230 if (length[symbol] != 0)
231 h->symbol[offs[length[symbol]]++] = symbol;
232
233 /* return zero for complete set, positive for incomplete set */
234 return left;
235 }
236
237 /*
238 * Decode PKWare Compression Library stream.
239 *
240 * Format notes:
241 *
242 * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
243 * byte is 4, 5, or 6 for the number of extra bits in the distance code.
244 * This is the base-2 logarithm of the dictionary size minus six.
245 *
246 * - Compressed data is a combination of literals and length/distance pairs
247 * terminated by an end code. Literals are either Huffman coded or
248 * uncoded bytes. A length/distance pair is a coded length followed by a
249 * coded distance to represent a string that occurs earlier in the
250 * uncompressed data that occurs again at the current location.
251 *
252 * - A bit preceding a literal or length/distance pair indicates which comes
253 * next, 0 for literals, 1 for length/distance.
254 *
255 * - If literals are uncoded, then the next eight bits are the literal, in the
256 * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly,
257 * no bit reversal is needed for either the length extra bits or the distance
258 * extra bits.
259 *
260 * - Literal bytes are simply written to the output. A length/distance pair is
261 * an instruction to copy previously uncompressed bytes to the output. The
262 * copy is from distance bytes back in the output stream, copying for length
263 * bytes.
264 *
265 * - Distances pointing before the beginning of the output data are not
266 * permitted.
267 *
268 * - Overlapped copies, where the length is greater than the distance, are
269 * allowed and common. For example, a distance of one and a length of 518
270 * simply copies the last byte 518 times. A distance of four and a length of
271 * twelve copies the last four bytes three times. A simple forward copy
272 * ignoring whether the length is greater than the distance or not implements
273 * this correctly.
274 */
275 local int decomp(struct state *s)
276 {
277 int lit; /* true if literals are coded */
278 int dict; /* log2(dictionary size) - 6 */
279 int symbol; /* decoded symbol, extra bits for distance */
280 int len; /* length for copy */
281 int dist; /* distance for copy */
282 int copy; /* copy counter */
283 unsigned char *from, *to; /* copy pointers */
284 static int virgin = 1; /* build tables once */
285 static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
286 static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
287 static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
288 static struct huffman litcode = {litcnt, litsym}; /* length code */
289 static struct huffman lencode = {lencnt, lensym}; /* length code */
290 static struct huffman distcode = {distcnt, distsym};/* distance code */
291 /* bit lengths of literal codes */
292 static const unsigned char litlen[] = {
293 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
294 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
295 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
296 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
297 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
298 44, 173};
299 /* bit lengths of length codes 0..15 */
300 static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
301 /* bit lengths of distance codes 0..63 */
302 static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
303 static const short base[16] = { /* base for length codes */
304 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
305 static const char extra[16] = { /* extra bits for length codes */
306 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
307
308 /* set up decoding tables (once--might not be thread-safe) */
309 if (virgin) {
310 construct(&litcode, litlen, sizeof(litlen));
311 construct(&lencode, lenlen, sizeof(lenlen));
312 construct(&distcode, distlen, sizeof(distlen));
313 virgin = 0;
314 }
315
316 /* read header */
317 lit = bits(s, 8);
318 if (lit > 1) return -1;
319 dict = bits(s, 8);
320 if (dict < 4 || dict > 6) return -2;
321
322 /* decode literals and length/distance pairs */
323 do {
324 if (bits(s, 1)) {
325 /* get length */
326 symbol = decode(s, &lencode);
327 len = base[symbol] + bits(s, extra[symbol]);
328 if (len == 519) break; /* end code */
329
330 /* get distance */
331 symbol = len == 2 ? 2 : dict;
332 dist = decode(s, &distcode) << symbol;
333 dist += bits(s, symbol);
334 dist++;
335 if (s->first && dist > s->next)
336 return -3; /* distance too far back */
337
338 /* copy length bytes from distance bytes back */
339 do {
340 to = s->out + s->next;
341 from = to - dist;
342 copy = MAXWIN;
343 if (s->next < dist) {
344 from += copy;
345 copy = dist;
346 }
347 copy -= s->next;
348 if (copy > len) copy = len;
349 len -= copy;
350 s->next += copy;
351 do {
352 *to++ = *from++;
353 } while (--copy);
354 if (s->next == MAXWIN) {
355 if (s->outfun(s->outhow, s->out, s->next)) return 1;
356 s->next = 0;
357 s->first = 0;
358 }
359 } while (len != 0);
360 }
361 else {
362 /* get literal and write it */
363 symbol = lit ? decode(s, &litcode) : bits(s, 8);
364 s->out[s->next++] = symbol;
365 if (s->next == MAXWIN) {
366 if (s->outfun(s->outhow, s->out, s->next)) return 1;
367 s->next = 0;
368 s->first = 0;
369 }
370 }
371 } while (1);
372 return 0;
373 }
374
375 /* See comments in blast.h */
376 int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow)
377 {
378 struct state s; /* input/output state */
379 int err; /* return value */
380
381 /* initialize input state */
382 s.infun = infun;
383 s.inhow = inhow;
384 s.left = 0;
385 s.bitbuf = 0;
386 s.bitcnt = 0;
387
388 /* initialize output state */
389 s.outfun = outfun;
390 s.outhow = outhow;
391 s.next = 0;
392 s.first = 1;
393
394 /* return if bits() or decode() tries to read past available input */
395 if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
396 err = 2; /* then skip decomp(), return error */
397 else
398 err = decomp(&s); /* decompress */
399
400 /* write any leftover output and update the error code if needed */
401 if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
402 err = 1;
403 return err;
404 }
405
406 #ifdef TEST
407 /* Example of how to use blast() */
408 #include <stdio.h>
409 #include <stdlib.h>
410
411 #define CHUNK 16384
412
413 local unsigned inf(void *how, unsigned char **buf)
414 {
415 static unsigned char hold[CHUNK];
416
417 *buf = hold;
418 return fread(hold, 1, CHUNK, (FILE *)how);
419 }
420
421 local int outf(void *how, unsigned char *buf, unsigned len)
422 {
423 return fwrite(buf, 1, len, (FILE *)how) != len;
424 }
425
426 /* Decompress a PKWare Compression Library stream from stdin to stdout */
427 int main(void)
428 {
429 int ret, n;
430
431 /* decompress to stdout */
432 ret = blast(inf, stdin, outf, stdout);
433 if (ret != 0) fprintf(stderr, "blast error: %d\n", ret);
434
435 /* see if there are any leftover bytes */
436 n = 0;
437 while (getchar() != EOF) n++;
438 if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n);
439
440 /* return blast() error code */
441 return ret;
442 }
443 #endif
0 /* blast.h -- interface for blast.c
1 Copyright (C) 2003 Mark Adler
2 version 1.1, 16 Feb 2003
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the author be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Mark Adler madler@alumni.caltech.edu
21 */
22
23
24 /*
25 * blast() decompresses the PKWare Data Compression Library (DCL) compressed
26 * format. It provides the same functionality as the explode() function in
27 * that library. (Note: PKWare overused the "implode" verb, and the format
28 * used by their library implode() function is completely different and
29 * incompatible with the implode compression method supported by PKZIP.)
30 */
31
32
33 typedef unsigned (*blast_in)(void *how, unsigned char **buf);
34 typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
35 /* Definitions for input/output functions passed to blast(). See below for
36 * what the provided functions need to do.
37 */
38
39
40 int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow);
41 /* Decompress input to output using the provided infun() and outfun() calls.
42 * On success, the return value of blast() is zero. If there is an error in
43 * the source data, i.e. it is not in the proper format, then a negative value
44 * is returned. If there is not enough input available or there is not enough
45 * output space, then a positive error is returned.
46 *
47 * The input function is invoked: len = infun(how, &buf), where buf is set by
48 * infun() to point to the input buffer, and infun() returns the number of
49 * available bytes there. If infun() returns zero, then blast() returns with
50 * an input error. (blast() only asks for input if it needs it.) inhow is for
51 * use by the application to pass an input descriptor to infun(), if desired.
52 *
53 * The output function is invoked: err = outfun(how, buf, len), where the bytes
54 * to be written are buf[0..len-1]. If err is not zero, then blast() returns
55 * with an output error. outfun() is always called with len <= 4096. outhow
56 * is for use by the application to pass an output descriptor to outfun(), if
57 * desired.
58 *
59 * The return codes are:
60 *
61 * 2: ran out of input before completing decompression
62 * 1: output error before completing decompression
63 * 0: successful decompression
64 * -1: literal flag not zero or one
65 * -2: dictionary size not in 4..6
66 * -3: distance is too far back
67 *
68 * At the bottom of blast.c is an example program that uses blast() that can be
69 * compiled to produce a command-line decompression filter by defining TEST.
70 */
0 {*******************************************************}
1 { }
2 { Borland Delphi Supplemental Components }
3 { ZLIB Data Compression Interface Unit }
4 { }
5 { Copyright (c) 1997,99 Borland Corporation }
6 { }
7 {*******************************************************}
8
9 { Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }
10
11 unit ZLib;
12
13 interface
14
15 uses SysUtils, Classes;
16
17 type
18 TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
19 TFree = procedure (AppData, Block: Pointer); cdecl;
20
21 // Internal structure. Ignore.
22 TZStreamRec = packed record
23 next_in: PChar; // next input byte
24 avail_in: Integer; // number of bytes available at next_in
25 total_in: Longint; // total nb of input bytes read so far
26
27 next_out: PChar; // next output byte should be put here
28 avail_out: Integer; // remaining free space at next_out
29 total_out: Longint; // total nb of bytes output so far
30
31 msg: PChar; // last error message, NULL if no error
32 internal: Pointer; // not visible by applications
33
34 zalloc: TAlloc; // used to allocate the internal state
35 zfree: TFree; // used to free the internal state
36 AppData: Pointer; // private data object passed to zalloc and zfree
37
38 data_type: Integer; // best guess about the data type: ascii or binary
39 adler: Longint; // adler32 value of the uncompressed data
40 reserved: Longint; // reserved for future use
41 end;
42
43 // Abstract ancestor class
44 TCustomZlibStream = class(TStream)
45 private
46 FStrm: TStream;
47 FStrmPos: Integer;
48 FOnProgress: TNotifyEvent;
49 FZRec: TZStreamRec;
50 FBuffer: array [Word] of Char;
51 protected
52 procedure Progress(Sender: TObject); dynamic;
53 property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
54 constructor Create(Strm: TStream);
55 end;
56
57 { TCompressionStream compresses data on the fly as data is written to it, and
58 stores the compressed data to another stream.
59
60 TCompressionStream is write-only and strictly sequential. Reading from the
61 stream will raise an exception. Using Seek to move the stream pointer
62 will raise an exception.
63
64 Output data is cached internally, written to the output stream only when
65 the internal output buffer is full. All pending output data is flushed
66 when the stream is destroyed.
67
68 The Position property returns the number of uncompressed bytes of
69 data that have been written to the stream so far.
70
71 CompressionRate returns the on-the-fly percentage by which the original
72 data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
73 If raw data size = 100 and compressed data size = 25, the CompressionRate
74 is 75%
75
76 The OnProgress event is called each time the output buffer is filled and
77 written to the output stream. This is useful for updating a progress
78 indicator when you are writing a large chunk of data to the compression
79 stream in a single call.}
80
81
82 TCompressionLevel = (clNone, clFastest, clDefault, clMax);
83
84 TCompressionStream = class(TCustomZlibStream)
85 private
86 function GetCompressionRate: Single;
87 public
88 constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
89 destructor Destroy; override;
90 function Read(var Buffer; Count: Longint): Longint; override;
91 function Write(const Buffer; Count: Longint): Longint; override;
92 function Seek(Offset: Longint; Origin: Word): Longint; override;
93 property CompressionRate: Single read GetCompressionRate;
94 property OnProgress;
95 end;
96
97 { TDecompressionStream decompresses data on the fly as data is read from it.
98
99 Compressed data comes from a separate source stream. TDecompressionStream
100 is read-only and unidirectional; you can seek forward in the stream, but not
101 backwards. The special case of setting the stream position to zero is
102 allowed. Seeking forward decompresses data until the requested position in
103 the uncompressed data has been reached. Seeking backwards, seeking relative
104 to the end of the stream, requesting the size of the stream, and writing to
105 the stream will raise an exception.
106
107 The Position property returns the number of bytes of uncompressed data that
108 have been read from the stream so far.
109
110 The OnProgress event is called each time the internal input buffer of
111 compressed data is exhausted and the next block is read from the input stream.
112 This is useful for updating a progress indicator when you are reading a
113 large chunk of data from the decompression stream in a single call.}
114
115 TDecompressionStream = class(TCustomZlibStream)
116 public
117 constructor Create(Source: TStream);
118 destructor Destroy; override;
119 function Read(var Buffer; Count: Longint): Longint; override;
120 function Write(const Buffer; Count: Longint): Longint; override;
121 function Seek(Offset: Longint; Origin: Word): Longint; override;
122 property OnProgress;
123 end;
124
125
126
127 { CompressBuf compresses data, buffer to buffer, in one call.
128 In: InBuf = ptr to compressed data
129 InBytes = number of bytes in InBuf
130 Out: OutBuf = ptr to newly allocated buffer containing decompressed data
131 OutBytes = number of bytes in OutBuf }
132 procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
133 out OutBuf: Pointer; out OutBytes: Integer);
134
135
136 { DecompressBuf decompresses data, buffer to buffer, in one call.
137 In: InBuf = ptr to compressed data
138 InBytes = number of bytes in InBuf
139 OutEstimate = zero, or est. size of the decompressed data
140 Out: OutBuf = ptr to newly allocated buffer containing decompressed data
141 OutBytes = number of bytes in OutBuf }
142 procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
143 OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
144
145 { DecompressToUserBuf decompresses data, buffer to buffer, in one call.
146 In: InBuf = ptr to compressed data
147 InBytes = number of bytes in InBuf
148 Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
149 BufSize = number of bytes in OutBuf }
150 procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
151 const OutBuf: Pointer; BufSize: Integer);
152
153 const
154 zlib_version = '1.2.2';
155
156 type
157 EZlibError = class(Exception);
158 ECompressionError = class(EZlibError);
159 EDecompressionError = class(EZlibError);
160
161 implementation
162
163 uses ZLibConst;
164
165 const
166 Z_NO_FLUSH = 0;
167 Z_PARTIAL_FLUSH = 1;
168 Z_SYNC_FLUSH = 2;
169 Z_FULL_FLUSH = 3;
170 Z_FINISH = 4;
171
172 Z_OK = 0;
173 Z_STREAM_END = 1;
174 Z_NEED_DICT = 2;
175 Z_ERRNO = (-1);
176 Z_STREAM_ERROR = (-2);
177 Z_DATA_ERROR = (-3);
178 Z_MEM_ERROR = (-4);
179 Z_BUF_ERROR = (-5);
180 Z_VERSION_ERROR = (-6);
181
182 Z_NO_COMPRESSION = 0;
183 Z_BEST_SPEED = 1;
184 Z_BEST_COMPRESSION = 9;
185 Z_DEFAULT_COMPRESSION = (-1);
186
187 Z_FILTERED = 1;
188 Z_HUFFMAN_ONLY = 2;
189 Z_RLE = 3;
190 Z_DEFAULT_STRATEGY = 0;
191
192 Z_BINARY = 0;
193 Z_ASCII = 1;
194 Z_UNKNOWN = 2;
195
196 Z_DEFLATED = 8;
197
198
199 {$L adler32.obj}
200 {$L compress.obj}
201 {$L crc32.obj}
202 {$L deflate.obj}
203 {$L infback.obj}
204 {$L inffast.obj}
205 {$L inflate.obj}
206 {$L inftrees.obj}
207 {$L trees.obj}
208 {$L uncompr.obj}
209 {$L zutil.obj}
210
211 procedure adler32; external;
212 procedure compressBound; external;
213 procedure crc32; external;
214 procedure deflateInit2_; external;
215 procedure deflateParams; external;
216
217 function _malloc(Size: Integer): Pointer; cdecl;
218 begin
219 Result := AllocMem(Size);
220 end;
221
222 procedure _free(Block: Pointer); cdecl;
223 begin
224 FreeMem(Block);
225 end;
226
227 procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
228 begin
229 FillChar(P^, count, B);
230 end;
231
232 procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
233 begin
234 Move(source^, dest^, count);
235 end;
236
237
238
239 // deflate compresses data
240 function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
241 recsize: Integer): Integer; external;
242 function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
243 function deflateEnd(var strm: TZStreamRec): Integer; external;
244
245 // inflate decompresses data
246 function inflateInit_(var strm: TZStreamRec; version: PChar;
247 recsize: Integer): Integer; external;
248 function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
249 function inflateEnd(var strm: TZStreamRec): Integer; external;
250 function inflateReset(var strm: TZStreamRec): Integer; external;
251
252
253 function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
254 begin
255 // GetMem(Result, Items*Size);
256 Result := AllocMem(Items * Size);
257 end;
258
259 procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
260 begin
261 FreeMem(Block);
262 end;
263
264 {function zlibCheck(code: Integer): Integer;
265 begin
266 Result := code;
267 if code < 0 then
268 raise EZlibError.Create('error'); //!!
269 end;}
270
271 function CCheck(code: Integer): Integer;
272 begin
273 Result := code;
274 if code < 0 then
275 raise ECompressionError.Create('error'); //!!
276 end;
277
278 function DCheck(code: Integer): Integer;
279 begin
280 Result := code;
281 if code < 0 then
282 raise EDecompressionError.Create('error'); //!!
283 end;
284
285 procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
286 out OutBuf: Pointer; out OutBytes: Integer);
287 var
288 strm: TZStreamRec;
289 P: Pointer;
290 begin
291 FillChar(strm, sizeof(strm), 0);
292 strm.zalloc := zlibAllocMem;
293 strm.zfree := zlibFreeMem;
294 OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
295 GetMem(OutBuf, OutBytes);
296 try
297 strm.next_in := InBuf;
298 strm.avail_in := InBytes;
299 strm.next_out := OutBuf;
300 strm.avail_out := OutBytes;
301 CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
302 try
303 while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
304 begin
305 P := OutBuf;
306 Inc(OutBytes, 256);
307 ReallocMem(OutBuf, OutBytes);
308 strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
309 strm.avail_out := 256;
310 end;
311 finally
312 CCheck(deflateEnd(strm));
313 end;
314 ReallocMem(OutBuf, strm.total_out);
315 OutBytes := strm.total_out;
316 except
317 FreeMem(OutBuf);
318 raise
319 end;
320 end;
321
322
323 procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
324 OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
325 var
326 strm: TZStreamRec;
327 P: Pointer;
328 BufInc: Integer;
329 begin
330 FillChar(strm, sizeof(strm), 0);
331 strm.zalloc := zlibAllocMem;
332 strm.zfree := zlibFreeMem;
333 BufInc := (InBytes + 255) and not 255;
334 if OutEstimate = 0 then
335 OutBytes := BufInc
336 else
337 OutBytes := OutEstimate;
338 GetMem(OutBuf, OutBytes);
339 try
340 strm.next_in := InBuf;
341 strm.avail_in := InBytes;
342 strm.next_out := OutBuf;
343 strm.avail_out := OutBytes;
344 DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
345 try
346 while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
347 begin
348 P := OutBuf;
349 Inc(OutBytes, BufInc);
350 ReallocMem(OutBuf, OutBytes);
351 strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
352 strm.avail_out := BufInc;
353 end;
354 finally
355 DCheck(inflateEnd(strm));
356 end;
357 ReallocMem(OutBuf, strm.total_out);
358 OutBytes := strm.total_out;
359 except
360 FreeMem(OutBuf);
361 raise
362 end;
363 end;
364
365 procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
366 const OutBuf: Pointer; BufSize: Integer);
367 var
368 strm: TZStreamRec;
369 begin
370 FillChar(strm, sizeof(strm), 0);
371 strm.zalloc := zlibAllocMem;
372 strm.zfree := zlibFreeMem;
373 strm.next_in := InBuf;
374 strm.avail_in := InBytes;
375 strm.next_out := OutBuf;
376 strm.avail_out := BufSize;
377 DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
378 try
379 if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
380 raise EZlibError.CreateRes(@sTargetBufferTooSmall);
381 finally
382 DCheck(inflateEnd(strm));
383 end;
384 end;
385
386 // TCustomZlibStream
387
388 constructor TCustomZLibStream.Create(Strm: TStream);
389 begin
390 inherited Create;
391 FStrm := Strm;
392 FStrmPos := Strm.Position;
393 FZRec.zalloc := zlibAllocMem;
394 FZRec.zfree := zlibFreeMem;
395 end;
396
397 procedure TCustomZLibStream.Progress(Sender: TObject);
398 begin
399 if Assigned(FOnProgress) then FOnProgress(Sender);
400 end;
401
402
403 // TCompressionStream
404
405 constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
406 Dest: TStream);
407 const
408 Levels: array [TCompressionLevel] of ShortInt =
409 (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
410 begin
411 inherited Create(Dest);
412 FZRec.next_out := FBuffer;
413 FZRec.avail_out := sizeof(FBuffer);
414 CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
415 end;
416
417 destructor TCompressionStream.Destroy;
418 begin
419 FZRec.next_in := nil;
420 FZRec.avail_in := 0;
421 try
422 if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
423 while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
424 and (FZRec.avail_out = 0) do
425 begin
426 FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
427 FZRec.next_out := FBuffer;
428 FZRec.avail_out := sizeof(FBuffer);
429 end;
430 if FZRec.avail_out < sizeof(FBuffer) then
431 FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
432 finally
433 deflateEnd(FZRec);
434 end;
435 inherited Destroy;
436 end;
437
438 function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
439 begin
440 raise ECompressionError.CreateRes(@sInvalidStreamOp);
441 end;
442
443 function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
444 begin
445 FZRec.next_in := @Buffer;
446 FZRec.avail_in := Count;
447 if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
448 while (FZRec.avail_in > 0) do
449 begin
450 CCheck(deflate(FZRec, 0));
451 if FZRec.avail_out = 0 then
452 begin
453 FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
454 FZRec.next_out := FBuffer;
455 FZRec.avail_out := sizeof(FBuffer);
456 FStrmPos := FStrm.Position;
457 Progress(Self);
458 end;
459 end;
460 Result := Count;
461 end;
462
463 function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
464 begin
465 if (Offset = 0) and (Origin = soFromCurrent) then
466 Result := FZRec.total_in
467 else
468 raise ECompressionError.CreateRes(@sInvalidStreamOp);
469 end;
470
471 function TCompressionStream.GetCompressionRate: Single;
472 begin
473 if FZRec.total_in = 0 then
474 Result := 0
475 else
476 Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
477 end;
478
479
480 // TDecompressionStream
481
482 constructor TDecompressionStream.Create(Source: TStream);
483 begin
484 inherited Create(Source);
485 FZRec.next_in := FBuffer;
486 FZRec.avail_in := 0;
487 DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
488 end;
489
490 destructor TDecompressionStream.Destroy;
491 begin
492 FStrm.Seek(-FZRec.avail_in, 1);
493 inflateEnd(FZRec);
494 inherited Destroy;
495 end;
496
497 function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
498 begin
499 FZRec.next_out := @Buffer;
500 FZRec.avail_out := Count;
501 if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
502 while (FZRec.avail_out > 0) do
503 begin
504 if FZRec.avail_in = 0 then
505 begin
506 FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
507 if FZRec.avail_in = 0 then
508 begin
509 Result := Count - FZRec.avail_out;
510 Exit;
511 end;
512 FZRec.next_in := FBuffer;
513 FStrmPos := FStrm.Position;
514 Progress(Self);
515 end;
516 CCheck(inflate(FZRec, 0));
517 end;
518 Result := Count;
519 end;
520
521 function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
522 begin
523 raise EDecompressionError.CreateRes(@sInvalidStreamOp);
524 end;
525
526 function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
527 var
528 I: Integer;
529 Buf: array [0..4095] of Char;
530 begin
531 if (Offset = 0) and (Origin = soFromBeginning) then
532 begin
533 DCheck(inflateReset(FZRec));
534 FZRec.next_in := FBuffer;
535 FZRec.avail_in := 0;
536 FStrm.Position := 0;
537 FStrmPos := 0;
538 end
539 else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
540 ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
541 begin
542 if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
543 if Offset > 0 then
544 begin
545 for I := 1 to Offset div sizeof(Buf) do
546 ReadBuffer(Buf, sizeof(Buf));
547 ReadBuffer(Buf, Offset mod sizeof(Buf));
548 end;
549 end
550 else
551 raise EDecompressionError.CreateRes(@sInvalidStreamOp);
552 Result := FZRec.total_out;
553 end;
554
555
556 end.
0 unit ZLibConst;
1
2 interface
3
4 resourcestring
5 sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
6 sInvalidStreamOp = 'Invalid stream operation';
7
8 implementation
9
10 end.
0
1 Overview
2 ========
3
4 This directory contains an update to the ZLib interface unit,
5 distributed by Borland as a Delphi supplemental component.
6
7 The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
8 and is based on zlib version 1.0.4. There are a series of bugs
9 and security problems associated with that old zlib version, and
10 we recommend the users to update their ZLib unit.
11
12
13 Summary of modifications
14 ========================
15
16 - Improved makefile, adapted to zlib version 1.2.1.
17
18 - Some field types from TZStreamRec are changed from Integer to
19 Longint, for consistency with the zlib.h header, and for 64-bit
20 readiness.
21
22 - The zlib_version constant is updated.
23
24 - The new Z_RLE strategy has its corresponding symbolic constant.
25
26 - The allocation and deallocation functions and function types
27 (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
28 and _malloc and _free are added as C RTL stubs. As a result,
29 the original C sources of zlib can be compiled out of the box,
30 and linked to the ZLib unit.
31
32
33 Suggestions for improvements
34 ============================
35
36 Currently, the ZLib unit provides only a limited wrapper around
37 the zlib library, and much of the original zlib functionality is
38 missing. Handling compressed file formats like ZIP/GZIP or PNG
39 cannot be implemented without having this functionality.
40 Applications that handle these formats are either using their own,
41 duplicated code, or not using the ZLib unit at all.
42
43 Here are a few suggestions:
44
45 - Checksum class wrappers around adler32() and crc32(), similar
46 to the Java classes that implement the java.util.zip.Checksum
47 interface.
48
49 - The ability to read and write raw deflate streams, without the
50 zlib stream header and trailer. Raw deflate streams are used
51 in the ZIP file format.
52
53 - The ability to read and write gzip streams, used in the GZIP
54 file format, and normally produced by the gzip program.
55
56 - The ability to select a different compression strategy, useful
57 to PNG and MNG image compression, and to multimedia compression
58 in general. Besides the compression level
59
60 TCompressionLevel = (clNone, clFastest, clDefault, clMax);
61
62 which, in fact, could have used the 'z' prefix and avoided
63 TColor-like symbols
64
65 TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
66
67 there could be a compression strategy
68
69 TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
70
71 - ZIP and GZIP stream handling via TStreams.
72
73
74 --
75 Cosmin Truta <cosmint@cs.ubbcluj.ro>
0 # Makefile for zlib
1 # For use with Delphi and C++ Builder under Win32
2 # Updated for zlib 1.2.x by Cosmin Truta
3
4 # ------------ Borland C++ ------------
5
6 # This project uses the Delphi (fastcall/register) calling convention:
7 LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
8
9 CC = bcc32
10 LD = bcc32
11 AR = tlib
12 # do not use "-pr" in CFLAGS
13 CFLAGS = -a -d -k- -O2 $(LOC)
14 LDFLAGS =
15
16
17 # variables
18 ZLIB_LIB = zlib.lib
19
20 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
21 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
22 OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
23 OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
24
25
26 # targets
27 all: $(ZLIB_LIB) example.exe minigzip.exe
28
29 .c.obj:
30 $(CC) -c $(CFLAGS) $*.c
31
32 adler32.obj: adler32.c zlib.h zconf.h
33
34 compress.obj: compress.c zlib.h zconf.h
35
36 crc32.obj: crc32.c zlib.h zconf.h crc32.h
37
38 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
39
40 gzio.obj: gzio.c zutil.h zlib.h zconf.h
41
42 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
43 inffast.h inffixed.h
44
45 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
46 inffast.h
47
48 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
49 inffast.h inffixed.h
50
51 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
52
53 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
54
55 uncompr.obj: uncompr.c zlib.h zconf.h
56
57 zutil.obj: zutil.c zutil.h zlib.h zconf.h
58
59 example.obj: example.c zlib.h zconf.h
60
61 minigzip.obj: minigzip.c zlib.h zconf.h
62
63
64 # For the sake of the old Borland make,
65 # the command line is cut to fit in the MS-DOS 128 byte limit:
66 $(ZLIB_LIB): $(OBJ1) $(OBJ2)
67 -del $(ZLIB_LIB)
68 $(AR) $(ZLIB_LIB) $(OBJP1)
69 $(AR) $(ZLIB_LIB) $(OBJP2)
70
71
72 # testing
73 test: example.exe minigzip.exe
74 example
75 echo hello world | minigzip | minigzip -d
76
77 example.exe: example.obj $(ZLIB_LIB)
78 $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
79
80 minigzip.exe: minigzip.obj $(ZLIB_LIB)
81 $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
82
83
84 # cleanup
85 clean:
86 -del *.obj
87 -del *.exe
88 -del *.lib
89 -del *.tds
90 -del zlib.bak
91 -del foo.gz
92
0 using System.Reflection;
1 using System.Runtime.CompilerServices;
2
3 //
4 // General Information about an assembly is controlled through the following
5 // set of attributes. Change these attribute values to modify the information
6 // associated with an assembly.
7 //
8 [assembly: AssemblyTitle("DotZLib")]
9 [assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
10 [assembly: AssemblyConfiguration("")]
11 [assembly: AssemblyCompany("Henrik Ravn")]
12 [assembly: AssemblyProduct("")]
13 [assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
14 [assembly: AssemblyTrademark("")]
15 [assembly: AssemblyCulture("")]
16
17 //
18 // Version information for an assembly consists of the following four values:
19 //
20 // Major Version
21 // Minor Version
22 // Build Number
23 // Revision
24 //
25 // You can specify all the values or you can default the Revision and Build Numbers
26 // by using the '*' as shown below:
27
28 [assembly: AssemblyVersion("1.0.*")]
29
30 //
31 // In order to sign your assembly you must specify a key to use. Refer to the
32 // Microsoft .NET Framework documentation for more information on assembly signing.
33 //
34 // Use the attributes below to control which key is used for signing.
35 //
36 // Notes:
37 // (*) If no key is specified, the assembly is not signed.
38 // (*) KeyName refers to a key that has been installed in the Crypto Service
39 // Provider (CSP) on your machine. KeyFile refers to a file which contains
40 // a key.
41 // (*) If the KeyFile and the KeyName values are both specified, the
42 // following processing occurs:
43 // (1) If the KeyName can be found in the CSP, that key is used.
44 // (2) If the KeyName does not exist and the KeyFile does exist, the key
45 // in the KeyFile is installed into the CSP and used.
46 // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
47 // When specifying the KeyFile, the location of the KeyFile should be
48 // relative to the project output directory which is
49 // %Project Directory%\obj\<configuration>. For example, if your KeyFile is
50 // located in the project directory, you would specify the AssemblyKeyFile
51 // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
52 // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
53 // documentation for more information on this.
54 //
55 [assembly: AssemblyDelaySign(false)]
56 [assembly: AssemblyKeyFile("")]
57 [assembly: AssemblyKeyName("")]
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Runtime.InteropServices;
9 using System.Text;
10
11
12 namespace DotZLib
13 {
14 #region ChecksumGeneratorBase
15 /// <summary>
16 /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
17 /// </summary>
18 /// <example></example>
19 public abstract class ChecksumGeneratorBase : ChecksumGenerator
20 {
21 /// <summary>
22 /// The value of the current checksum
23 /// </summary>
24 protected uint _current;
25
26 /// <summary>
27 /// Initializes a new instance of the checksum generator base - the current checksum is
28 /// set to zero
29 /// </summary>
30 public ChecksumGeneratorBase()
31 {
32 _current = 0;
33 }
34
35 /// <summary>
36 /// Initializes a new instance of the checksum generator basewith a specified value
37 /// </summary>
38 /// <param name="initialValue">The value to set the current checksum to</param>
39 public ChecksumGeneratorBase(uint initialValue)
40 {
41 _current = initialValue;
42 }
43
44 /// <summary>
45 /// Resets the current checksum to zero
46 /// </summary>
47 public void Reset() { _current = 0; }
48
49 /// <summary>
50 /// Gets the current checksum value
51 /// </summary>
52 public uint Value { get { return _current; } }
53
54 /// <summary>
55 /// Updates the current checksum with part of an array of bytes
56 /// </summary>
57 /// <param name="data">The data to update the checksum with</param>
58 /// <param name="offset">Where in <c>data</c> to start updating</param>
59 /// <param name="count">The number of bytes from <c>data</c> to use</param>
60 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
61 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
62 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
63 /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
64 /// This is therefore the only method a derived class has to implement</remarks>
65 public abstract void Update(byte[] data, int offset, int count);
66
67 /// <summary>
68 /// Updates the current checksum with an array of bytes.
69 /// </summary>
70 /// <param name="data">The data to update the checksum with</param>
71 public void Update(byte[] data)
72 {
73 Update(data, 0, data.Length);
74 }
75
76 /// <summary>
77 /// Updates the current checksum with the data from a string
78 /// </summary>
79 /// <param name="data">The string to update the checksum with</param>
80 /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
81 public void Update(string data)
82 {
83 Update(Encoding.UTF8.GetBytes(data));
84 }
85
86 /// <summary>
87 /// Updates the current checksum with the data from a string, using a specific encoding
88 /// </summary>
89 /// <param name="data">The string to update the checksum with</param>
90 /// <param name="encoding">The encoding to use</param>
91 public void Update(string data, Encoding encoding)
92 {
93 Update(encoding.GetBytes(data));
94 }
95
96 }
97 #endregion
98
99 #region CRC32
100 /// <summary>
101 /// Implements a CRC32 checksum generator
102 /// </summary>
103 public sealed class CRC32Checksum : ChecksumGeneratorBase
104 {
105 #region DLL imports
106
107 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
108 private static extern uint crc32(uint crc, int data, uint length);
109
110 #endregion
111
112 /// <summary>
113 /// Initializes a new instance of the CRC32 checksum generator
114 /// </summary>
115 public CRC32Checksum() : base() {}
116
117 /// <summary>
118 /// Initializes a new instance of the CRC32 checksum generator with a specified value
119 /// </summary>
120 /// <param name="initialValue">The value to set the current checksum to</param>
121 public CRC32Checksum(uint initialValue) : base(initialValue) {}
122
123 /// <summary>
124 /// Updates the current checksum with part of an array of bytes
125 /// </summary>
126 /// <param name="data">The data to update the checksum with</param>
127 /// <param name="offset">Where in <c>data</c> to start updating</param>
128 /// <param name="count">The number of bytes from <c>data</c> to use</param>
129 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
130 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
131 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
132 public override void Update(byte[] data, int offset, int count)
133 {
134 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
135 if ((offset+count) > data.Length) throw new ArgumentException();
136 GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
137 try
138 {
139 _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
140 }
141 finally
142 {
143 hData.Free();
144 }
145 }
146
147 }
148 #endregion
149
150 #region Adler
151 /// <summary>
152 /// Implements a checksum generator that computes the Adler checksum on data
153 /// </summary>
154 public sealed class AdlerChecksum : ChecksumGeneratorBase
155 {
156 #region DLL imports
157
158 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
159 private static extern uint adler32(uint adler, int data, uint length);
160
161 #endregion
162
163 /// <summary>
164 /// Initializes a new instance of the Adler checksum generator
165 /// </summary>
166 public AdlerChecksum() : base() {}
167
168 /// <summary>
169 /// Initializes a new instance of the Adler checksum generator with a specified value
170 /// </summary>
171 /// <param name="initialValue">The value to set the current checksum to</param>
172 public AdlerChecksum(uint initialValue) : base(initialValue) {}
173
174 /// <summary>
175 /// Updates the current checksum with part of an array of bytes
176 /// </summary>
177 /// <param name="data">The data to update the checksum with</param>
178 /// <param name="offset">Where in <c>data</c> to start updating</param>
179 /// <param name="count">The number of bytes from <c>data</c> to use</param>
180 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
181 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
182 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
183 public override void Update(byte[] data, int offset, int count)
184 {
185 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
186 if ((offset+count) > data.Length) throw new ArgumentException();
187 GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
188 try
189 {
190 _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
191 }
192 finally
193 {
194 hData.Free();
195 }
196 }
197
198 }
199 #endregion
200
201 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Diagnostics;
9
10 namespace DotZLib
11 {
12
13 /// <summary>
14 /// This class implements a circular buffer
15 /// </summary>
16 internal class CircularBuffer
17 {
18 #region Private data
19 private int _capacity;
20 private int _head;
21 private int _tail;
22 private int _size;
23 private byte[] _buffer;
24 #endregion
25
26 public CircularBuffer(int capacity)
27 {
28 Debug.Assert( capacity > 0 );
29 _buffer = new byte[capacity];
30 _capacity = capacity;
31 _head = 0;
32 _tail = 0;
33 _size = 0;
34 }
35
36 public int Size { get { return _size; } }
37
38 public int Put(byte[] source, int offset, int count)
39 {
40 Debug.Assert( count > 0 );
41 int trueCount = Math.Min(count, _capacity - Size);
42 for (int i = 0; i < trueCount; ++i)
43 _buffer[(_tail+i) % _capacity] = source[offset+i];
44 _tail += trueCount;
45 _tail %= _capacity;
46 _size += trueCount;
47 return trueCount;
48 }
49
50 public bool Put(byte b)
51 {
52 if (Size == _capacity) // no room
53 return false;
54 _buffer[_tail++] = b;
55 _tail %= _capacity;
56 ++_size;
57 return true;
58 }
59
60 public int Get(byte[] destination, int offset, int count)
61 {
62 int trueCount = Math.Min(count,Size);
63 for (int i = 0; i < trueCount; ++i)
64 destination[offset + i] = _buffer[(_head+i) % _capacity];
65 _head += trueCount;
66 _head %= _capacity;
67 _size -= trueCount;
68 return trueCount;
69 }
70
71 public int Get()
72 {
73 if (Size == 0)
74 return -1;
75
76 int result = (int)_buffer[_head++ % _capacity];
77 --_size;
78 return result;
79 }
80
81 }
82 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Runtime.InteropServices;
9
10 namespace DotZLib
11 {
12 /// <summary>
13 /// Implements the common functionality needed for all <see cref="Codec"/>s
14 /// </summary>
15 public abstract class CodecBase : Codec, IDisposable
16 {
17
18 #region Data members
19
20 /// <summary>
21 /// Instance of the internal zlib buffer structure that is
22 /// passed to all functions in the zlib dll
23 /// </summary>
24 internal ZStream _ztream = new ZStream();
25
26 /// <summary>
27 /// True if the object instance has been disposed, false otherwise
28 /// </summary>
29 protected bool _isDisposed = false;
30
31 /// <summary>
32 /// The size of the internal buffers
33 /// </summary>
34 protected const int kBufferSize = 16384;
35
36 private byte[] _outBuffer = new byte[kBufferSize];
37 private byte[] _inBuffer = new byte[kBufferSize];
38
39 private GCHandle _hInput;
40 private GCHandle _hOutput;
41
42 private uint _checksum = 0;
43
44 #endregion
45
46 /// <summary>
47 /// Initializes a new instance of the <c>CodeBase</c> class.
48 /// </summary>
49 public CodecBase()
50 {
51 try
52 {
53 _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
54 _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
55 }
56 catch (Exception)
57 {
58 CleanUp(false);
59 throw;
60 }
61 }
62
63
64 #region Codec Members
65
66 /// <summary>
67 /// Occurs when more processed data are available.
68 /// </summary>
69 public event DataAvailableHandler DataAvailable;
70
71 /// <summary>
72 /// Fires the <see cref="DataAvailable"/> event
73 /// </summary>
74 protected void OnDataAvailable()
75 {
76 if (_ztream.total_out > 0)
77 {
78 if (DataAvailable != null)
79 DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
80 resetOutput();
81 }
82 }
83
84 /// <summary>
85 /// Adds more data to the codec to be processed.
86 /// </summary>
87 /// <param name="data">Byte array containing the data to be added to the codec</param>
88 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
89 public void Add(byte[] data)
90 {
91 Add(data,0,data.Length);
92 }
93
94 /// <summary>
95 /// Adds more data to the codec to be processed.
96 /// </summary>
97 /// <param name="data">Byte array containing the data to be added to the codec</param>
98 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
99 /// <param name="count">The number of bytes to add</param>
100 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
101 /// <remarks>This must be implemented by a derived class</remarks>
102 public abstract void Add(byte[] data, int offset, int count);
103
104 /// <summary>
105 /// Finishes up any pending data that needs to be processed and handled.
106 /// </summary>
107 /// <remarks>This must be implemented by a derived class</remarks>
108 public abstract void Finish();
109
110 /// <summary>
111 /// Gets the checksum of the data that has been added so far
112 /// </summary>
113 public uint Checksum { get { return _checksum; } }
114
115 #endregion
116
117 #region Destructor & IDisposable stuff
118
119 /// <summary>
120 /// Destroys this instance
121 /// </summary>
122 ~CodecBase()
123 {
124 CleanUp(false);
125 }
126
127 /// <summary>
128 /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
129 /// </summary>
130 public void Dispose()
131 {
132 CleanUp(true);
133 }
134
135 /// <summary>
136 /// Performs any codec specific cleanup
137 /// </summary>
138 /// <remarks>This must be implemented by a derived class</remarks>
139 protected abstract void CleanUp();
140
141 // performs the release of the handles and calls the dereived CleanUp()
142 private void CleanUp(bool isDisposing)
143 {
144 if (!_isDisposed)
145 {
146 CleanUp();
147 if (_hInput.IsAllocated)
148 _hInput.Free();
149 if (_hOutput.IsAllocated)
150 _hOutput.Free();
151
152 _isDisposed = true;
153 }
154 }
155
156
157 #endregion
158
159 #region Helper methods
160
161 /// <summary>
162 /// Copies a number of bytes to the internal codec buffer - ready for proccesing
163 /// </summary>
164 /// <param name="data">The byte array that contains the data to copy</param>
165 /// <param name="startIndex">The index of the first byte to copy</param>
166 /// <param name="count">The number of bytes to copy from <c>data</c></param>
167 protected void copyInput(byte[] data, int startIndex, int count)
168 {
169 Array.Copy(data, startIndex, _inBuffer,0, count);
170 _ztream.next_in = _hInput.AddrOfPinnedObject();
171 _ztream.total_in = 0;
172 _ztream.avail_in = (uint)count;
173
174 }
175
176 /// <summary>
177 /// Resets the internal output buffers to a known state - ready for processing
178 /// </summary>
179 protected void resetOutput()
180 {
181 _ztream.total_out = 0;
182 _ztream.avail_out = kBufferSize;
183 _ztream.next_out = _hOutput.AddrOfPinnedObject();
184 }
185
186 /// <summary>
187 /// Updates the running checksum property
188 /// </summary>
189 /// <param name="newSum">The new checksum value</param>
190 protected void setChecksum(uint newSum)
191 {
192 _checksum = newSum;
193 }
194 #endregion
195
196 }
197 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Diagnostics;
9 using System.Runtime.InteropServices;
10
11 namespace DotZLib
12 {
13
14 /// <summary>
15 /// Implements a data compressor, using the deflate algorithm in the ZLib dll
16 /// </summary>
17 public sealed class Deflater : CodecBase
18 {
19 #region Dll imports
20 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
21 private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
22
23 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
24 private static extern int deflate(ref ZStream sz, int flush);
25
26 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
27 private static extern int deflateReset(ref ZStream sz);
28
29 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
30 private static extern int deflateEnd(ref ZStream sz);
31 #endregion
32
33 /// <summary>
34 /// Constructs an new instance of the <c>Deflater</c>
35 /// </summary>
36 /// <param name="level">The compression level to use for this <c>Deflater</c></param>
37 public Deflater(CompressLevel level) : base()
38 {
39 int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
40 if (retval != 0)
41 throw new ZLibException(retval, "Could not initialize deflater");
42
43 resetOutput();
44 }
45
46 /// <summary>
47 /// Adds more data to the codec to be processed.
48 /// </summary>
49 /// <param name="data">Byte array containing the data to be added to the codec</param>
50 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
51 /// <param name="count">The number of bytes to add</param>
52 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
53 public override void Add(byte[] data, int offset, int count)
54 {
55 if (data == null) throw new ArgumentNullException();
56 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
57 if ((offset+count) > data.Length) throw new ArgumentException();
58
59 int total = count;
60 int inputIndex = offset;
61 int err = 0;
62
63 while (err >= 0 && inputIndex < total)
64 {
65 copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
66 while (err >= 0 && _ztream.avail_in > 0)
67 {
68 err = deflate(ref _ztream, (int)FlushTypes.None);
69 if (err == 0)
70 while (_ztream.avail_out == 0)
71 {
72 OnDataAvailable();
73 err = deflate(ref _ztream, (int)FlushTypes.None);
74 }
75 inputIndex += (int)_ztream.total_in;
76 }
77 }
78 setChecksum( _ztream.adler );
79 }
80
81
82 /// <summary>
83 /// Finishes up any pending data that needs to be processed and handled.
84 /// </summary>
85 public override void Finish()
86 {
87 int err;
88 do
89 {
90 err = deflate(ref _ztream, (int)FlushTypes.Finish);
91 OnDataAvailable();
92 }
93 while (err == 0);
94 setChecksum( _ztream.adler );
95 deflateReset(ref _ztream);
96 resetOutput();
97 }
98
99 /// <summary>
100 /// Closes the internal zlib deflate stream
101 /// </summary>
102 protected override void CleanUp() { deflateEnd(ref _ztream); }
103
104 }
105 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.IO;
9 using System.Runtime.InteropServices;
10 using System.Text;
11
12
13 namespace DotZLib
14 {
15
16 #region Internal types
17
18 /// <summary>
19 /// Defines constants for the various flush types used with zlib
20 /// </summary>
21 internal enum FlushTypes
22 {
23 None, Partial, Sync, Full, Finish, Block
24 }
25
26 #region ZStream structure
27 // internal mapping of the zlib zstream structure for marshalling
28 [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
29 internal struct ZStream
30 {
31 public IntPtr next_in;
32 public uint avail_in;
33 public uint total_in;
34
35 public IntPtr next_out;
36 public uint avail_out;
37 public uint total_out;
38
39 [MarshalAs(UnmanagedType.LPStr)]
40 string msg;
41 uint state;
42
43 uint zalloc;
44 uint zfree;
45 uint opaque;
46
47 int data_type;
48 public uint adler;
49 uint reserved;
50 }
51
52 #endregion
53
54 #endregion
55
56 #region Public enums
57 /// <summary>
58 /// Defines constants for the available compression levels in zlib
59 /// </summary>
60 public enum CompressLevel : int
61 {
62 /// <summary>
63 /// The default compression level with a reasonable compromise between compression and speed
64 /// </summary>
65 Default = -1,
66 /// <summary>
67 /// No compression at all. The data are passed straight through.
68 /// </summary>
69 None = 0,
70 /// <summary>
71 /// The maximum compression rate available.
72 /// </summary>
73 Best = 9,
74 /// <summary>
75 /// The fastest available compression level.
76 /// </summary>
77 Fastest = 1
78 }
79 #endregion
80
81 #region Exception classes
82 /// <summary>
83 /// The exception that is thrown when an error occurs on the zlib dll
84 /// </summary>
85 public class ZLibException : ApplicationException
86 {
87 /// <summary>
88 /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
89 /// error message and error code
90 /// </summary>
91 /// <param name="errorCode">The zlib error code that caused the exception</param>
92 /// <param name="msg">A message that (hopefully) describes the error</param>
93 public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
94 {
95 }
96
97 /// <summary>
98 /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
99 /// error code
100 /// </summary>
101 /// <param name="errorCode">The zlib error code that caused the exception</param>
102 public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
103 {
104 }
105 }
106 #endregion
107
108 #region Interfaces
109
110 /// <summary>
111 /// Declares methods and properties that enables a running checksum to be calculated
112 /// </summary>
113 public interface ChecksumGenerator
114 {
115 /// <summary>
116 /// Gets the current value of the checksum
117 /// </summary>
118 uint Value { get; }
119
120 /// <summary>
121 /// Clears the current checksum to 0
122 /// </summary>
123 void Reset();
124
125 /// <summary>
126 /// Updates the current checksum with an array of bytes
127 /// </summary>
128 /// <param name="data">The data to update the checksum with</param>
129 void Update(byte[] data);
130
131 /// <summary>
132 /// Updates the current checksum with part of an array of bytes
133 /// </summary>
134 /// <param name="data">The data to update the checksum with</param>
135 /// <param name="offset">Where in <c>data</c> to start updating</param>
136 /// <param name="count">The number of bytes from <c>data</c> to use</param>
137 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
138 /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
139 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
140 void Update(byte[] data, int offset, int count);
141
142 /// <summary>
143 /// Updates the current checksum with the data from a string
144 /// </summary>
145 /// <param name="data">The string to update the checksum with</param>
146 /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
147 void Update(string data);
148
149 /// <summary>
150 /// Updates the current checksum with the data from a string, using a specific encoding
151 /// </summary>
152 /// <param name="data">The string to update the checksum with</param>
153 /// <param name="encoding">The encoding to use</param>
154 void Update(string data, Encoding encoding);
155 }
156
157
158 /// <summary>
159 /// Represents the method that will be called from a codec when new data
160 /// are available.
161 /// </summary>
162 /// <paramref name="data">The byte array containing the processed data</paramref>
163 /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
164 /// <paramref name="count">The number of processed bytes available</paramref>
165 /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
166 /// You cannot assume that startIndex will be zero.
167 /// </remarks>
168 public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
169
170 /// <summary>
171 /// Declares methods and events for implementing compressors/decompressors
172 /// </summary>
173 public interface Codec
174 {
175 /// <summary>
176 /// Occurs when more processed data are available.
177 /// </summary>
178 event DataAvailableHandler DataAvailable;
179
180 /// <summary>
181 /// Adds more data to the codec to be processed.
182 /// </summary>
183 /// <param name="data">Byte array containing the data to be added to the codec</param>
184 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
185 void Add(byte[] data);
186
187 /// <summary>
188 /// Adds more data to the codec to be processed.
189 /// </summary>
190 /// <param name="data">Byte array containing the data to be added to the codec</param>
191 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
192 /// <param name="count">The number of bytes to add</param>
193 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
194 void Add(byte[] data, int offset, int count);
195
196 /// <summary>
197 /// Finishes up any pending data that needs to be processed and handled.
198 /// </summary>
199 void Finish();
200
201 /// <summary>
202 /// Gets the checksum of the data that has been added so far
203 /// </summary>
204 uint Checksum { get; }
205
206
207 }
208
209 #endregion
210
211 #region Classes
212 /// <summary>
213 /// Encapsulates general information about the ZLib library
214 /// </summary>
215 public class Info
216 {
217 #region DLL imports
218 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
219 private static extern uint zlibCompileFlags();
220
221 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
222 private static extern string zlibVersion();
223 #endregion
224
225 #region Private stuff
226 private uint _flags;
227
228 // helper function that unpacks a bitsize mask
229 private static int bitSize(uint bits)
230 {
231 switch (bits)
232 {
233 case 0: return 16;
234 case 1: return 32;
235 case 2: return 64;
236 }
237 return -1;
238 }
239 #endregion
240
241 /// <summary>
242 /// Constructs an instance of the <c>Info</c> class.
243 /// </summary>
244 public Info()
245 {
246 _flags = zlibCompileFlags();
247 }
248
249 /// <summary>
250 /// True if the library is compiled with debug info
251 /// </summary>
252 public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
253
254 /// <summary>
255 /// True if the library is compiled with assembly optimizations
256 /// </summary>
257 public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
258
259 /// <summary>
260 /// Gets the size of the unsigned int that was compiled into Zlib
261 /// </summary>
262 public int SizeOfUInt { get { return bitSize(_flags & 3); } }
263
264 /// <summary>
265 /// Gets the size of the unsigned long that was compiled into Zlib
266 /// </summary>
267 public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
268
269 /// <summary>
270 /// Gets the size of the pointers that were compiled into Zlib
271 /// </summary>
272 public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
273
274 /// <summary>
275 /// Gets the size of the z_off_t type that was compiled into Zlib
276 /// </summary>
277 public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
278
279 /// <summary>
280 /// Gets the version of ZLib as a string, e.g. "1.2.1"
281 /// </summary>
282 public static string Version { get { return zlibVersion(); } }
283 }
284
285 #endregion
286
287 }
0 <VisualStudioProject>
1 <CSHARP
2 ProjectType = "Local"
3 ProductVersion = "7.10.3077"
4 SchemaVersion = "2.0"
5 ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
6 >
7 <Build>
8 <Settings
9 ApplicationIcon = ""
10 AssemblyKeyContainerName = ""
11 AssemblyName = "DotZLib"
12 AssemblyOriginatorKeyFile = ""
13 DefaultClientScript = "JScript"
14 DefaultHTMLPageLayout = "Grid"
15 DefaultTargetSchema = "IE50"
16 DelaySign = "false"
17 OutputType = "Library"
18 PreBuildEvent = ""
19 PostBuildEvent = ""
20 RootNamespace = "DotZLib"
21 RunPostBuildEvent = "OnBuildSuccess"
22 StartupObject = ""
23 >
24 <Config
25 Name = "Debug"
26 AllowUnsafeBlocks = "false"
27 BaseAddress = "285212672"
28 CheckForOverflowUnderflow = "false"
29 ConfigurationOverrideFile = ""
30 DefineConstants = "DEBUG;TRACE"
31 DocumentationFile = "docs\DotZLib.xml"
32 DebugSymbols = "true"
33 FileAlignment = "4096"
34 IncrementalBuild = "false"
35 NoStdLib = "false"
36 NoWarn = "1591"
37 Optimize = "false"
38 OutputPath = "bin\Debug\"
39 RegisterForComInterop = "false"
40 RemoveIntegerChecks = "false"
41 TreatWarningsAsErrors = "false"
42 WarningLevel = "4"
43 />
44 <Config
45 Name = "Release"
46 AllowUnsafeBlocks = "false"
47 BaseAddress = "285212672"
48 CheckForOverflowUnderflow = "false"
49 ConfigurationOverrideFile = ""
50 DefineConstants = "TRACE"
51 DocumentationFile = "docs\DotZLib.xml"
52 DebugSymbols = "false"
53 FileAlignment = "4096"
54 IncrementalBuild = "false"
55 NoStdLib = "false"
56 NoWarn = ""
57 Optimize = "true"
58 OutputPath = "bin\Release\"
59 RegisterForComInterop = "false"
60 RemoveIntegerChecks = "false"
61 TreatWarningsAsErrors = "false"
62 WarningLevel = "4"
63 />
64 </Settings>
65 <References>
66 <Reference
67 Name = "System"
68 AssemblyName = "System"
69 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
70 />
71 <Reference
72 Name = "System.Data"
73 AssemblyName = "System.Data"
74 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
75 />
76 <Reference
77 Name = "System.XML"
78 AssemblyName = "System.Xml"
79 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
80 />
81 <Reference
82 Name = "nunit.framework"
83 AssemblyName = "nunit.framework"
84 HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
85 AssemblyFolderKey = "hklm\dn\nunit.framework"
86 />
87 </References>
88 </Build>
89 <Files>
90 <Include>
91 <File
92 RelPath = "AssemblyInfo.cs"
93 SubType = "Code"
94 BuildAction = "Compile"
95 />
96 <File
97 RelPath = "ChecksumImpl.cs"
98 SubType = "Code"
99 BuildAction = "Compile"
100 />
101 <File
102 RelPath = "CircularBuffer.cs"
103 SubType = "Code"
104 BuildAction = "Compile"
105 />
106 <File
107 RelPath = "CodecBase.cs"
108 SubType = "Code"
109 BuildAction = "Compile"
110 />
111 <File
112 RelPath = "Deflater.cs"
113 SubType = "Code"
114 BuildAction = "Compile"
115 />
116 <File
117 RelPath = "DotZLib.cs"
118 SubType = "Code"
119 BuildAction = "Compile"
120 />
121 <File
122 RelPath = "GZipStream.cs"
123 SubType = "Code"
124 BuildAction = "Compile"
125 />
126 <File
127 RelPath = "Inflater.cs"
128 SubType = "Code"
129 BuildAction = "Compile"
130 />
131 <File
132 RelPath = "UnitTests.cs"
133 SubType = "Code"
134 BuildAction = "Compile"
135 />
136 </Include>
137 </Files>
138 </CSHARP>
139 </VisualStudioProject>
140
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.IO;
9 using System.Runtime.InteropServices;
10
11 namespace DotZLib
12 {
13 /// <summary>
14 /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
15 /// </summary>
16 public class GZipStream : Stream, IDisposable
17 {
18 #region Dll Imports
19 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
20 private static extern IntPtr gzopen(string name, string mode);
21
22 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
23 private static extern int gzclose(IntPtr gzFile);
24
25 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
26 private static extern int gzwrite(IntPtr gzFile, int data, int length);
27
28 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
29 private static extern int gzread(IntPtr gzFile, int data, int length);
30
31 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
32 private static extern int gzgetc(IntPtr gzFile);
33
34 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
35 private static extern int gzputc(IntPtr gzFile, int c);
36
37 #endregion
38
39 #region Private data
40 private IntPtr _gzFile;
41 private bool _isDisposed = false;
42 private bool _isWriting;
43 #endregion
44
45 #region Constructors
46 /// <summary>
47 /// Creates a new file as a writeable GZipStream
48 /// </summary>
49 /// <param name="fileName">The name of the compressed file to create</param>
50 /// <param name="level">The compression level to use when adding data</param>
51 /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
52 public GZipStream(string fileName, CompressLevel level)
53 {
54 _isWriting = true;
55 _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
56 if (_gzFile == IntPtr.Zero)
57 throw new ZLibException(-1, "Could not open " + fileName);
58 }
59
60 /// <summary>
61 /// Opens an existing file as a readable GZipStream
62 /// </summary>
63 /// <param name="fileName">The name of the file to open</param>
64 /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
65 public GZipStream(string fileName)
66 {
67 _isWriting = false;
68 _gzFile = gzopen(fileName, "rb");
69 if (_gzFile == IntPtr.Zero)
70 throw new ZLibException(-1, "Could not open " + fileName);
71
72 }
73 #endregion
74
75 #region Access properties
76 /// <summary>
77 /// Returns true of this stream can be read from, false otherwise
78 /// </summary>
79 public override bool CanRead
80 {
81 get
82 {
83 return !_isWriting;
84 }
85 }
86
87
88 /// <summary>
89 /// Returns false.
90 /// </summary>
91 public override bool CanSeek
92 {
93 get
94 {
95 return false;
96 }
97 }
98
99 /// <summary>
100 /// Returns true if this tsream is writeable, false otherwise
101 /// </summary>
102 public override bool CanWrite
103 {
104 get
105 {
106 return _isWriting;
107 }
108 }
109 #endregion
110
111 #region Destructor & IDispose stuff
112
113 /// <summary>
114 /// Destroys this instance
115 /// </summary>
116 ~GZipStream()
117 {
118 cleanUp(false);
119 }
120
121 /// <summary>
122 /// Closes the external file handle
123 /// </summary>
124 public void Dispose()
125 {
126 cleanUp(true);
127 }
128
129 // Does the actual closing of the file handle.
130 private void cleanUp(bool isDisposing)
131 {
132 if (!_isDisposed)
133 {
134 gzclose(_gzFile);
135 _isDisposed = true;
136 }
137 }
138 #endregion
139
140 #region Basic reading and writing
141 /// <summary>
142 /// Attempts to read a number of bytes from the stream.
143 /// </summary>
144 /// <param name="buffer">The destination data buffer</param>
145 /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
146 /// <param name="count">The number of bytes requested</param>
147 /// <returns>The number of bytes read</returns>
148 /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
149 /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
150 /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
151 /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
152 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
153 public override int Read(byte[] buffer, int offset, int count)
154 {
155 if (!CanRead) throw new NotSupportedException();
156 if (buffer == null) throw new ArgumentNullException();
157 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
158 if ((offset+count) > buffer.Length) throw new ArgumentException();
159 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
160
161 GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
162 int result;
163 try
164 {
165 result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
166 if (result < 0)
167 throw new IOException();
168 }
169 finally
170 {
171 h.Free();
172 }
173 return result;
174 }
175
176 /// <summary>
177 /// Attempts to read a single byte from the stream.
178 /// </summary>
179 /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
180 public override int ReadByte()
181 {
182 if (!CanRead) throw new NotSupportedException();
183 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
184 return gzgetc(_gzFile);
185 }
186
187 /// <summary>
188 /// Writes a number of bytes to the stream
189 /// </summary>
190 /// <param name="buffer"></param>
191 /// <param name="offset"></param>
192 /// <param name="count"></param>
193 /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
194 /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
195 /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
196 /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
197 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
198 public override void Write(byte[] buffer, int offset, int count)
199 {
200 if (!CanWrite) throw new NotSupportedException();
201 if (buffer == null) throw new ArgumentNullException();
202 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
203 if ((offset+count) > buffer.Length) throw new ArgumentException();
204 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
205
206 GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
207 try
208 {
209 int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
210 if (result < 0)
211 throw new IOException();
212 }
213 finally
214 {
215 h.Free();
216 }
217 }
218
219 /// <summary>
220 /// Writes a single byte to the stream
221 /// </summary>
222 /// <param name="value">The byte to add to the stream.</param>
223 /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
224 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
225 public override void WriteByte(byte value)
226 {
227 if (!CanWrite) throw new NotSupportedException();
228 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
229
230 int result = gzputc(_gzFile, (int)value);
231 if (result < 0)
232 throw new IOException();
233 }
234 #endregion
235
236 #region Position & length stuff
237 /// <summary>
238 /// Not supported.
239 /// </summary>
240 /// <param name="value"></param>
241 /// <exception cref="NotSupportedException">Always thrown</exception>
242 public override void SetLength(long value)
243 {
244 throw new NotSupportedException();
245 }
246
247 /// <summary>
248 /// Not suppported.
249 /// </summary>
250 /// <param name="offset"></param>
251 /// <param name="origin"></param>
252 /// <returns></returns>
253 /// <exception cref="NotSupportedException">Always thrown</exception>
254 public override long Seek(long offset, SeekOrigin origin)
255 {
256 throw new NotSupportedException();
257 }
258
259 /// <summary>
260 /// Flushes the <c>GZipStream</c>.
261 /// </summary>
262 /// <remarks>In this implementation, this method does nothing. This is because excessive
263 /// flushing may degrade the achievable compression rates.</remarks>
264 public override void Flush()
265 {
266 // left empty on purpose
267 }
268
269 /// <summary>
270 /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
271 /// </summary>
272 /// <remarks>In this implementation this property is not supported</remarks>
273 /// <exception cref="NotSupportedException">Always thrown</exception>
274 public override long Position
275 {
276 get
277 {
278 throw new NotSupportedException();
279 }
280 set
281 {
282 throw new NotSupportedException();
283 }
284 }
285
286 /// <summary>
287 /// Gets the size of the stream. Not suppported.
288 /// </summary>
289 /// <remarks>In this implementation this property is not supported</remarks>
290 /// <exception cref="NotSupportedException">Always thrown</exception>
291 public override long Length
292 {
293 get
294 {
295 throw new NotSupportedException();
296 }
297 }
298 #endregion
299 }
300 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Diagnostics;
9 using System.Runtime.InteropServices;
10
11 namespace DotZLib
12 {
13
14 /// <summary>
15 /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
16 /// </summary>
17 public class Inflater : CodecBase
18 {
19 #region Dll imports
20 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
21 private static extern int inflateInit_(ref ZStream sz, string vs, int size);
22
23 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
24 private static extern int inflate(ref ZStream sz, int flush);
25
26 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
27 private static extern int inflateReset(ref ZStream sz);
28
29 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
30 private static extern int inflateEnd(ref ZStream sz);
31 #endregion
32
33 /// <summary>
34 /// Constructs an new instance of the <c>Inflater</c>
35 /// </summary>
36 public Inflater() : base()
37 {
38 int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
39 if (retval != 0)
40 throw new ZLibException(retval, "Could not initialize inflater");
41
42 resetOutput();
43 }
44
45
46 /// <summary>
47 /// Adds more data to the codec to be processed.
48 /// </summary>
49 /// <param name="data">Byte array containing the data to be added to the codec</param>
50 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
51 /// <param name="count">The number of bytes to add</param>
52 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
53 public override void Add(byte[] data, int offset, int count)
54 {
55 if (data == null) throw new ArgumentNullException();
56 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
57 if ((offset+count) > data.Length) throw new ArgumentException();
58
59 int total = count;
60 int inputIndex = offset;
61 int err = 0;
62
63 while (err >= 0 && inputIndex < total)
64 {
65 copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
66 err = inflate(ref _ztream, (int)FlushTypes.None);
67 if (err == 0)
68 while (_ztream.avail_out == 0)
69 {
70 OnDataAvailable();
71 err = inflate(ref _ztream, (int)FlushTypes.None);
72 }
73
74 inputIndex += (int)_ztream.total_in;
75 }
76 setChecksum( _ztream.adler );
77 }
78
79
80 /// <summary>
81 /// Finishes up any pending data that needs to be processed and handled.
82 /// </summary>
83 public override void Finish()
84 {
85 int err;
86 do
87 {
88 err = inflate(ref _ztream, (int)FlushTypes.Finish);
89 OnDataAvailable();
90 }
91 while (err == 0);
92 setChecksum( _ztream.adler );
93 inflateReset(ref _ztream);
94 resetOutput();
95 }
96
97 /// <summary>
98 /// Closes the internal zlib inflate stream
99 /// </summary>
100 protected override void CleanUp() { inflateEnd(ref _ztream); }
101
102
103 }
104 }
0 //
1 // © Copyright Henrik Ravn 2004
2 //
3 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 using System;
8 using System.Collections;
9 using System.IO;
10
11 // uncomment the define below to include unit tests
12 //#define nunit
13 #if nunit
14 using NUnit.Framework;
15
16 // Unit tests for the DotZLib class library
17 // ----------------------------------------
18 //
19 // Use this with NUnit 2 from http://www.nunit.org
20 //
21
22 namespace DotZLibTests
23 {
24 using DotZLib;
25
26 // helper methods
27 internal class Utils
28 {
29 public static bool byteArrEqual( byte[] lhs, byte[] rhs )
30 {
31 if (lhs.Length != rhs.Length)
32 return false;
33 for (int i = lhs.Length-1; i >= 0; --i)
34 if (lhs[i] != rhs[i])
35 return false;
36 return true;
37 }
38
39 }
40
41
42 [TestFixture]
43 public class CircBufferTests
44 {
45 #region Circular buffer tests
46 [Test]
47 public void SinglePutGet()
48 {
49 CircularBuffer buf = new CircularBuffer(10);
50 Assert.AreEqual( 0, buf.Size );
51 Assert.AreEqual( -1, buf.Get() );
52
53 Assert.IsTrue(buf.Put( 1 ));
54 Assert.AreEqual( 1, buf.Size );
55 Assert.AreEqual( 1, buf.Get() );
56 Assert.AreEqual( 0, buf.Size );
57 Assert.AreEqual( -1, buf.Get() );
58 }
59
60 [Test]
61 public void BlockPutGet()
62 {
63 CircularBuffer buf = new CircularBuffer(10);
64 byte[] arr = {1,2,3,4,5,6,7,8,9,10};
65 Assert.AreEqual( 10, buf.Put(arr,0,10) );
66 Assert.AreEqual( 10, buf.Size );
67 Assert.IsFalse( buf.Put(11) );
68 Assert.AreEqual( 1, buf.Get() );
69 Assert.IsTrue( buf.Put(11) );
70
71 byte[] arr2 = (byte[])arr.Clone();
72 Assert.AreEqual( 9, buf.Get(arr2,1,9) );
73 Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
74 }
75
76 #endregion
77 }
78
79 [TestFixture]
80 public class ChecksumTests
81 {
82 #region CRC32 Tests
83 [Test]
84 public void CRC32_Null()
85 {
86 CRC32Checksum crc32 = new CRC32Checksum();
87 Assert.AreEqual( 0, crc32.Value );
88
89 crc32 = new CRC32Checksum(1);
90 Assert.AreEqual( 1, crc32.Value );
91
92 crc32 = new CRC32Checksum(556);
93 Assert.AreEqual( 556, crc32.Value );
94 }
95
96 [Test]
97 public void CRC32_Data()
98 {
99 CRC32Checksum crc32 = new CRC32Checksum();
100 byte[] data = { 1,2,3,4,5,6,7 };
101 crc32.Update(data);
102 Assert.AreEqual( 0x70e46888, crc32.Value );
103
104 crc32 = new CRC32Checksum();
105 crc32.Update("penguin");
106 Assert.AreEqual( 0x0e5c1a120, crc32.Value );
107
108 crc32 = new CRC32Checksum(1);
109 crc32.Update("penguin");
110 Assert.AreEqual(0x43b6aa94, crc32.Value);
111
112 }
113 #endregion
114
115 #region Adler tests
116
117 [Test]
118 public void Adler_Null()
119 {
120 AdlerChecksum adler = new AdlerChecksum();
121 Assert.AreEqual(0, adler.Value);
122
123 adler = new AdlerChecksum(1);
124 Assert.AreEqual( 1, adler.Value );
125
126 adler = new AdlerChecksum(556);
127 Assert.AreEqual( 556, adler.Value );
128 }
129
130 [Test]
131 public void Adler_Data()
132 {
133 AdlerChecksum adler = new AdlerChecksum(1);
134 byte[] data = { 1,2,3,4,5,6,7 };
135 adler.Update(data);
136 Assert.AreEqual( 0x5b001d, adler.Value );
137
138 adler = new AdlerChecksum();
139 adler.Update("penguin");
140 Assert.AreEqual(0x0bcf02f6, adler.Value );
141
142 adler = new AdlerChecksum(1);
143 adler.Update("penguin");
144 Assert.AreEqual(0x0bd602f7, adler.Value);
145
146 }
147 #endregion
148 }
149
150 [TestFixture]
151 public class InfoTests
152 {
153 #region Info tests
154 [Test]
155 public void Info_Version()
156 {
157 Info info = new Info();
158 Assert.AreEqual("1.2.2", Info.Version);
159 Assert.AreEqual(32, info.SizeOfUInt);
160 Assert.AreEqual(32, info.SizeOfULong);
161 Assert.AreEqual(32, info.SizeOfPointer);
162 Assert.AreEqual(32, info.SizeOfOffset);
163 }
164 #endregion
165 }
166
167 [TestFixture]
168 public class DeflateInflateTests
169 {
170 #region Deflate tests
171 [Test]
172 public void Deflate_Init()
173 {
174 using (Deflater def = new Deflater(CompressLevel.Default))
175 {
176 }
177 }
178
179 private ArrayList compressedData = new ArrayList();
180 private uint adler1;
181
182 private ArrayList uncompressedData = new ArrayList();
183 private uint adler2;
184
185 public void CDataAvail(byte[] data, int startIndex, int count)
186 {
187 for (int i = 0; i < count; ++i)
188 compressedData.Add(data[i+startIndex]);
189 }
190
191 [Test]
192 public void Deflate_Compress()
193 {
194 compressedData.Clear();
195
196 byte[] testData = new byte[35000];
197 for (int i = 0; i < testData.Length; ++i)
198 testData[i] = 5;
199
200 using (Deflater def = new Deflater((CompressLevel)5))
201 {
202 def.DataAvailable += new DataAvailableHandler(CDataAvail);
203 def.Add(testData);
204 def.Finish();
205 adler1 = def.Checksum;
206 }
207 }
208 #endregion
209
210 #region Inflate tests
211 [Test]
212 public void Inflate_Init()
213 {
214 using (Inflater inf = new Inflater())
215 {
216 }
217 }
218
219 private void DDataAvail(byte[] data, int startIndex, int count)
220 {
221 for (int i = 0; i < count; ++i)
222 uncompressedData.Add(data[i+startIndex]);
223 }
224
225 [Test]
226 public void Inflate_Expand()
227 {
228 uncompressedData.Clear();
229
230 using (Inflater inf = new Inflater())
231 {
232 inf.DataAvailable += new DataAvailableHandler(DDataAvail);
233 inf.Add((byte[])compressedData.ToArray(typeof(byte)));
234 inf.Finish();
235 adler2 = inf.Checksum;
236 }
237 Assert.AreEqual( adler1, adler2 );
238 }
239 #endregion
240 }
241
242 [TestFixture]
243 public class GZipStreamTests
244 {
245 #region GZipStream test
246 [Test]
247 public void GZipStream_WriteRead()
248 {
249 using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
250 {
251 BinaryWriter writer = new BinaryWriter(gzOut);
252 writer.Write("hi there");
253 writer.Write(Math.PI);
254 writer.Write(42);
255 }
256
257 using (GZipStream gzIn = new GZipStream("gzstream.gz"))
258 {
259 BinaryReader reader = new BinaryReader(gzIn);
260 string s = reader.ReadString();
261 Assert.AreEqual("hi there",s);
262 double d = reader.ReadDouble();
263 Assert.AreEqual(Math.PI, d);
264 int i = reader.ReadInt32();
265 Assert.AreEqual(42,i);
266 }
267
268 }
269 #endregion
270 }
271 }
272
273 #endif
0 <?xml version="1.0" encoding="utf-8" ?>
1 <project name="DotZLib" default="build" basedir="./DotZLib">
2 <description>A .Net wrapper library around ZLib1.dll</description>
3
4 <property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
5 <property name="build.root" value="bin" />
6
7 <property name="debug" value="true" />
8 <property name="nunit" value="true" />
9
10 <property name="build.folder" value="${build.root}/debug/" if="${debug}" />
11 <property name="build.folder" value="${build.root}/release/" unless="${debug}" />
12
13 <target name="clean" description="Remove all generated files">
14 <delete dir="${build.root}" failonerror="false" />
15 </target>
16
17 <target name="build" description="compiles the source code">
18
19 <mkdir dir="${build.folder}" />
20 <csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
21 <references basedir="${nunit.location}">
22 <includes if="${nunit}" name="nunit.framework.dll" />
23 </references>
24 <sources>
25 <includes name="*.cs" />
26 <excludes name="UnitTests.cs" unless="${nunit}" />
27 </sources>
28 <arg value="/d:nunit" if="${nunit}" />
29 </csc>
30 </target>
31
32 </project>
0 Microsoft Visual Studio Solution File, Format Version 8.00
1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
2 ProjectSection(ProjectDependencies) = postProject
3 EndProjectSection
4 EndProject
5 Global
6 GlobalSection(SolutionConfiguration) = preSolution
7 Debug = Debug
8 Release = Release
9 EndGlobalSection
10 GlobalSection(ProjectConfiguration) = postSolution
11 {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
12 {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
13 {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
14 {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
15 EndGlobalSection
16 GlobalSection(ExtensibilityGlobals) = postSolution
17 EndGlobalSection
18 GlobalSection(ExtensibilityAddIns) = postSolution
19 EndGlobalSection
20 EndGlobal
0 Boost Software License - Version 1.0 - August 17th, 2003
1
2 Permission is hereby granted, free of charge, to any person or organization
3 obtaining a copy of the software and accompanying documentation covered by
4 this license (the "Software") to use, reproduce, display, distribute,
5 execute, and transmit the Software, and to prepare derivative works of the
6 Software, and to permit third-parties to whom the Software is furnished to
7 do so, all subject to the following:
8
9 The copyright notices in the Software and this entire statement, including
10 the above license grant, this restriction and the following disclaimer,
11 must be included in all copies of the Software, in whole or in part, and
12 all derivative works of the Software, unless such copies or derivative
13 works are solely in the form of machine-executable object code generated by
14 a source language processor.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
19 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
0 This directory contains a .Net wrapper class library for the ZLib1.dll
1
2 The wrapper includes support for inflating/deflating memory buffers,
3 .Net streaming wrappers for the gz streams part of zlib, and wrappers
4 for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
5
6 Directory structure:
7 --------------------
8
9 LICENSE_1_0.txt - License file.
10 readme.txt - This file.
11 DotZLib.chm - Class library documentation
12 DotZLib.build - NAnt build file
13 DotZLib.sln - Microsoft Visual Studio 2003 solution file
14
15 DotZLib\*.cs - Source files for the class library
16
17 Unit tests:
18 -----------
19 The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
20 To include unit tests in the build, define nunit before building.
21
22
23 Build instructions:
24 -------------------
25
26 1. Using Visual Studio.Net 2003:
27 Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
28 will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
29 you are building the release or debug version of the library. Check
30 DotZLib/UnitTests.cs for instructions on how to include unit tests in the
31 build.
32
33 2. Using NAnt:
34 Open a command prompt with access to the build environment and run nant
35 in the same directory as the DotZLib.build file.
36 You can define 2 properties on the nant command-line to control the build:
37 debug={true|false} to toggle between release/debug builds (default=true).
38 nunit={true|false} to include or esclude unit tests (default=true).
39 Also the target clean will remove binaries.
40 Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
41 or ./DotZLib/bin/debug, depending on whether you are building the release
42 or debug version of the library.
43
44 Examples:
45 nant -D:debug=false -D:nunit=false
46 will build a release mode version of the library without unit tests.
47 nant
48 will build a debug version of the library with unit tests
49 nant clean
50 will remove all previously built files.
51
52
53 ---------------------------------
54 Copyright (c) Henrik Ravn 2004
55
56 Use, modification and distribution are subject to the Boost Software License, Version 1.0.
57 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0 See infback9.h for what this is and how to use it.
0 /* infback9.c -- inflate deflate64 data using a call-back interface
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 #include "zutil.h"
6 #include "infback9.h"
7 #include "inftree9.h"
8 #include "inflate9.h"
9
10 #define WSIZE 65536UL
11
12 /*
13 strm provides memory allocation functions in zalloc and zfree, or
14 Z_NULL to use the library memory allocation functions.
15
16 window is a user-supplied window and output buffer that is 64K bytes.
17 */
18 int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
19 z_stream FAR *strm;
20 unsigned char FAR *window;
21 const char *version;
22 int stream_size;
23 {
24 struct inflate_state FAR *state;
25
26 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
27 stream_size != (int)(sizeof(z_stream)))
28 return Z_VERSION_ERROR;
29 if (strm == Z_NULL || window == Z_NULL)
30 return Z_STREAM_ERROR;
31 strm->msg = Z_NULL; /* in case we return an error */
32 if (strm->zalloc == (alloc_func)0) {
33 strm->zalloc = zcalloc;
34 strm->opaque = (voidpf)0;
35 }
36 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
37 state = (struct inflate_state FAR *)ZALLOC(strm, 1,
38 sizeof(struct inflate_state));
39 if (state == Z_NULL) return Z_MEM_ERROR;
40 Tracev((stderr, "inflate: allocated\n"));
41 strm->state = (voidpf)state;
42 state->window = window;
43 return Z_OK;
44 }
45
46 /*
47 Build and output length and distance decoding tables for fixed code
48 decoding.
49 */
50 #ifdef MAKEFIXED
51 #include <stdio.h>
52
53 void makefixed9(void)
54 {
55 unsigned sym, bits, low, size;
56 code *next, *lenfix, *distfix;
57 struct inflate_state state;
58 code fixed[544];
59
60 /* literal/length table */
61 sym = 0;
62 while (sym < 144) state.lens[sym++] = 8;
63 while (sym < 256) state.lens[sym++] = 9;
64 while (sym < 280) state.lens[sym++] = 7;
65 while (sym < 288) state.lens[sym++] = 8;
66 next = fixed;
67 lenfix = next;
68 bits = 9;
69 inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
70
71 /* distance table */
72 sym = 0;
73 while (sym < 32) state.lens[sym++] = 5;
74 distfix = next;
75 bits = 5;
76 inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
77
78 /* write tables */
79 puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
80 puts(" * Generated automatically by makefixed9().");
81 puts(" */");
82 puts("");
83 puts(" /* WARNING: this file should *not* be used by applications.");
84 puts(" It is part of the implementation of this library and is");
85 puts(" subject to change. Applications should only use zlib.h.");
86 puts(" */");
87 puts("");
88 size = 1U << 9;
89 printf(" static const code lenfix[%u] = {", size);
90 low = 0;
91 for (;;) {
92 if ((low % 6) == 0) printf("\n ");
93 printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
94 lenfix[low].val);
95 if (++low == size) break;
96 putchar(',');
97 }
98 puts("\n };");
99 size = 1U << 5;
100 printf("\n static const code distfix[%u] = {", size);
101 low = 0;
102 for (;;) {
103 if ((low % 5) == 0) printf("\n ");
104 printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
105 distfix[low].val);
106 if (++low == size) break;
107 putchar(',');
108 }
109 puts("\n };");
110 }
111 #endif /* MAKEFIXED */
112
113 /* Macros for inflateBack(): */
114
115 /* Clear the input bit accumulator */
116 #define INITBITS() \
117 do { \
118 hold = 0; \
119 bits = 0; \
120 } while (0)
121
122 /* Assure that some input is available. If input is requested, but denied,
123 then return a Z_BUF_ERROR from inflateBack(). */
124 #define PULL() \
125 do { \
126 if (have == 0) { \
127 have = in(in_desc, &next); \
128 if (have == 0) { \
129 next = Z_NULL; \
130 ret = Z_BUF_ERROR; \
131 goto inf_leave; \
132 } \
133 } \
134 } while (0)
135
136 /* Get a byte of input into the bit accumulator, or return from inflateBack()
137 with an error if there is no input available. */
138 #define PULLBYTE() \
139 do { \
140 PULL(); \
141 have--; \
142 hold += (unsigned long)(*next++) << bits; \
143 bits += 8; \
144 } while (0)
145
146 /* Assure that there are at least n bits in the bit accumulator. If there is
147 not enough available input to do that, then return from inflateBack() with
148 an error. */
149 #define NEEDBITS(n) \
150 do { \
151 while (bits < (unsigned)(n)) \
152 PULLBYTE(); \
153 } while (0)
154
155 /* Return the low n bits of the bit accumulator (n <= 16) */
156 #define BITS(n) \
157 ((unsigned)hold & ((1U << (n)) - 1))
158
159 /* Remove n bits from the bit accumulator */
160 #define DROPBITS(n) \
161 do { \
162 hold >>= (n); \
163 bits -= (unsigned)(n); \
164 } while (0)
165
166 /* Remove zero to seven bits as needed to go to a byte boundary */
167 #define BYTEBITS() \
168 do { \
169 hold >>= bits & 7; \
170 bits -= bits & 7; \
171 } while (0)
172
173 /* Assure that some output space is available, by writing out the window
174 if it's full. If the write fails, return from inflateBack() with a
175 Z_BUF_ERROR. */
176 #define ROOM() \
177 do { \
178 if (left == 0) { \
179 put = window; \
180 left = WSIZE; \
181 wrap = 1; \
182 if (out(out_desc, put, (unsigned)left)) { \
183 ret = Z_BUF_ERROR; \
184 goto inf_leave; \
185 } \
186 } \
187 } while (0)
188
189 /*
190 strm provides the memory allocation functions and window buffer on input,
191 and provides information on the unused input on return. For Z_DATA_ERROR
192 returns, strm will also provide an error message.
193
194 in() and out() are the call-back input and output functions. When
195 inflateBack() needs more input, it calls in(). When inflateBack() has
196 filled the window with output, or when it completes with data in the
197 window, it calls out() to write out the data. The application must not
198 change the provided input until in() is called again or inflateBack()
199 returns. The application must not change the window/output buffer until
200 inflateBack() returns.
201
202 in() and out() are called with a descriptor parameter provided in the
203 inflateBack() call. This parameter can be a structure that provides the
204 information required to do the read or write, as well as accumulated
205 information on the input and output such as totals and check values.
206
207 in() should return zero on failure. out() should return non-zero on
208 failure. If either in() or out() fails, than inflateBack() returns a
209 Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
210 was in() or out() that caused in the error. Otherwise, inflateBack()
211 returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
212 error, or Z_MEM_ERROR if it could not allocate memory for the state.
213 inflateBack() can also return Z_STREAM_ERROR if the input parameters
214 are not correct, i.e. strm is Z_NULL or the state was not initialized.
215 */
216 int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
217 z_stream FAR *strm;
218 in_func in;
219 void FAR *in_desc;
220 out_func out;
221 void FAR *out_desc;
222 {
223 struct inflate_state FAR *state;
224 unsigned char FAR *next; /* next input */
225 unsigned char FAR *put; /* next output */
226 unsigned have; /* available input */
227 unsigned long left; /* available output */
228 inflate_mode mode; /* current inflate mode */
229 int lastblock; /* true if processing last block */
230 int wrap; /* true if the window has wrapped */
231 unsigned long write; /* window write index */
232 unsigned char FAR *window; /* allocated sliding window, if needed */
233 unsigned long hold; /* bit buffer */
234 unsigned bits; /* bits in bit buffer */
235 unsigned extra; /* extra bits needed */
236 unsigned long length; /* literal or length of data to copy */
237 unsigned long offset; /* distance back to copy string from */
238 unsigned long copy; /* number of stored or match bytes to copy */
239 unsigned char FAR *from; /* where to copy match bytes from */
240 code const FAR *lencode; /* starting table for length/literal codes */
241 code const FAR *distcode; /* starting table for distance codes */
242 unsigned lenbits; /* index bits for lencode */
243 unsigned distbits; /* index bits for distcode */
244 code this; /* current decoding table entry */
245 code last; /* parent table entry */
246 unsigned len; /* length to copy for repeats, bits to drop */
247 int ret; /* return code */
248 static const unsigned short order[19] = /* permutation of code lengths */
249 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
250 #include "inffix9.h"
251
252 /* Check that the strm exists and that the state was initialized */
253 if (strm == Z_NULL || strm->state == Z_NULL)
254 return Z_STREAM_ERROR;
255 state = (struct inflate_state FAR *)strm->state;
256
257 /* Reset the state */
258 strm->msg = Z_NULL;
259 mode = TYPE;
260 lastblock = 0;
261 write = 0;
262 wrap = 0;
263 window = state->window;
264 next = strm->next_in;
265 have = next != Z_NULL ? strm->avail_in : 0;
266 hold = 0;
267 bits = 0;
268 put = window;
269 left = WSIZE;
270 lencode = Z_NULL;
271 distcode = Z_NULL;
272
273 /* Inflate until end of block marked as last */
274 for (;;)
275 switch (mode) {
276 case TYPE:
277 /* determine and dispatch block type */
278 if (lastblock) {
279 BYTEBITS();
280 mode = DONE;
281 break;
282 }
283 NEEDBITS(3);
284 lastblock = BITS(1);
285 DROPBITS(1);
286 switch (BITS(2)) {
287 case 0: /* stored block */
288 Tracev((stderr, "inflate: stored block%s\n",
289 lastblock ? " (last)" : ""));
290 mode = STORED;
291 break;
292 case 1: /* fixed block */
293 lencode = lenfix;
294 lenbits = 9;
295 distcode = distfix;
296 distbits = 5;
297 Tracev((stderr, "inflate: fixed codes block%s\n",
298 lastblock ? " (last)" : ""));
299 mode = LEN; /* decode codes */
300 break;
301 case 2: /* dynamic block */
302 Tracev((stderr, "inflate: dynamic codes block%s\n",
303 lastblock ? " (last)" : ""));
304 mode = TABLE;
305 break;
306 case 3:
307 strm->msg = (char *)"invalid block type";
308 mode = BAD;
309 }
310 DROPBITS(2);
311 break;
312
313 case STORED:
314 /* get and verify stored block length */
315 BYTEBITS(); /* go to byte boundary */
316 NEEDBITS(32);
317 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
318 strm->msg = (char *)"invalid stored block lengths";
319 mode = BAD;
320 break;
321 }
322 length = (unsigned)hold & 0xffff;
323 Tracev((stderr, "inflate: stored length %lu\n",
324 length));
325 INITBITS();
326
327 /* copy stored block from input to output */
328 while (length != 0) {
329 copy = length;
330 PULL();
331 ROOM();
332 if (copy > have) copy = have;
333 if (copy > left) copy = left;
334 zmemcpy(put, next, copy);
335 have -= copy;
336 next += copy;
337 left -= copy;
338 put += copy;
339 length -= copy;
340 }
341 Tracev((stderr, "inflate: stored end\n"));
342 mode = TYPE;
343 break;
344
345 case TABLE:
346 /* get dynamic table entries descriptor */
347 NEEDBITS(14);
348 state->nlen = BITS(5) + 257;
349 DROPBITS(5);
350 state->ndist = BITS(5) + 1;
351 DROPBITS(5);
352 state->ncode = BITS(4) + 4;
353 DROPBITS(4);
354 if (state->nlen > 286) {
355 strm->msg = (char *)"too many length symbols";
356 mode = BAD;
357 break;
358 }
359 Tracev((stderr, "inflate: table sizes ok\n"));
360
361 /* get code length code lengths (not a typo) */
362 state->have = 0;
363 while (state->have < state->ncode) {
364 NEEDBITS(3);
365 state->lens[order[state->have++]] = (unsigned short)BITS(3);
366 DROPBITS(3);
367 }
368 while (state->have < 19)
369 state->lens[order[state->have++]] = 0;
370 state->next = state->codes;
371 lencode = (code const FAR *)(state->next);
372 lenbits = 7;
373 ret = inflate_table9(CODES, state->lens, 19, &(state->next),
374 &(lenbits), state->work);
375 if (ret) {
376 strm->msg = (char *)"invalid code lengths set";
377 mode = BAD;
378 break;
379 }
380 Tracev((stderr, "inflate: code lengths ok\n"));
381
382 /* get length and distance code code lengths */
383 state->have = 0;
384 while (state->have < state->nlen + state->ndist) {
385 for (;;) {
386 this = lencode[BITS(lenbits)];
387 if ((unsigned)(this.bits) <= bits) break;
388 PULLBYTE();
389 }
390 if (this.val < 16) {
391 NEEDBITS(this.bits);
392 DROPBITS(this.bits);
393 state->lens[state->have++] = this.val;
394 }
395 else {
396 if (this.val == 16) {
397 NEEDBITS(this.bits + 2);
398 DROPBITS(this.bits);
399 if (state->have == 0) {
400 strm->msg = (char *)"invalid bit length repeat";
401 mode = BAD;
402 break;
403 }
404 len = (unsigned)(state->lens[state->have - 1]);
405 copy = 3 + BITS(2);
406 DROPBITS(2);
407 }
408 else if (this.val == 17) {
409 NEEDBITS(this.bits + 3);
410 DROPBITS(this.bits);
411 len = 0;
412 copy = 3 + BITS(3);
413 DROPBITS(3);
414 }
415 else {
416 NEEDBITS(this.bits + 7);
417 DROPBITS(this.bits);
418 len = 0;
419 copy = 11 + BITS(7);
420 DROPBITS(7);
421 }
422 if (state->have + copy > state->nlen + state->ndist) {
423 strm->msg = (char *)"invalid bit length repeat";
424 mode = BAD;
425 break;
426 }
427 while (copy--)
428 state->lens[state->have++] = (unsigned short)len;
429 }
430 }
431
432 /* handle error breaks in while */
433 if (mode == BAD) break;
434
435 /* build code tables */
436 state->next = state->codes;
437 lencode = (code const FAR *)(state->next);
438 lenbits = 9;
439 ret = inflate_table9(LENS, state->lens, state->nlen,
440 &(state->next), &(lenbits), state->work);
441 if (ret) {
442 strm->msg = (char *)"invalid literal/lengths set";
443 mode = BAD;
444 break;
445 }
446 distcode = (code const FAR *)(state->next);
447 distbits = 6;
448 ret = inflate_table9(DISTS, state->lens + state->nlen,
449 state->ndist, &(state->next), &(distbits),
450 state->work);
451 if (ret) {
452 strm->msg = (char *)"invalid distances set";
453 mode = BAD;
454 break;
455 }
456 Tracev((stderr, "inflate: codes ok\n"));
457 mode = LEN;
458
459 case LEN:
460 /* get a literal, length, or end-of-block code */
461 for (;;) {
462 this = lencode[BITS(lenbits)];
463 if ((unsigned)(this.bits) <= bits) break;
464 PULLBYTE();
465 }
466 if (this.op && (this.op & 0xf0) == 0) {
467 last = this;
468 for (;;) {
469 this = lencode[last.val +
470 (BITS(last.bits + last.op) >> last.bits)];
471 if ((unsigned)(last.bits + this.bits) <= bits) break;
472 PULLBYTE();
473 }
474 DROPBITS(last.bits);
475 }
476 DROPBITS(this.bits);
477 length = (unsigned)this.val;
478
479 /* process literal */
480 if (this.op == 0) {
481 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
482 "inflate: literal '%c'\n" :
483 "inflate: literal 0x%02x\n", this.val));
484 ROOM();
485 *put++ = (unsigned char)(length);
486 left--;
487 mode = LEN;
488 break;
489 }
490
491 /* process end of block */
492 if (this.op & 32) {
493 Tracevv((stderr, "inflate: end of block\n"));
494 mode = TYPE;
495 break;
496 }
497
498 /* invalid code */
499 if (this.op & 64) {
500 strm->msg = (char *)"invalid literal/length code";
501 mode = BAD;
502 break;
503 }
504
505 /* length code -- get extra bits, if any */
506 extra = (unsigned)(this.op) & 31;
507 if (extra != 0) {
508 NEEDBITS(extra);
509 length += BITS(extra);
510 DROPBITS(extra);
511 }
512 Tracevv((stderr, "inflate: length %lu\n", length));
513
514 /* get distance code */
515 for (;;) {
516 this = distcode[BITS(distbits)];
517 if ((unsigned)(this.bits) <= bits) break;
518 PULLBYTE();
519 }
520 if ((this.op & 0xf0) == 0) {
521 last = this;
522 for (;;) {
523 this = distcode[last.val +
524 (BITS(last.bits + last.op) >> last.bits)];
525 if ((unsigned)(last.bits + this.bits) <= bits) break;
526 PULLBYTE();
527 }
528 DROPBITS(last.bits);
529 }
530 DROPBITS(this.bits);
531 if (this.op & 64) {
532 strm->msg = (char *)"invalid distance code";
533 mode = BAD;
534 break;
535 }
536 offset = (unsigned)this.val;
537
538 /* get distance extra bits, if any */
539 extra = (unsigned)(this.op) & 15;
540 if (extra != 0) {
541 NEEDBITS(extra);
542 offset += BITS(extra);
543 DROPBITS(extra);
544 }
545 if (offset > WSIZE - (wrap ? 0: left)) {
546 strm->msg = (char *)"invalid distance too far back";
547 mode = BAD;
548 break;
549 }
550 Tracevv((stderr, "inflate: distance %lu\n", offset));
551
552 /* copy match from window to output */
553 do {
554 ROOM();
555 copy = WSIZE - offset;
556 if (copy < left) {
557 from = put + copy;
558 copy = left - copy;
559 }
560 else {
561 from = put - offset;
562 copy = left;
563 }
564 if (copy > length) copy = length;
565 length -= copy;
566 left -= copy;
567 do {
568 *put++ = *from++;
569 } while (--copy);
570 } while (length != 0);
571 break;
572
573 case DONE:
574 /* inflate stream terminated properly -- write leftover output */
575 ret = Z_STREAM_END;
576 if (left < WSIZE) {
577 if (out(out_desc, window, (unsigned)(WSIZE - left)))
578 ret = Z_BUF_ERROR;
579 }
580 goto inf_leave;
581
582 case BAD:
583 ret = Z_DATA_ERROR;
584 goto inf_leave;
585
586 default: /* can't happen, but makes compilers happy */
587 ret = Z_STREAM_ERROR;
588 goto inf_leave;
589 }
590
591 /* Return unused input */
592 inf_leave:
593 strm->next_in = next;
594 strm->avail_in = have;
595 return ret;
596 }
597
598 int ZEXPORT inflateBack9End(strm)
599 z_stream FAR *strm;
600 {
601 if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
602 return Z_STREAM_ERROR;
603 ZFREE(strm, strm->state);
604 strm->state = Z_NULL;
605 Tracev((stderr, "inflate: end\n"));
606 return Z_OK;
607 }
0 /* infback9.h -- header for using inflateBack9 functions
1 * Copyright (C) 2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 * This header file and associated patches provide a decoder for PKWare's
7 * undocumented deflate64 compression method (method 9). Use with infback9.c,
8 * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported.
9 * This should be compiled with zlib, since it uses zutil.h and zutil.o.
10 * This code has not yet been tested on 16-bit architectures. See the
11 * comments in zlib.h for inflateBack() usage. These functions are used
12 * identically, except that there is no windowBits parameter, and a 64K
13 * window must be provided. Also if int's are 16 bits, then a zero for
14 * the third parameter of the "out" function actually means 65536UL.
15 * zlib.h must be included before this header file.
16 */
17
18 ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
19 in_func in, void FAR *in_desc,
20 out_func out, void FAR *out_desc));
21 ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
22 ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
23 unsigned char FAR *window,
24 const char *version,
25 int stream_size));
26 #define inflateBack9Init(strm, window) \
27 inflateBack9Init_((strm), (window), \
28 ZLIB_VERSION, sizeof(z_stream))
0 /* inffix9.h -- table for decoding deflate64 fixed codes
1 * Generated automatically by makefixed9().
2 */
3
4 /* WARNING: this file should *not* be used by applications.
5 It is part of the implementation of this library and is
6 subject to change. Applications should only use zlib.h.
7 */
8
9 static const code lenfix[512] = {
10 {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
11 {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
12 {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
13 {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
14 {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
15 {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
16 {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
17 {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
18 {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
19 {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
20 {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
21 {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
22 {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
23 {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
24 {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
25 {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
26 {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
27 {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
28 {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
29 {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
30 {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
31 {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
32 {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
33 {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
34 {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
35 {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
36 {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
37 {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
38 {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
39 {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
40 {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
41 {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
42 {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
43 {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
44 {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
45 {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
46 {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
47 {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
48 {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
49 {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
50 {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
51 {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
52 {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
53 {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
54 {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
55 {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
56 {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
57 {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
58 {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
59 {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
60 {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
61 {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
62 {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
63 {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
64 {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
65 {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
66 {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
67 {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
68 {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
69 {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
70 {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
71 {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
72 {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
73 {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
74 {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
75 {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
76 {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
77 {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
78 {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
79 {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
80 {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
81 {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
82 {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
83 {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
84 {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
85 {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
86 {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
87 {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
88 {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
89 {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
90 {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
91 {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
92 {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
93 {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
94 {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
95 {0,8,79},{0,9,255}
96 };
97
98 static const code distfix[32] = {
99 {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
100 {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
101 {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
102 {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
103 {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
104 {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
105 {134,5,193},{142,5,49153}
106 };
0 /* inflate9.h -- internal inflate state definition
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* Possible inflate modes between inflate() calls */
11 typedef enum {
12 TYPE, /* i: waiting for type bits, including last-flag bit */
13 STORED, /* i: waiting for stored size (length and complement) */
14 TABLE, /* i: waiting for dynamic block table lengths */
15 LEN, /* i: waiting for length/lit code */
16 DONE, /* finished check, done -- remain here until reset */
17 BAD /* got a data error -- remain here until reset */
18 } inflate_mode;
19
20 /*
21 State transitions between above modes -
22
23 (most modes can go to the BAD mode -- not shown for clarity)
24
25 Read deflate blocks:
26 TYPE -> STORED or TABLE or LEN or DONE
27 STORED -> TYPE
28 TABLE -> LENLENS -> CODELENS -> LEN
29 Read deflate codes:
30 LEN -> LEN or TYPE
31 */
32
33 /* state maintained between inflate() calls. Approximately 7K bytes. */
34 struct inflate_state {
35 /* sliding window */
36 unsigned char FAR *window; /* allocated sliding window, if needed */
37 /* dynamic table building */
38 unsigned ncode; /* number of code length code lengths */
39 unsigned nlen; /* number of length code lengths */
40 unsigned ndist; /* number of distance code lengths */
41 unsigned have; /* number of code lengths in lens[] */
42 code FAR *next; /* next available space in codes[] */
43 unsigned short lens[320]; /* temporary storage for code lengths */
44 unsigned short work[288]; /* work area for code table building */
45 code codes[ENOUGH]; /* space for code tables */
46 };
0 /* inftree9.c -- generate Huffman trees for efficient decoding
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 #include "zutil.h"
6 #include "inftree9.h"
7
8 #define MAXBITS 15
9
10 const char inflate9_copyright[] =
11 " inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler ";
12 /*
13 If you use the zlib library in a product, an acknowledgment is welcome
14 in the documentation of your product. If for some reason you cannot
15 include such an acknowledgment, I would appreciate that you keep this
16 copyright string in the executable of your product.
17 */
18
19 /*
20 Build a set of tables to decode the provided canonical Huffman code.
21 The code lengths are lens[0..codes-1]. The result starts at *table,
22 whose indices are 0..2^bits-1. work is a writable array of at least
23 lens shorts, which is used as a work area. type is the type of code
24 to be generated, CODES, LENS, or DISTS. On return, zero is success,
25 -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
26 on return points to the next available entry's address. bits is the
27 requested root table index bits, and on return it is the actual root
28 table index bits. It will differ if the request is greater than the
29 longest code or if it is less than the shortest code.
30 */
31 int inflate_table9(type, lens, codes, table, bits, work)
32 codetype type;
33 unsigned short FAR *lens;
34 unsigned codes;
35 code FAR * FAR *table;
36 unsigned FAR *bits;
37 unsigned short FAR *work;
38 {
39 unsigned len; /* a code's length in bits */
40 unsigned sym; /* index of code symbols */
41 unsigned min, max; /* minimum and maximum code lengths */
42 unsigned root; /* number of index bits for root table */
43 unsigned curr; /* number of index bits for current table */
44 unsigned drop; /* code bits to drop for sub-table */
45 int left; /* number of prefix codes available */
46 unsigned used; /* code entries in table used */
47 unsigned huff; /* Huffman code */
48 unsigned incr; /* for incrementing code, index */
49 unsigned fill; /* index for replicating entries */
50 unsigned low; /* low bits for current root entry */
51 unsigned mask; /* mask for low root bits */
52 code this; /* table entry for duplication */
53 code FAR *next; /* next available space in table */
54 const unsigned short FAR *base; /* base value table to use */
55 const unsigned short FAR *extra; /* extra bits table to use */
56 int end; /* use base and extra for symbol > end */
57 unsigned short count[MAXBITS+1]; /* number of codes of each length */
58 unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
59 static const unsigned short lbase[31] = { /* Length codes 257..285 base */
60 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
61 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
62 131, 163, 195, 227, 3, 0, 0};
63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
64 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
65 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
66 133, 133, 133, 133, 144, 72, 199};
67 static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
68 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
69 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
70 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
71 static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
72 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
73 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
74 139, 139, 140, 140, 141, 141, 142, 142};
75
76 /*
77 Process a set of code lengths to create a canonical Huffman code. The
78 code lengths are lens[0..codes-1]. Each length corresponds to the
79 symbols 0..codes-1. The Huffman code is generated by first sorting the
80 symbols by length from short to long, and retaining the symbol order
81 for codes with equal lengths. Then the code starts with all zero bits
82 for the first code of the shortest length, and the codes are integer
83 increments for the same length, and zeros are appended as the length
84 increases. For the deflate format, these bits are stored backwards
85 from their more natural integer increment ordering, and so when the
86 decoding tables are built in the large loop below, the integer codes
87 are incremented backwards.
88
89 This routine assumes, but does not check, that all of the entries in
90 lens[] are in the range 0..MAXBITS. The caller must assure this.
91 1..MAXBITS is interpreted as that code length. zero means that that
92 symbol does not occur in this code.
93
94 The codes are sorted by computing a count of codes for each length,
95 creating from that a table of starting indices for each length in the
96 sorted table, and then entering the symbols in order in the sorted
97 table. The sorted table is work[], with that space being provided by
98 the caller.
99
100 The length counts are used for other purposes as well, i.e. finding
101 the minimum and maximum length codes, determining if there are any
102 codes at all, checking for a valid set of lengths, and looking ahead
103 at length counts to determine sub-table sizes when building the
104 decoding tables.
105 */
106
107 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
108 for (len = 0; len <= MAXBITS; len++)
109 count[len] = 0;
110 for (sym = 0; sym < codes; sym++)
111 count[lens[sym]]++;
112
113 /* bound code lengths, force root to be within code lengths */
114 root = *bits;
115 for (max = MAXBITS; max >= 1; max--)
116 if (count[max] != 0) break;
117 if (root > max) root = max;
118 if (max == 0) return -1; /* no codes! */
119 for (min = 1; min <= MAXBITS; min++)
120 if (count[min] != 0) break;
121 if (root < min) root = min;
122
123 /* check for an over-subscribed or incomplete set of lengths */
124 left = 1;
125 for (len = 1; len <= MAXBITS; len++) {
126 left <<= 1;
127 left -= count[len];
128 if (left < 0) return -1; /* over-subscribed */
129 }
130 if (left > 0 && (type == CODES || (codes - count[0] != 1)))
131 return -1; /* incomplete set */
132
133 /* generate offsets into symbol table for each length for sorting */
134 offs[1] = 0;
135 for (len = 1; len < MAXBITS; len++)
136 offs[len + 1] = offs[len] + count[len];
137
138 /* sort symbols by length, by symbol order within each length */
139 for (sym = 0; sym < codes; sym++)
140 if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
141
142 /*
143 Create and fill in decoding tables. In this loop, the table being
144 filled is at next and has curr index bits. The code being used is huff
145 with length len. That code is converted to an index by dropping drop
146 bits off of the bottom. For codes where len is less than drop + curr,
147 those top drop + curr - len bits are incremented through all values to
148 fill the table with replicated entries.
149
150 root is the number of index bits for the root table. When len exceeds
151 root, sub-tables are created pointed to by the root entry with an index
152 of the low root bits of huff. This is saved in low to check for when a
153 new sub-table should be started. drop is zero when the root table is
154 being filled, and drop is root when sub-tables are being filled.
155
156 When a new sub-table is needed, it is necessary to look ahead in the
157 code lengths to determine what size sub-table is needed. The length
158 counts are used for this, and so count[] is decremented as codes are
159 entered in the tables.
160
161 used keeps track of how many table entries have been allocated from the
162 provided *table space. It is checked when a LENS table is being made
163 against the space in *table, ENOUGH, minus the maximum space needed by
164 the worst case distance code, MAXD. This should never happen, but the
165 sufficiency of ENOUGH has not been proven exhaustively, hence the check.
166 This assumes that when type == LENS, bits == 9.
167
168 sym increments through all symbols, and the loop terminates when
169 all codes of length max, i.e. all codes, have been processed. This
170 routine permits incomplete codes, so another loop after this one fills
171 in the rest of the decoding tables with invalid code markers.
172 */
173
174 /* set up for code type */
175 switch (type) {
176 case CODES:
177 base = extra = work; /* dummy value--not used */
178 end = 19;
179 break;
180 case LENS:
181 base = lbase;
182 base -= 257;
183 extra = lext;
184 extra -= 257;
185 end = 256;
186 break;
187 default: /* DISTS */
188 base = dbase;
189 extra = dext;
190 end = -1;
191 }
192
193 /* initialize state for loop */
194 huff = 0; /* starting code */
195 sym = 0; /* starting code symbol */
196 len = min; /* starting code length */
197 next = *table; /* current table to fill in */
198 curr = root; /* current table index bits */
199 drop = 0; /* current bits to drop from code for index */
200 low = (unsigned)(-1); /* trigger new sub-table when len > root */
201 used = 1U << root; /* use root table entries */
202 mask = used - 1; /* mask for comparing low */
203
204 /* check available table space */
205 if (type == LENS && used >= ENOUGH - MAXD)
206 return 1;
207
208 /* process all codes and make table entries */
209 for (;;) {
210 /* create table entry */
211 this.bits = (unsigned char)(len - drop);
212 if ((int)(work[sym]) < end) {
213 this.op = (unsigned char)0;
214 this.val = work[sym];
215 }
216 else if ((int)(work[sym]) > end) {
217 this.op = (unsigned char)(extra[work[sym]]);
218 this.val = base[work[sym]];
219 }
220 else {
221 this.op = (unsigned char)(32 + 64); /* end of block */
222 this.val = 0;
223 }
224
225 /* replicate for those indices with low len bits equal to huff */
226 incr = 1U << (len - drop);
227 fill = 1U << curr;
228 do {
229 fill -= incr;
230 next[(huff >> drop) + fill] = this;
231 } while (fill != 0);
232
233 /* backwards increment the len-bit code huff */
234 incr = 1U << (len - 1);
235 while (huff & incr)
236 incr >>= 1;
237 if (incr != 0) {
238 huff &= incr - 1;
239 huff += incr;
240 }
241 else
242 huff = 0;
243
244 /* go to next symbol, update count, len */
245 sym++;
246 if (--(count[len]) == 0) {
247 if (len == max) break;
248 len = lens[work[sym]];
249 }
250
251 /* create new sub-table if needed */
252 if (len > root && (huff & mask) != low) {
253 /* if first time, transition to sub-tables */
254 if (drop == 0)
255 drop = root;
256
257 /* increment past last table */
258 next += 1U << curr;
259
260 /* determine length of next table */
261 curr = len - drop;
262 left = (int)(1 << curr);
263 while (curr + drop < max) {
264 left -= count[curr + drop];
265 if (left <= 0) break;
266 curr++;
267 left <<= 1;
268 }
269
270 /* check for enough space */
271 used += 1U << curr;
272 if (type == LENS && used >= ENOUGH - MAXD)
273 return 1;
274
275 /* point entry in root table to sub-table */
276 low = huff & mask;
277 (*table)[low].op = (unsigned char)curr;
278 (*table)[low].bits = (unsigned char)root;
279 (*table)[low].val = (unsigned short)(next - *table);
280 }
281 }
282
283 /*
284 Fill in rest of table for incomplete codes. This loop is similar to the
285 loop above in incrementing huff for table indices. It is assumed that
286 len is equal to curr + drop, so there is no loop needed to increment
287 through high index bits. When the current sub-table is filled, the loop
288 drops back to the root table to fill in any remaining entries there.
289 */
290 this.op = (unsigned char)64; /* invalid code marker */
291 this.bits = (unsigned char)(len - drop);
292 this.val = (unsigned short)0;
293 while (huff != 0) {
294 /* when done with sub-table, drop back to root table */
295 if (drop != 0 && (huff & mask) != low) {
296 drop = 0;
297 len = root;
298 next = *table;
299 curr = root;
300 this.bits = (unsigned char)len;
301 }
302
303 /* put invalid code marker in table */
304 next[huff >> drop] = this;
305
306 /* backwards increment the len-bit code huff */
307 incr = 1U << (len - 1);
308 while (huff & incr)
309 incr >>= 1;
310 if (incr != 0) {
311 huff &= incr - 1;
312 huff += incr;
313 }
314 else
315 huff = 0;
316 }
317
318 /* set return parameters */
319 *table += used;
320 *bits = root;
321 return 0;
322 }
0 /* inftree9.h -- header to use inftree9.c
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* Structure for decoding tables. Each entry provides either the
11 information needed to do the operation requested by the code that
12 indexed that table entry, or it provides a pointer to another
13 table that indexes more bits of the code. op indicates whether
14 the entry is a pointer to another table, a literal, a length or
15 distance, an end-of-block, or an invalid code. For a table
16 pointer, the low four bits of op is the number of index bits of
17 that table. For a length or distance, the low four bits of op
18 is the number of extra bits to get after the code. bits is
19 the number of bits in this code or part of the code to drop off
20 of the bit buffer. val is the actual byte to output in the case
21 of a literal, the base length or distance, or the offset from
22 the current table to the next table. Each entry is four bytes. */
23 typedef struct {
24 unsigned char op; /* operation, extra bits, table bits */
25 unsigned char bits; /* bits in this part of the code */
26 unsigned short val; /* offset in table or code value */
27 } code;
28
29 /* op values as set by inflate_table():
30 00000000 - literal
31 0000tttt - table link, tttt != 0 is the number of table index bits
32 100eeeee - length or distance, eeee is the number of extra bits
33 01100000 - end of block
34 01000000 - invalid code
35 */
36
37 /* Maximum size of dynamic tree. The maximum found in a long but non-
38 exhaustive search was 1004 code structures (850 for length/literals
39 and 154 for distances, the latter actually the result of an
40 exhaustive search). The true maximum is not known, but the value
41 below is more than safe. */
42 #define ENOUGH 1440
43 #define MAXD 154
44
45 /* Type of code to build for inftable() */
46 typedef enum {
47 CODES,
48 LENS,
49 DISTS
50 } codetype;
51
52 extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
53 unsigned codes, code FAR * FAR *table,
54 unsigned FAR *bits, unsigned short FAR *work));
0 /* inffas86.c is a hand tuned assembler version of
1 *
2 * inffast.c -- fast decoding
3 * Copyright (C) 1995-2003 Mark Adler
4 * For conditions of distribution and use, see copyright notice in zlib.h
5 *
6 * Copyright (C) 2003 Chris Anderson <christop@charm.net>
7 * Please use the copyright conditions above.
8 *
9 * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
10 * slightly quicker on x86 systems because, instead of using rep movsb to copy
11 * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
12 * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
13 * from http://fedora.linux.duke.edu/fc1_x86_64
14 * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
15 * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
16 * when decompressing mozilla-source-1.3.tar.gz.
17 *
18 * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
19 * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
20 * the moment. I have successfully compiled and tested this code with gcc2.96,
21 * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
22 * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
23 * enabled. I will attempt to merge the MMX code into this version. Newer
24 * versions of this and inffast.S can be found at
25 * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
26 */
27
28 #include "zutil.h"
29 #include "inftrees.h"
30 #include "inflate.h"
31 #include "inffast.h"
32
33 /* Mark Adler's comments from inffast.c: */
34
35 /*
36 Decode literal, length, and distance codes and write out the resulting
37 literal and match bytes until either not enough input or output is
38 available, an end-of-block is encountered, or a data error is encountered.
39 When large enough input and output buffers are supplied to inflate(), for
40 example, a 16K input buffer and a 64K output buffer, more than 95% of the
41 inflate execution time is spent in this routine.
42
43 Entry assumptions:
44
45 state->mode == LEN
46 strm->avail_in >= 6
47 strm->avail_out >= 258
48 start >= strm->avail_out
49 state->bits < 8
50
51 On return, state->mode is one of:
52
53 LEN -- ran out of enough output space or enough available input
54 TYPE -- reached end of block code, inflate() to interpret next block
55 BAD -- error in block data
56
57 Notes:
58
59 - The maximum input bits used by a length/distance pair is 15 bits for the
60 length code, 5 bits for the length extra, 15 bits for the distance code,
61 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
62 Therefore if strm->avail_in >= 6, then there is enough input to avoid
63 checking for available input while decoding.
64
65 - The maximum bytes that a single length/distance pair can output is 258
66 bytes, which is the maximum length that can be coded. inflate_fast()
67 requires strm->avail_out >= 258 for each loop to avoid checking for
68 output space.
69 */
70 void inflate_fast(strm, start)
71 z_streamp strm;
72 unsigned start; /* inflate()'s starting value for strm->avail_out */
73 {
74 struct inflate_state FAR *state;
75 struct inffast_ar {
76 /* 64 32 x86 x86_64 */
77 /* ar offset register */
78 /* 0 0 */ void *esp; /* esp save */
79 /* 8 4 */ void *ebp; /* ebp save */
80 /* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
81 /* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
82 /* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
83 /* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
84 /* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
85 /* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
86 /* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
87 /* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
88 /* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */
89 /* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
90 /* 92 48 */ unsigned wsize; /* window size */
91 /* 96 52 */ unsigned write; /* window write index */
92 /*100 56 */ unsigned lmask; /* r12 mask for lcode */
93 /*104 60 */ unsigned dmask; /* r13 mask for dcode */
94 /*108 64 */ unsigned len; /* r14 match length */
95 /*112 68 */ unsigned dist; /* r15 match distance */
96 /*116 72 */ unsigned status; /* set when state chng*/
97 } ar;
98
99 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
100 #define PAD_AVAIL_IN 6
101 #define PAD_AVAIL_OUT 258
102 #else
103 #define PAD_AVAIL_IN 5
104 #define PAD_AVAIL_OUT 257
105 #endif
106
107 /* copy state to local variables */
108 state = (struct inflate_state FAR *)strm->state;
109 ar.in = strm->next_in;
110 ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
111 ar.out = strm->next_out;
112 ar.beg = ar.out - (start - strm->avail_out);
113 ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
114 ar.wsize = state->wsize;
115 ar.write = state->write;
116 ar.window = state->window;
117 ar.hold = state->hold;
118 ar.bits = state->bits;
119 ar.lcode = state->lencode;
120 ar.dcode = state->distcode;
121 ar.lmask = (1U << state->lenbits) - 1;
122 ar.dmask = (1U << state->distbits) - 1;
123
124 /* decode literals and length/distances until end-of-block or not enough
125 input data or output space */
126
127 /* align in on 1/2 hold size boundary */
128 while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
129 ar.hold += (unsigned long)*ar.in++ << ar.bits;
130 ar.bits += 8;
131 }
132
133 #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
134 __asm__ __volatile__ (
135 " leaq %0, %%rax\n"
136 " movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */
137 " movq %%rsp, (%%rax)\n"
138 " movq %%rax, %%rsp\n" /* make rsp point to &ar */
139 " movq 16(%%rsp), %%rsi\n" /* rsi = in */
140 " movq 32(%%rsp), %%rdi\n" /* rdi = out */
141 " movq 24(%%rsp), %%r9\n" /* r9 = last */
142 " movq 48(%%rsp), %%r10\n" /* r10 = end */
143 " movq 64(%%rsp), %%rbp\n" /* rbp = lcode */
144 " movq 72(%%rsp), %%r11\n" /* r11 = dcode */
145 " movq 80(%%rsp), %%rdx\n" /* rdx = hold */
146 " movl 88(%%rsp), %%ebx\n" /* ebx = bits */
147 " movl 100(%%rsp), %%r12d\n" /* r12d = lmask */
148 " movl 104(%%rsp), %%r13d\n" /* r13d = dmask */
149 /* r14d = len */
150 /* r15d = dist */
151 " cld\n"
152 " cmpq %%rdi, %%r10\n"
153 " je .L_one_time\n" /* if only one decode left */
154 " cmpq %%rsi, %%r9\n"
155 " je .L_one_time\n"
156 " jmp .L_do_loop\n"
157
158 ".L_one_time:\n"
159 " movq %%r12, %%r8\n" /* r8 = lmask */
160 " cmpb $32, %%bl\n"
161 " ja .L_get_length_code_one_time\n"
162
163 " lodsl\n" /* eax = *(uint *)in++ */
164 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
165 " addb $32, %%bl\n" /* bits += 32 */
166 " shlq %%cl, %%rax\n"
167 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
168 " jmp .L_get_length_code_one_time\n"
169
170 ".align 32,0x90\n"
171 ".L_while_test:\n"
172 " cmpq %%rdi, %%r10\n"
173 " jbe .L_break_loop\n"
174 " cmpq %%rsi, %%r9\n"
175 " jbe .L_break_loop\n"
176
177 ".L_do_loop:\n"
178 " movq %%r12, %%r8\n" /* r8 = lmask */
179 " cmpb $32, %%bl\n"
180 " ja .L_get_length_code\n" /* if (32 < bits) */
181
182 " lodsl\n" /* eax = *(uint *)in++ */
183 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
184 " addb $32, %%bl\n" /* bits += 32 */
185 " shlq %%cl, %%rax\n"
186 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
187
188 ".L_get_length_code:\n"
189 " andq %%rdx, %%r8\n" /* r8 &= hold */
190 " movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
191
192 " movb %%ah, %%cl\n" /* cl = this.bits */
193 " subb %%ah, %%bl\n" /* bits -= this.bits */
194 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
195
196 " testb %%al, %%al\n"
197 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
198
199 " movq %%r12, %%r8\n" /* r8 = lmask */
200 " shrl $16, %%eax\n" /* output this.val char */
201 " stosb\n"
202
203 ".L_get_length_code_one_time:\n"
204 " andq %%rdx, %%r8\n" /* r8 &= hold */
205 " movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
206
207 ".L_dolen:\n"
208 " movb %%ah, %%cl\n" /* cl = this.bits */
209 " subb %%ah, %%bl\n" /* bits -= this.bits */
210 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
211
212 " testb %%al, %%al\n"
213 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
214
215 " shrl $16, %%eax\n" /* output this.val char */
216 " stosb\n"
217 " jmp .L_while_test\n"
218
219 ".align 32,0x90\n"
220 ".L_test_for_length_base:\n"
221 " movl %%eax, %%r14d\n" /* len = this */
222 " shrl $16, %%r14d\n" /* len = this.val */
223 " movb %%al, %%cl\n"
224
225 " testb $16, %%al\n"
226 " jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
227 " andb $15, %%cl\n" /* op &= 15 */
228 " jz .L_decode_distance\n" /* if (!op) */
229
230 ".L_add_bits_to_len:\n"
231 " subb %%cl, %%bl\n"
232 " xorl %%eax, %%eax\n"
233 " incl %%eax\n"
234 " shll %%cl, %%eax\n"
235 " decl %%eax\n"
236 " andl %%edx, %%eax\n" /* eax &= hold */
237 " shrq %%cl, %%rdx\n"
238 " addl %%eax, %%r14d\n" /* len += hold & mask[op] */
239
240 ".L_decode_distance:\n"
241 " movq %%r13, %%r8\n" /* r8 = dmask */
242 " cmpb $32, %%bl\n"
243 " ja .L_get_distance_code\n" /* if (32 < bits) */
244
245 " lodsl\n" /* eax = *(uint *)in++ */
246 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
247 " addb $32, %%bl\n" /* bits += 32 */
248 " shlq %%cl, %%rax\n"
249 " orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
250
251 ".L_get_distance_code:\n"
252 " andq %%rdx, %%r8\n" /* r8 &= hold */
253 " movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
254
255 ".L_dodist:\n"
256 " movl %%eax, %%r15d\n" /* dist = this */
257 " shrl $16, %%r15d\n" /* dist = this.val */
258 " movb %%ah, %%cl\n"
259 " subb %%ah, %%bl\n" /* bits -= this.bits */
260 " shrq %%cl, %%rdx\n" /* hold >>= this.bits */
261 " movb %%al, %%cl\n" /* cl = this.op */
262
263 " testb $16, %%al\n" /* if ((op & 16) == 0) */
264 " jz .L_test_for_second_level_dist\n"
265 " andb $15, %%cl\n" /* op &= 15 */
266 " jz .L_check_dist_one\n"
267
268 ".L_add_bits_to_dist:\n"
269 " subb %%cl, %%bl\n"
270 " xorl %%eax, %%eax\n"
271 " incl %%eax\n"
272 " shll %%cl, %%eax\n"
273 " decl %%eax\n" /* (1 << op) - 1 */
274 " andl %%edx, %%eax\n" /* eax &= hold */
275 " shrq %%cl, %%rdx\n"
276 " addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */
277
278 ".L_check_window:\n"
279 " movq %%rsi, %%r8\n" /* save in so from can use it's reg */
280 " movq %%rdi, %%rax\n"
281 " subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */
282
283 " cmpl %%r15d, %%eax\n"
284 " jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
285
286 " movl %%r14d, %%ecx\n" /* ecx = len */
287 " movq %%rdi, %%rsi\n"
288 " subq %%r15, %%rsi\n" /* from = out - dist */
289
290 " sarl %%ecx\n"
291 " jnc .L_copy_two\n" /* if len % 2 == 0 */
292
293 " rep movsw\n"
294 " movb (%%rsi), %%al\n"
295 " movb %%al, (%%rdi)\n"
296 " incq %%rdi\n"
297
298 " movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
299 " jmp .L_while_test\n"
300
301 ".L_copy_two:\n"
302 " rep movsw\n"
303 " movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
304 " jmp .L_while_test\n"
305
306 ".align 32,0x90\n"
307 ".L_check_dist_one:\n"
308 " cmpl $1, %%r15d\n" /* if dist 1, is a memset */
309 " jne .L_check_window\n"
310 " cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */
311 " je .L_check_window\n"
312
313 " movl %%r14d, %%ecx\n" /* ecx = len */
314 " movb -1(%%rdi), %%al\n"
315 " movb %%al, %%ah\n"
316
317 " sarl %%ecx\n"
318 " jnc .L_set_two\n"
319 " movb %%al, (%%rdi)\n"
320 " incq %%rdi\n"
321
322 ".L_set_two:\n"
323 " rep stosw\n"
324 " jmp .L_while_test\n"
325
326 ".align 32,0x90\n"
327 ".L_test_for_second_level_length:\n"
328 " testb $64, %%al\n"
329 " jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
330
331 " xorl %%eax, %%eax\n"
332 " incl %%eax\n"
333 " shll %%cl, %%eax\n"
334 " decl %%eax\n"
335 " andl %%edx, %%eax\n" /* eax &= hold */
336 " addl %%r14d, %%eax\n" /* eax += len */
337 " movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
338 " jmp .L_dolen\n"
339
340 ".align 32,0x90\n"
341 ".L_test_for_second_level_dist:\n"
342 " testb $64, %%al\n"
343 " jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
344
345 " xorl %%eax, %%eax\n"
346 " incl %%eax\n"
347 " shll %%cl, %%eax\n"
348 " decl %%eax\n"
349 " andl %%edx, %%eax\n" /* eax &= hold */
350 " addl %%r15d, %%eax\n" /* eax += dist */
351 " movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
352 " jmp .L_dodist\n"
353
354 ".align 32,0x90\n"
355 ".L_clip_window:\n"
356 " movl %%eax, %%ecx\n" /* ecx = nbytes */
357 " movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */
358 " negl %%ecx\n" /* nbytes = -nbytes */
359
360 " cmpl %%r15d, %%eax\n"
361 " jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
362
363 " addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */
364 " cmpl $0, 96(%%rsp)\n"
365 " jne .L_wrap_around_window\n" /* if (write != 0) */
366
367 " movq 56(%%rsp), %%rsi\n" /* from = window */
368 " subl %%ecx, %%eax\n" /* eax -= nbytes */
369 " addq %%rax, %%rsi\n" /* from += wsize - nbytes */
370
371 " movl %%r14d, %%eax\n" /* eax = len */
372 " cmpl %%ecx, %%r14d\n"
373 " jbe .L_do_copy\n" /* if (nbytes >= len) */
374
375 " subl %%ecx, %%eax\n" /* eax -= nbytes */
376 " rep movsb\n"
377 " movq %%rdi, %%rsi\n"
378 " subq %%r15, %%rsi\n" /* from = &out[ -dist ] */
379 " jmp .L_do_copy\n"
380
381 ".align 32,0x90\n"
382 ".L_wrap_around_window:\n"
383 " movl 96(%%rsp), %%eax\n" /* eax = write */
384 " cmpl %%eax, %%ecx\n"
385 " jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
386
387 " movl 92(%%rsp), %%esi\n" /* from = wsize */
388 " addq 56(%%rsp), %%rsi\n" /* from += window */
389 " addq %%rax, %%rsi\n" /* from += write */
390 " subq %%rcx, %%rsi\n" /* from -= nbytes */
391 " subl %%eax, %%ecx\n" /* nbytes -= write */
392
393 " movl %%r14d, %%eax\n" /* eax = len */
394 " cmpl %%ecx, %%eax\n"
395 " jbe .L_do_copy\n" /* if (nbytes >= len) */
396
397 " subl %%ecx, %%eax\n" /* len -= nbytes */
398 " rep movsb\n"
399 " movq 56(%%rsp), %%rsi\n" /* from = window */
400 " movl 96(%%rsp), %%ecx\n" /* nbytes = write */
401 " cmpl %%ecx, %%eax\n"
402 " jbe .L_do_copy\n" /* if (nbytes >= len) */
403
404 " subl %%ecx, %%eax\n" /* len -= nbytes */
405 " rep movsb\n"
406 " movq %%rdi, %%rsi\n"
407 " subq %%r15, %%rsi\n" /* from = out - dist */
408 " jmp .L_do_copy\n"
409
410 ".align 32,0x90\n"
411 ".L_contiguous_in_window:\n"
412 " movq 56(%%rsp), %%rsi\n" /* rsi = window */
413 " addq %%rax, %%rsi\n"
414 " subq %%rcx, %%rsi\n" /* from += write - nbytes */
415
416 " movl %%r14d, %%eax\n" /* eax = len */
417 " cmpl %%ecx, %%eax\n"
418 " jbe .L_do_copy\n" /* if (nbytes >= len) */
419
420 " subl %%ecx, %%eax\n" /* len -= nbytes */
421 " rep movsb\n"
422 " movq %%rdi, %%rsi\n"
423 " subq %%r15, %%rsi\n" /* from = out - dist */
424 " jmp .L_do_copy\n" /* if (nbytes >= len) */
425
426 ".align 32,0x90\n"
427 ".L_do_copy:\n"
428 " movl %%eax, %%ecx\n" /* ecx = len */
429 " rep movsb\n"
430
431 " movq %%r8, %%rsi\n" /* move in back to %esi, toss from */
432 " jmp .L_while_test\n"
433
434 ".L_test_for_end_of_block:\n"
435 " testb $32, %%al\n"
436 " jz .L_invalid_literal_length_code\n"
437 " movl $1, 116(%%rsp)\n"
438 " jmp .L_break_loop_with_status\n"
439
440 ".L_invalid_literal_length_code:\n"
441 " movl $2, 116(%%rsp)\n"
442 " jmp .L_break_loop_with_status\n"
443
444 ".L_invalid_distance_code:\n"
445 " movl $3, 116(%%rsp)\n"
446 " jmp .L_break_loop_with_status\n"
447
448 ".L_invalid_distance_too_far:\n"
449 " movl $4, 116(%%rsp)\n"
450 " jmp .L_break_loop_with_status\n"
451
452 ".L_break_loop:\n"
453 " movl $0, 116(%%rsp)\n"
454
455 ".L_break_loop_with_status:\n"
456 /* put in, out, bits, and hold back into ar and pop esp */
457 " movq %%rsi, 16(%%rsp)\n" /* in */
458 " movq %%rdi, 32(%%rsp)\n" /* out */
459 " movl %%ebx, 88(%%rsp)\n" /* bits */
460 " movq %%rdx, 80(%%rsp)\n" /* hold */
461 " movq (%%rsp), %%rax\n" /* restore rbp and rsp */
462 " movq 8(%%rsp), %%rbp\n"
463 " movq %%rax, %%rsp\n"
464 :
465 : "m" (ar)
466 : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
467 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
468 );
469 #elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
470 __asm__ __volatile__ (
471 " leal %0, %%eax\n"
472 " movl %%esp, (%%eax)\n" /* save esp, ebp */
473 " movl %%ebp, 4(%%eax)\n"
474 " movl %%eax, %%esp\n"
475 " movl 8(%%esp), %%esi\n" /* esi = in */
476 " movl 16(%%esp), %%edi\n" /* edi = out */
477 " movl 40(%%esp), %%edx\n" /* edx = hold */
478 " movl 44(%%esp), %%ebx\n" /* ebx = bits */
479 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
480
481 " cld\n"
482 " jmp .L_do_loop\n"
483
484 ".align 32,0x90\n"
485 ".L_while_test:\n"
486 " cmpl %%edi, 24(%%esp)\n" /* out < end */
487 " jbe .L_break_loop\n"
488 " cmpl %%esi, 12(%%esp)\n" /* in < last */
489 " jbe .L_break_loop\n"
490
491 ".L_do_loop:\n"
492 " cmpb $15, %%bl\n"
493 " ja .L_get_length_code\n" /* if (15 < bits) */
494
495 " xorl %%eax, %%eax\n"
496 " lodsw\n" /* al = *(ushort *)in++ */
497 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
498 " addb $16, %%bl\n" /* bits += 16 */
499 " shll %%cl, %%eax\n"
500 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
501
502 ".L_get_length_code:\n"
503 " movl 56(%%esp), %%eax\n" /* eax = lmask */
504 " andl %%edx, %%eax\n" /* eax &= hold */
505 " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
506
507 ".L_dolen:\n"
508 " movb %%ah, %%cl\n" /* cl = this.bits */
509 " subb %%ah, %%bl\n" /* bits -= this.bits */
510 " shrl %%cl, %%edx\n" /* hold >>= this.bits */
511
512 " testb %%al, %%al\n"
513 " jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
514
515 " shrl $16, %%eax\n" /* output this.val char */
516 " stosb\n"
517 " jmp .L_while_test\n"
518
519 ".align 32,0x90\n"
520 ".L_test_for_length_base:\n"
521 " movl %%eax, %%ecx\n" /* len = this */
522 " shrl $16, %%ecx\n" /* len = this.val */
523 " movl %%ecx, 64(%%esp)\n" /* save len */
524 " movb %%al, %%cl\n"
525
526 " testb $16, %%al\n"
527 " jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
528 " andb $15, %%cl\n" /* op &= 15 */
529 " jz .L_decode_distance\n" /* if (!op) */
530 " cmpb %%cl, %%bl\n"
531 " jae .L_add_bits_to_len\n" /* if (op <= bits) */
532
533 " movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
534 " xorl %%eax, %%eax\n"
535 " lodsw\n" /* al = *(ushort *)in++ */
536 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
537 " addb $16, %%bl\n" /* bits += 16 */
538 " shll %%cl, %%eax\n"
539 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
540 " movb %%ch, %%cl\n" /* move op back to ecx */
541
542 ".L_add_bits_to_len:\n"
543 " subb %%cl, %%bl\n"
544 " xorl %%eax, %%eax\n"
545 " incl %%eax\n"
546 " shll %%cl, %%eax\n"
547 " decl %%eax\n"
548 " andl %%edx, %%eax\n" /* eax &= hold */
549 " shrl %%cl, %%edx\n"
550 " addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */
551
552 ".L_decode_distance:\n"
553 " cmpb $15, %%bl\n"
554 " ja .L_get_distance_code\n" /* if (15 < bits) */
555
556 " xorl %%eax, %%eax\n"
557 " lodsw\n" /* al = *(ushort *)in++ */
558 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
559 " addb $16, %%bl\n" /* bits += 16 */
560 " shll %%cl, %%eax\n"
561 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
562
563 ".L_get_distance_code:\n"
564 " movl 60(%%esp), %%eax\n" /* eax = dmask */
565 " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
566 " andl %%edx, %%eax\n" /* eax &= hold */
567 " movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
568
569 ".L_dodist:\n"
570 " movl %%eax, %%ebp\n" /* dist = this */
571 " shrl $16, %%ebp\n" /* dist = this.val */
572 " movb %%ah, %%cl\n"
573 " subb %%ah, %%bl\n" /* bits -= this.bits */
574 " shrl %%cl, %%edx\n" /* hold >>= this.bits */
575 " movb %%al, %%cl\n" /* cl = this.op */
576
577 " testb $16, %%al\n" /* if ((op & 16) == 0) */
578 " jz .L_test_for_second_level_dist\n"
579 " andb $15, %%cl\n" /* op &= 15 */
580 " jz .L_check_dist_one\n"
581 " cmpb %%cl, %%bl\n"
582 " jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */
583
584 " movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
585 " xorl %%eax, %%eax\n"
586 " lodsw\n" /* al = *(ushort *)in++ */
587 " movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
588 " addb $16, %%bl\n" /* bits += 16 */
589 " shll %%cl, %%eax\n"
590 " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
591 " movb %%ch, %%cl\n" /* move op back to ecx */
592
593 ".L_add_bits_to_dist:\n"
594 " subb %%cl, %%bl\n"
595 " xorl %%eax, %%eax\n"
596 " incl %%eax\n"
597 " shll %%cl, %%eax\n"
598 " decl %%eax\n" /* (1 << op) - 1 */
599 " andl %%edx, %%eax\n" /* eax &= hold */
600 " shrl %%cl, %%edx\n"
601 " addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
602
603 ".L_check_window:\n"
604 " movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */
605 " movl %%edi, %%eax\n"
606 " subl 20(%%esp), %%eax\n" /* nbytes = out - beg */
607
608 " cmpl %%ebp, %%eax\n"
609 " jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
610
611 " movl 64(%%esp), %%ecx\n" /* ecx = len */
612 " movl %%edi, %%esi\n"
613 " subl %%ebp, %%esi\n" /* from = out - dist */
614
615 " sarl %%ecx\n"
616 " jnc .L_copy_two\n" /* if len % 2 == 0 */
617
618 " rep movsw\n"
619 " movb (%%esi), %%al\n"
620 " movb %%al, (%%edi)\n"
621 " incl %%edi\n"
622
623 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
624 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
625 " jmp .L_while_test\n"
626
627 ".L_copy_two:\n"
628 " rep movsw\n"
629 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
630 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
631 " jmp .L_while_test\n"
632
633 ".align 32,0x90\n"
634 ".L_check_dist_one:\n"
635 " cmpl $1, %%ebp\n" /* if dist 1, is a memset */
636 " jne .L_check_window\n"
637 " cmpl %%edi, 20(%%esp)\n"
638 " je .L_check_window\n" /* out == beg, if outside window */
639
640 " movl 64(%%esp), %%ecx\n" /* ecx = len */
641 " movb -1(%%edi), %%al\n"
642 " movb %%al, %%ah\n"
643
644 " sarl %%ecx\n"
645 " jnc .L_set_two\n"
646 " movb %%al, (%%edi)\n"
647 " incl %%edi\n"
648
649 ".L_set_two:\n"
650 " rep stosw\n"
651 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
652 " jmp .L_while_test\n"
653
654 ".align 32,0x90\n"
655 ".L_test_for_second_level_length:\n"
656 " testb $64, %%al\n"
657 " jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
658
659 " xorl %%eax, %%eax\n"
660 " incl %%eax\n"
661 " shll %%cl, %%eax\n"
662 " decl %%eax\n"
663 " andl %%edx, %%eax\n" /* eax &= hold */
664 " addl 64(%%esp), %%eax\n" /* eax += len */
665 " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
666 " jmp .L_dolen\n"
667
668 ".align 32,0x90\n"
669 ".L_test_for_second_level_dist:\n"
670 " testb $64, %%al\n"
671 " jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
672
673 " xorl %%eax, %%eax\n"
674 " incl %%eax\n"
675 " shll %%cl, %%eax\n"
676 " decl %%eax\n"
677 " andl %%edx, %%eax\n" /* eax &= hold */
678 " addl %%ebp, %%eax\n" /* eax += dist */
679 " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
680 " movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
681 " jmp .L_dodist\n"
682
683 ".align 32,0x90\n"
684 ".L_clip_window:\n"
685 " movl %%eax, %%ecx\n"
686 " movl 48(%%esp), %%eax\n" /* eax = wsize */
687 " negl %%ecx\n" /* nbytes = -nbytes */
688 " movl 28(%%esp), %%esi\n" /* from = window */
689
690 " cmpl %%ebp, %%eax\n"
691 " jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
692
693 " addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
694 " cmpl $0, 52(%%esp)\n"
695 " jne .L_wrap_around_window\n" /* if (write != 0) */
696
697 " subl %%ecx, %%eax\n"
698 " addl %%eax, %%esi\n" /* from += wsize - nbytes */
699
700 " movl 64(%%esp), %%eax\n" /* eax = len */
701 " cmpl %%ecx, %%eax\n"
702 " jbe .L_do_copy\n" /* if (nbytes >= len) */
703
704 " subl %%ecx, %%eax\n" /* len -= nbytes */
705 " rep movsb\n"
706 " movl %%edi, %%esi\n"
707 " subl %%ebp, %%esi\n" /* from = out - dist */
708 " jmp .L_do_copy\n"
709
710 ".align 32,0x90\n"
711 ".L_wrap_around_window:\n"
712 " movl 52(%%esp), %%eax\n" /* eax = write */
713 " cmpl %%eax, %%ecx\n"
714 " jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
715
716 " addl 48(%%esp), %%esi\n" /* from += wsize */
717 " addl %%eax, %%esi\n" /* from += write */
718 " subl %%ecx, %%esi\n" /* from -= nbytes */
719 " subl %%eax, %%ecx\n" /* nbytes -= write */
720
721 " movl 64(%%esp), %%eax\n" /* eax = len */
722 " cmpl %%ecx, %%eax\n"
723 " jbe .L_do_copy\n" /* if (nbytes >= len) */
724
725 " subl %%ecx, %%eax\n" /* len -= nbytes */
726 " rep movsb\n"
727 " movl 28(%%esp), %%esi\n" /* from = window */
728 " movl 52(%%esp), %%ecx\n" /* nbytes = write */
729 " cmpl %%ecx, %%eax\n"
730 " jbe .L_do_copy\n" /* if (nbytes >= len) */
731
732 " subl %%ecx, %%eax\n" /* len -= nbytes */
733 " rep movsb\n"
734 " movl %%edi, %%esi\n"
735 " subl %%ebp, %%esi\n" /* from = out - dist */
736 " jmp .L_do_copy\n"
737
738 ".align 32,0x90\n"
739 ".L_contiguous_in_window:\n"
740 " addl %%eax, %%esi\n"
741 " subl %%ecx, %%esi\n" /* from += write - nbytes */
742
743 " movl 64(%%esp), %%eax\n" /* eax = len */
744 " cmpl %%ecx, %%eax\n"
745 " jbe .L_do_copy\n" /* if (nbytes >= len) */
746
747 " subl %%ecx, %%eax\n" /* len -= nbytes */
748 " rep movsb\n"
749 " movl %%edi, %%esi\n"
750 " subl %%ebp, %%esi\n" /* from = out - dist */
751 " jmp .L_do_copy\n" /* if (nbytes >= len) */
752
753 ".align 32,0x90\n"
754 ".L_do_copy:\n"
755 " movl %%eax, %%ecx\n"
756 " rep movsb\n"
757
758 " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
759 " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
760 " jmp .L_while_test\n"
761
762 ".L_test_for_end_of_block:\n"
763 " testb $32, %%al\n"
764 " jz .L_invalid_literal_length_code\n"
765 " movl $1, 72(%%esp)\n"
766 " jmp .L_break_loop_with_status\n"
767
768 ".L_invalid_literal_length_code:\n"
769 " movl $2, 72(%%esp)\n"
770 " jmp .L_break_loop_with_status\n"
771
772 ".L_invalid_distance_code:\n"
773 " movl $3, 72(%%esp)\n"
774 " jmp .L_break_loop_with_status\n"
775
776 ".L_invalid_distance_too_far:\n"
777 " movl 8(%%esp), %%esi\n"
778 " movl $4, 72(%%esp)\n"
779 " jmp .L_break_loop_with_status\n"
780
781 ".L_break_loop:\n"
782 " movl $0, 72(%%esp)\n"
783
784 ".L_break_loop_with_status:\n"
785 /* put in, out, bits, and hold back into ar and pop esp */
786 " movl %%esi, 8(%%esp)\n" /* save in */
787 " movl %%edi, 16(%%esp)\n" /* save out */
788 " movl %%ebx, 44(%%esp)\n" /* save bits */
789 " movl %%edx, 40(%%esp)\n" /* save hold */
790 " movl 4(%%esp), %%ebp\n" /* restore esp, ebp */
791 " movl (%%esp), %%esp\n"
792 :
793 : "m" (ar)
794 : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
795 );
796 #elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
797 __asm {
798 lea eax, ar
799 mov [eax], esp /* save esp, ebp */
800 mov [eax+4], ebp
801 mov esp, eax
802 mov esi, [esp+8] /* esi = in */
803 mov edi, [esp+16] /* edi = out */
804 mov edx, [esp+40] /* edx = hold */
805 mov ebx, [esp+44] /* ebx = bits */
806 mov ebp, [esp+32] /* ebp = lcode */
807
808 cld
809 jmp L_do_loop
810
811 ALIGN 4
812 L_while_test:
813 cmp [esp+24], edi
814 jbe L_break_loop
815 cmp [esp+12], esi
816 jbe L_break_loop
817
818 L_do_loop:
819 cmp bl, 15
820 ja L_get_length_code /* if (15 < bits) */
821
822 xor eax, eax
823 lodsw /* al = *(ushort *)in++ */
824 mov cl, bl /* cl = bits, needs it for shifting */
825 add bl, 16 /* bits += 16 */
826 shl eax, cl
827 or edx, eax /* hold |= *((ushort *)in)++ << bits */
828
829 L_get_length_code:
830 mov eax, [esp+56] /* eax = lmask */
831 and eax, edx /* eax &= hold */
832 mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
833
834 L_dolen:
835 mov cl, ah /* cl = this.bits */
836 sub bl, ah /* bits -= this.bits */
837 shr edx, cl /* hold >>= this.bits */
838
839 test al, al
840 jnz L_test_for_length_base /* if (op != 0) 45.7% */
841
842 shr eax, 16 /* output this.val char */
843 stosb
844 jmp L_while_test
845
846 ALIGN 4
847 L_test_for_length_base:
848 mov ecx, eax /* len = this */
849 shr ecx, 16 /* len = this.val */
850 mov [esp+64], ecx /* save len */
851 mov cl, al
852
853 test al, 16
854 jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
855 and cl, 15 /* op &= 15 */
856 jz L_decode_distance /* if (!op) */
857 cmp bl, cl
858 jae L_add_bits_to_len /* if (op <= bits) */
859
860 mov ch, cl /* stash op in ch, freeing cl */
861 xor eax, eax
862 lodsw /* al = *(ushort *)in++ */
863 mov cl, bl /* cl = bits, needs it for shifting */
864 add bl, 16 /* bits += 16 */
865 shl eax, cl
866 or edx, eax /* hold |= *((ushort *)in)++ << bits */
867 mov cl, ch /* move op back to ecx */
868
869 L_add_bits_to_len:
870 sub bl, cl
871 xor eax, eax
872 inc eax
873 shl eax, cl
874 dec eax
875 and eax, edx /* eax &= hold */
876 shr edx, cl
877 add [esp+64], eax /* len += hold & mask[op] */
878
879 L_decode_distance:
880 cmp bl, 15
881 ja L_get_distance_code /* if (15 < bits) */
882
883 xor eax, eax
884 lodsw /* al = *(ushort *)in++ */
885 mov cl, bl /* cl = bits, needs it for shifting */
886 add bl, 16 /* bits += 16 */
887 shl eax, cl
888 or edx, eax /* hold |= *((ushort *)in)++ << bits */
889
890 L_get_distance_code:
891 mov eax, [esp+60] /* eax = dmask */
892 mov ecx, [esp+36] /* ecx = dcode */
893 and eax, edx /* eax &= hold */
894 mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
895
896 L_dodist:
897 mov ebp, eax /* dist = this */
898 shr ebp, 16 /* dist = this.val */
899 mov cl, ah
900 sub bl, ah /* bits -= this.bits */
901 shr edx, cl /* hold >>= this.bits */
902 mov cl, al /* cl = this.op */
903
904 test al, 16 /* if ((op & 16) == 0) */
905 jz L_test_for_second_level_dist
906 and cl, 15 /* op &= 15 */
907 jz L_check_dist_one
908 cmp bl, cl
909 jae L_add_bits_to_dist /* if (op <= bits) 97.6% */
910
911 mov ch, cl /* stash op in ch, freeing cl */
912 xor eax, eax
913 lodsw /* al = *(ushort *)in++ */
914 mov cl, bl /* cl = bits, needs it for shifting */
915 add bl, 16 /* bits += 16 */
916 shl eax, cl
917 or edx, eax /* hold |= *((ushort *)in)++ << bits */
918 mov cl, ch /* move op back to ecx */
919
920 L_add_bits_to_dist:
921 sub bl, cl
922 xor eax, eax
923 inc eax
924 shl eax, cl
925 dec eax /* (1 << op) - 1 */
926 and eax, edx /* eax &= hold */
927 shr edx, cl
928 add ebp, eax /* dist += hold & ((1 << op) - 1) */
929
930 L_check_window:
931 mov [esp+8], esi /* save in so from can use it's reg */
932 mov eax, edi
933 sub eax, [esp+20] /* nbytes = out - beg */
934
935 cmp eax, ebp
936 jb L_clip_window /* if (dist > nbytes) 4.2% */
937
938 mov ecx, [esp+64] /* ecx = len */
939 mov esi, edi
940 sub esi, ebp /* from = out - dist */
941
942 sar ecx, 1
943 jnc L_copy_two
944
945 rep movsw
946 mov al, [esi]
947 mov [edi], al
948 inc edi
949
950 mov esi, [esp+8] /* move in back to %esi, toss from */
951 mov ebp, [esp+32] /* ebp = lcode */
952 jmp L_while_test
953
954 L_copy_two:
955 rep movsw
956 mov esi, [esp+8] /* move in back to %esi, toss from */
957 mov ebp, [esp+32] /* ebp = lcode */
958 jmp L_while_test
959
960 ALIGN 4
961 L_check_dist_one:
962 cmp ebp, 1 /* if dist 1, is a memset */
963 jne L_check_window
964 cmp [esp+20], edi
965 je L_check_window /* out == beg, if outside window */
966
967 mov ecx, [esp+64] /* ecx = len */
968 mov al, [edi-1]
969 mov ah, al
970
971 sar ecx, 1
972 jnc L_set_two
973 mov [edi], al /* memset out with from[-1] */
974 inc edi
975
976 L_set_two:
977 rep stosw
978 mov ebp, [esp+32] /* ebp = lcode */
979 jmp L_while_test
980
981 ALIGN 4
982 L_test_for_second_level_length:
983 test al, 64
984 jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
985
986 xor eax, eax
987 inc eax
988 shl eax, cl
989 dec eax
990 and eax, edx /* eax &= hold */
991 add eax, [esp+64] /* eax += len */
992 mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
993 jmp L_dolen
994
995 ALIGN 4
996 L_test_for_second_level_dist:
997 test al, 64
998 jnz L_invalid_distance_code /* if ((op & 64) != 0) */
999
1000 xor eax, eax
1001 inc eax
1002 shl eax, cl
1003 dec eax
1004 and eax, edx /* eax &= hold */
1005 add eax, ebp /* eax += dist */
1006 mov ecx, [esp+36] /* ecx = dcode */
1007 mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
1008 jmp L_dodist
1009
1010 ALIGN 4
1011 L_clip_window:
1012 mov ecx, eax
1013 mov eax, [esp+48] /* eax = wsize */
1014 neg ecx /* nbytes = -nbytes */
1015 mov esi, [esp+28] /* from = window */
1016
1017 cmp eax, ebp
1018 jb L_invalid_distance_too_far /* if (dist > wsize) */
1019
1020 add ecx, ebp /* nbytes = dist - nbytes */
1021 cmp dword ptr [esp+52], 0
1022 jne L_wrap_around_window /* if (write != 0) */
1023
1024 sub eax, ecx
1025 add esi, eax /* from += wsize - nbytes */
1026
1027 mov eax, [esp+64] /* eax = len */
1028 cmp eax, ecx
1029 jbe L_do_copy /* if (nbytes >= len) */
1030
1031 sub eax, ecx /* len -= nbytes */
1032 rep movsb
1033 mov esi, edi
1034 sub esi, ebp /* from = out - dist */
1035 jmp L_do_copy
1036
1037 ALIGN 4
1038 L_wrap_around_window:
1039 mov eax, [esp+52] /* eax = write */
1040 cmp ecx, eax
1041 jbe L_contiguous_in_window /* if (write >= nbytes) */
1042
1043 add esi, [esp+48] /* from += wsize */
1044 add esi, eax /* from += write */
1045 sub esi, ecx /* from -= nbytes */
1046 sub ecx, eax /* nbytes -= write */
1047
1048 mov eax, [esp+64] /* eax = len */
1049 cmp eax, ecx
1050 jbe L_do_copy /* if (nbytes >= len) */
1051
1052 sub eax, ecx /* len -= nbytes */
1053 rep movsb
1054 mov esi, [esp+28] /* from = window */
1055 mov ecx, [esp+52] /* nbytes = write */
1056 cmp eax, ecx
1057 jbe L_do_copy /* if (nbytes >= len) */
1058
1059 sub eax, ecx /* len -= nbytes */
1060 rep movsb
1061 mov esi, edi
1062 sub esi, ebp /* from = out - dist */
1063 jmp L_do_copy
1064
1065 ALIGN 4
1066 L_contiguous_in_window:
1067 add esi, eax
1068 sub esi, ecx /* from += write - nbytes */
1069
1070 mov eax, [esp+64] /* eax = len */
1071 cmp eax, ecx
1072 jbe L_do_copy /* if (nbytes >= len) */
1073
1074 sub eax, ecx /* len -= nbytes */
1075 rep movsb
1076 mov esi, edi
1077 sub esi, ebp /* from = out - dist */
1078 jmp L_do_copy
1079
1080 ALIGN 4
1081 L_do_copy:
1082 mov ecx, eax
1083 rep movsb
1084
1085 mov esi, [esp+8] /* move in back to %esi, toss from */
1086 mov ebp, [esp+32] /* ebp = lcode */
1087 jmp L_while_test
1088
1089 L_test_for_end_of_block:
1090 test al, 32
1091 jz L_invalid_literal_length_code
1092 mov dword ptr [esp+72], 1
1093 jmp L_break_loop_with_status
1094
1095 L_invalid_literal_length_code:
1096 mov dword ptr [esp+72], 2
1097 jmp L_break_loop_with_status
1098
1099 L_invalid_distance_code:
1100 mov dword ptr [esp+72], 3
1101 jmp L_break_loop_with_status
1102
1103 L_invalid_distance_too_far:
1104 mov esi, [esp+4]
1105 mov dword ptr [esp+72], 4
1106 jmp L_break_loop_with_status
1107
1108 L_break_loop:
1109 mov dword ptr [esp+72], 0
1110
1111 L_break_loop_with_status:
1112 /* put in, out, bits, and hold back into ar and pop esp */
1113 mov [esp+8], esi /* save in */
1114 mov [esp+16], edi /* save out */
1115 mov [esp+44], ebx /* save bits */
1116 mov [esp+40], edx /* save hold */
1117 mov ebp, [esp+4] /* restore esp, ebp */
1118 mov esp, [esp]
1119 }
1120 #else
1121 #error "x86 architecture not defined"
1122 #endif
1123
1124 if (ar.status > 1) {
1125 if (ar.status == 2)
1126 strm->msg = "invalid literal/length code";
1127 else if (ar.status == 3)
1128 strm->msg = "invalid distance code";
1129 else
1130 strm->msg = "invalid distance too far back";
1131 state->mode = BAD;
1132 }
1133 else if ( ar.status == 1 ) {
1134 state->mode = TYPE;
1135 }
1136
1137 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
1138 ar.len = ar.bits >> 3;
1139 ar.in -= ar.len;
1140 ar.bits -= ar.len << 3;
1141 ar.hold &= (1U << ar.bits) - 1;
1142
1143 /* update state and return */
1144 strm->next_in = ar.in;
1145 strm->next_out = ar.out;
1146 strm->avail_in = (unsigned)(ar.in < ar.last ?
1147 PAD_AVAIL_IN + (ar.last - ar.in) :
1148 PAD_AVAIL_IN - (ar.in - ar.last));
1149 strm->avail_out = (unsigned)(ar.out < ar.end ?
1150 PAD_AVAIL_OUT + (ar.end - ar.out) :
1151 PAD_AVAIL_OUT - (ar.out - ar.end));
1152 state->hold = ar.hold;
1153 state->bits = ar.bits;
1154 return;
1155 }
1156
0 /*
1 * inffast.S is a hand tuned assembler version of:
2 *
3 * inffast.c -- fast decoding
4 * Copyright (C) 1995-2003 Mark Adler
5 * For conditions of distribution and use, see copyright notice in zlib.h
6 *
7 * Copyright (C) 2003 Chris Anderson <christop@charm.net>
8 * Please use the copyright conditions above.
9 *
10 * This version (Jan-23-2003) of inflate_fast was coded and tested under
11 * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that
12 * machine, I found that gzip style archives decompressed about 20% faster than
13 * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will
14 * depend on how large of a buffer is used for z_stream.next_in & next_out
15 * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in
16 * stream processing I/O and crc32/addler32. In my case, this routine used
17 * 70% of the cpu time and crc32 used 20%.
18 *
19 * I am confident that this version will work in the general case, but I have
20 * not tested a wide variety of datasets or a wide variety of platforms.
21 *
22 * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.
23 * It should be a runtime flag instead of compile time flag...
24 *
25 * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.
26 * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code
27 * is compiled. Without either option, runtime detection is enabled. Runtime
28 * detection should work on all modern cpus and the recomended algorithm (flip
29 * ID bit on eflags and then use the cpuid instruction) is used in many
30 * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12
31 * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o
32 * inffast.obj generates a COFF object which can then be linked with MSVC++
33 * compiled code. Tested under FreeBSD 4.7 with gcc-2.95.
34 *
35 * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and
36 * slower than compiler generated code). Adjusted cpuid check to use the MMX
37 * code only for Pentiums < P4 until I have more data on the P4. Speed
38 * improvment is only about 15% on the Athlon when compared with code generated
39 * with MSVC++. Not sure yet, but I think the P4 will also be slower using the
40 * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and
41 * have less latency than MMX ops. Added code to buffer the last 11 bytes of
42 * the input stream since the MMX code grabs bits in chunks of 32, which
43 * differs from the inffast.c algorithm. I don't think there would have been
44 * read overruns where a page boundary was crossed (a segfault), but there
45 * could have been overruns when next_in ends on unaligned memory (unintialized
46 * memory read).
47 *
48 * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C
49 * version of the non-MMX code so that it doesn't depend on zstrm and zstate
50 * structure offsets which are hard coded in this file. This was last tested
51 * with zlib-1.2.0 which is currently in beta testing, newer versions of this
52 * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and
53 * http://www.charm.net/~christop/zlib/
54 */
55
56
57 /*
58 * if you have underscore linking problems (_inflate_fast undefined), try
59 * using -DGAS_COFF
60 */
61 #if ! defined( GAS_COFF ) && ! defined( GAS_ELF )
62
63 #if defined( WIN32 ) || defined( __CYGWIN__ )
64 #define GAS_COFF /* windows object format */
65 #else
66 #define GAS_ELF
67 #endif
68
69 #endif /* ! GAS_COFF && ! GAS_ELF */
70
71
72 #if defined( GAS_COFF )
73
74 /* coff externals have underscores */
75 #define inflate_fast _inflate_fast
76 #define inflate_fast_use_mmx _inflate_fast_use_mmx
77
78 #endif /* GAS_COFF */
79
80
81 .file "inffast.S"
82
83 .globl inflate_fast
84
85 .text
86 .align 4,0
87 .L_invalid_literal_length_code_msg:
88 .string "invalid literal/length code"
89
90 .align 4,0
91 .L_invalid_distance_code_msg:
92 .string "invalid distance code"
93
94 .align 4,0
95 .L_invalid_distance_too_far_msg:
96 .string "invalid distance too far back"
97
98 #if ! defined( NO_MMX )
99 .align 4,0
100 .L_mask: /* mask[N] = ( 1 << N ) - 1 */
101 .long 0
102 .long 1
103 .long 3
104 .long 7
105 .long 15
106 .long 31
107 .long 63
108 .long 127
109 .long 255
110 .long 511
111 .long 1023
112 .long 2047
113 .long 4095
114 .long 8191
115 .long 16383
116 .long 32767
117 .long 65535
118 .long 131071
119 .long 262143
120 .long 524287
121 .long 1048575
122 .long 2097151
123 .long 4194303
124 .long 8388607
125 .long 16777215
126 .long 33554431
127 .long 67108863
128 .long 134217727
129 .long 268435455
130 .long 536870911
131 .long 1073741823
132 .long 2147483647
133 .long 4294967295
134 #endif /* NO_MMX */
135
136 .text
137
138 /*
139 * struct z_stream offsets, in zlib.h
140 */
141 #define next_in_strm 0 /* strm->next_in */
142 #define avail_in_strm 4 /* strm->avail_in */
143 #define next_out_strm 12 /* strm->next_out */
144 #define avail_out_strm 16 /* strm->avail_out */
145 #define msg_strm 24 /* strm->msg */
146 #define state_strm 28 /* strm->state */
147
148 /*
149 * struct inflate_state offsets, in inflate.h
150 */
151 #define mode_state 0 /* state->mode */
152 #define wsize_state 32 /* state->wsize */
153 #define write_state 40 /* state->write */
154 #define window_state 44 /* state->window */
155 #define hold_state 48 /* state->hold */
156 #define bits_state 52 /* state->bits */
157 #define lencode_state 68 /* state->lencode */
158 #define distcode_state 72 /* state->distcode */
159 #define lenbits_state 76 /* state->lenbits */
160 #define distbits_state 80 /* state->distbits */
161
162 /*
163 * inflate_fast's activation record
164 */
165 #define local_var_size 64 /* how much local space for vars */
166 #define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */
167 #define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */
168
169 /*
170 * offsets for local vars on stack
171 */
172 #define out 60 /* unsigned char* */
173 #define window 56 /* unsigned char* */
174 #define wsize 52 /* unsigned int */
175 #define write 48 /* unsigned int */
176 #define in 44 /* unsigned char* */
177 #define beg 40 /* unsigned char* */
178 #define buf 28 /* char[ 12 ] */
179 #define len 24 /* unsigned int */
180 #define last 20 /* unsigned char* */
181 #define end 16 /* unsigned char* */
182 #define dcode 12 /* code* */
183 #define lcode 8 /* code* */
184 #define dmask 4 /* unsigned int */
185 #define lmask 0 /* unsigned int */
186
187 /*
188 * typedef enum inflate_mode consts, in inflate.h
189 */
190 #define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
191 #define INFLATE_MODE_BAD 26
192
193
194 #if ! defined( USE_MMX ) && ! defined( NO_MMX )
195
196 #define RUN_TIME_MMX
197
198 #define CHECK_MMX 1
199 #define DO_USE_MMX 2
200 #define DONT_USE_MMX 3
201
202 .globl inflate_fast_use_mmx
203
204 .data
205
206 .align 4,0
207 inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */
208 .long CHECK_MMX
209
210 #if defined( GAS_ELF )
211 /* elf info */
212 .type inflate_fast_use_mmx,@object
213 .size inflate_fast_use_mmx,4
214 #endif
215
216 #endif /* RUN_TIME_MMX */
217
218 #if defined( GAS_COFF )
219 /* coff info: scl 2 = extern, type 32 = function */
220 .def inflate_fast; .scl 2; .type 32; .endef
221 #endif
222
223 .text
224
225 .align 32,0x90
226 inflate_fast:
227 pushl %edi
228 pushl %esi
229 pushl %ebp
230 pushl %ebx
231 pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */
232 subl $local_var_size, %esp
233 cld
234
235 #define strm_r %esi
236 #define state_r %edi
237
238 movl strm_sp(%esp), strm_r
239 movl state_strm(strm_r), state_r
240
241 /* in = strm->next_in;
242 * out = strm->next_out;
243 * last = in + strm->avail_in - 11;
244 * beg = out - (start - strm->avail_out);
245 * end = out + (strm->avail_out - 257);
246 */
247 movl avail_in_strm(strm_r), %edx
248 movl next_in_strm(strm_r), %eax
249
250 addl %eax, %edx /* avail_in += next_in */
251 subl $11, %edx /* avail_in -= 11 */
252
253 movl %eax, in(%esp)
254 movl %edx, last(%esp)
255
256 movl start_sp(%esp), %ebp
257 movl avail_out_strm(strm_r), %ecx
258 movl next_out_strm(strm_r), %ebx
259
260 subl %ecx, %ebp /* start -= avail_out */
261 negl %ebp /* start = -start */
262 addl %ebx, %ebp /* start += next_out */
263
264 subl $257, %ecx /* avail_out -= 257 */
265 addl %ebx, %ecx /* avail_out += out */
266
267 movl %ebx, out(%esp)
268 movl %ebp, beg(%esp)
269 movl %ecx, end(%esp)
270
271 /* wsize = state->wsize;
272 * write = state->write;
273 * window = state->window;
274 * hold = state->hold;
275 * bits = state->bits;
276 * lcode = state->lencode;
277 * dcode = state->distcode;
278 * lmask = ( 1 << state->lenbits ) - 1;
279 * dmask = ( 1 << state->distbits ) - 1;
280 */
281
282 movl lencode_state(state_r), %eax
283 movl distcode_state(state_r), %ecx
284
285 movl %eax, lcode(%esp)
286 movl %ecx, dcode(%esp)
287
288 movl $1, %eax
289 movl lenbits_state(state_r), %ecx
290 shll %cl, %eax
291 decl %eax
292 movl %eax, lmask(%esp)
293
294 movl $1, %eax
295 movl distbits_state(state_r), %ecx
296 shll %cl, %eax
297 decl %eax
298 movl %eax, dmask(%esp)
299
300 movl wsize_state(state_r), %eax
301 movl write_state(state_r), %ecx
302 movl window_state(state_r), %edx
303
304 movl %eax, wsize(%esp)
305 movl %ecx, write(%esp)
306 movl %edx, window(%esp)
307
308 movl hold_state(state_r), %ebp
309 movl bits_state(state_r), %ebx
310
311 #undef strm_r
312 #undef state_r
313
314 #define in_r %esi
315 #define from_r %esi
316 #define out_r %edi
317
318 movl in(%esp), in_r
319 movl last(%esp), %ecx
320 cmpl in_r, %ecx
321 ja .L_align_long /* if in < last */
322
323 addl $11, %ecx /* ecx = &in[ avail_in ] */
324 subl in_r, %ecx /* ecx = avail_in */
325 movl $12, %eax
326 subl %ecx, %eax /* eax = 12 - avail_in */
327 leal buf(%esp), %edi
328 rep movsb /* memcpy( buf, in, avail_in ) */
329 movl %eax, %ecx
330 xorl %eax, %eax
331 rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */
332 leal buf(%esp), in_r /* in = buf */
333 movl in_r, last(%esp) /* last = in, do just one iteration */
334 jmp .L_is_aligned
335
336 /* align in_r on long boundary */
337 .L_align_long:
338 testl $3, in_r
339 jz .L_is_aligned
340 xorl %eax, %eax
341 movb (in_r), %al
342 incl in_r
343 movl %ebx, %ecx
344 addl $8, %ebx
345 shll %cl, %eax
346 orl %eax, %ebp
347 jmp .L_align_long
348
349 .L_is_aligned:
350 movl out(%esp), out_r
351
352 #if defined( NO_MMX )
353 jmp .L_do_loop
354 #endif
355
356 #if defined( USE_MMX )
357 jmp .L_init_mmx
358 #endif
359
360 /*** Runtime MMX check ***/
361
362 #if defined( RUN_TIME_MMX )
363 .L_check_mmx:
364 cmpl $DO_USE_MMX, inflate_fast_use_mmx
365 je .L_init_mmx
366 ja .L_do_loop /* > 2 */
367
368 pushl %eax
369 pushl %ebx
370 pushl %ecx
371 pushl %edx
372 pushf
373 movl (%esp), %eax /* copy eflags to eax */
374 xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)
375 * to see if cpu supports cpuid...
376 * ID bit method not supported by NexGen but
377 * bios may load a cpuid instruction and
378 * cpuid may be disabled on Cyrix 5-6x86 */
379 popf
380 pushf
381 popl %edx /* copy new eflags to edx */
382 xorl %eax, %edx /* test if ID bit is flipped */
383 jz .L_dont_use_mmx /* not flipped if zero */
384 xorl %eax, %eax
385 cpuid
386 cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */
387 jne .L_dont_use_mmx
388 cmpl $0x6c65746e, %ecx
389 jne .L_dont_use_mmx
390 cmpl $0x49656e69, %edx
391 jne .L_dont_use_mmx
392 movl $1, %eax
393 cpuid /* get cpu features */
394 shrl $8, %eax
395 andl $15, %eax
396 cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */
397 jne .L_dont_use_mmx
398 testl $0x800000, %edx /* test if MMX feature is set (bit 23) */
399 jnz .L_use_mmx
400 jmp .L_dont_use_mmx
401 .L_use_mmx:
402 movl $DO_USE_MMX, inflate_fast_use_mmx
403 jmp .L_check_mmx_pop
404 .L_dont_use_mmx:
405 movl $DONT_USE_MMX, inflate_fast_use_mmx
406 .L_check_mmx_pop:
407 popl %edx
408 popl %ecx
409 popl %ebx
410 popl %eax
411 jmp .L_check_mmx
412 #endif
413
414
415 /*** Non-MMX code ***/
416
417 #if defined ( NO_MMX ) || defined( RUN_TIME_MMX )
418
419 #define hold_r %ebp
420 #define bits_r %bl
421 #define bitslong_r %ebx
422
423 .align 32,0x90
424 .L_while_test:
425 /* while (in < last && out < end)
426 */
427 cmpl out_r, end(%esp)
428 jbe .L_break_loop /* if (out >= end) */
429
430 cmpl in_r, last(%esp)
431 jbe .L_break_loop
432
433 .L_do_loop:
434 /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
435 *
436 * do {
437 * if (bits < 15) {
438 * hold |= *((unsigned short *)in)++ << bits;
439 * bits += 16
440 * }
441 * this = lcode[hold & lmask]
442 */
443 cmpb $15, bits_r
444 ja .L_get_length_code /* if (15 < bits) */
445
446 xorl %eax, %eax
447 lodsw /* al = *(ushort *)in++ */
448 movb bits_r, %cl /* cl = bits, needs it for shifting */
449 addb $16, bits_r /* bits += 16 */
450 shll %cl, %eax
451 orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
452
453 .L_get_length_code:
454 movl lmask(%esp), %edx /* edx = lmask */
455 movl lcode(%esp), %ecx /* ecx = lcode */
456 andl hold_r, %edx /* edx &= hold */
457 movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */
458
459 .L_dolen:
460 /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
461 *
462 * dolen:
463 * bits -= this.bits;
464 * hold >>= this.bits
465 */
466 movb %ah, %cl /* cl = this.bits */
467 subb %ah, bits_r /* bits -= this.bits */
468 shrl %cl, hold_r /* hold >>= this.bits */
469
470 /* check if op is a literal
471 * if (op == 0) {
472 * PUP(out) = this.val;
473 * }
474 */
475 testb %al, %al
476 jnz .L_test_for_length_base /* if (op != 0) 45.7% */
477
478 shrl $16, %eax /* output this.val char */
479 stosb
480 jmp .L_while_test
481
482 .L_test_for_length_base:
483 /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
484 *
485 * else if (op & 16) {
486 * len = this.val
487 * op &= 15
488 * if (op) {
489 * if (op > bits) {
490 * hold |= *((unsigned short *)in)++ << bits;
491 * bits += 16
492 * }
493 * len += hold & mask[op];
494 * bits -= op;
495 * hold >>= op;
496 * }
497 */
498 #define len_r %edx
499 movl %eax, len_r /* len = this */
500 shrl $16, len_r /* len = this.val */
501 movb %al, %cl
502
503 testb $16, %al
504 jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
505 andb $15, %cl /* op &= 15 */
506 jz .L_save_len /* if (!op) */
507 cmpb %cl, bits_r
508 jae .L_add_bits_to_len /* if (op <= bits) */
509
510 movb %cl, %ch /* stash op in ch, freeing cl */
511 xorl %eax, %eax
512 lodsw /* al = *(ushort *)in++ */
513 movb bits_r, %cl /* cl = bits, needs it for shifting */
514 addb $16, bits_r /* bits += 16 */
515 shll %cl, %eax
516 orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
517 movb %ch, %cl /* move op back to ecx */
518
519 .L_add_bits_to_len:
520 movl $1, %eax
521 shll %cl, %eax
522 decl %eax
523 subb %cl, bits_r
524 andl hold_r, %eax /* eax &= hold */
525 shrl %cl, hold_r
526 addl %eax, len_r /* len += hold & mask[op] */
527
528 .L_save_len:
529 movl len_r, len(%esp) /* save len */
530 #undef len_r
531
532 .L_decode_distance:
533 /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
534 *
535 * if (bits < 15) {
536 * hold |= *((unsigned short *)in)++ << bits;
537 * bits += 16
538 * }
539 * this = dcode[hold & dmask];
540 * dodist:
541 * bits -= this.bits;
542 * hold >>= this.bits;
543 * op = this.op;
544 */
545
546 cmpb $15, bits_r
547 ja .L_get_distance_code /* if (15 < bits) */
548
549 xorl %eax, %eax
550 lodsw /* al = *(ushort *)in++ */
551 movb bits_r, %cl /* cl = bits, needs it for shifting */
552 addb $16, bits_r /* bits += 16 */
553 shll %cl, %eax
554 orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
555
556 .L_get_distance_code:
557 movl dmask(%esp), %edx /* edx = dmask */
558 movl dcode(%esp), %ecx /* ecx = dcode */
559 andl hold_r, %edx /* edx &= hold */
560 movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */
561
562 #define dist_r %edx
563 .L_dodist:
564 movl %eax, dist_r /* dist = this */
565 shrl $16, dist_r /* dist = this.val */
566 movb %ah, %cl
567 subb %ah, bits_r /* bits -= this.bits */
568 shrl %cl, hold_r /* hold >>= this.bits */
569
570 /* if (op & 16) {
571 * dist = this.val
572 * op &= 15
573 * if (op > bits) {
574 * hold |= *((unsigned short *)in)++ << bits;
575 * bits += 16
576 * }
577 * dist += hold & mask[op];
578 * bits -= op;
579 * hold >>= op;
580 */
581 movb %al, %cl /* cl = this.op */
582
583 testb $16, %al /* if ((op & 16) == 0) */
584 jz .L_test_for_second_level_dist
585 andb $15, %cl /* op &= 15 */
586 jz .L_check_dist_one
587 cmpb %cl, bits_r
588 jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */
589
590 movb %cl, %ch /* stash op in ch, freeing cl */
591 xorl %eax, %eax
592 lodsw /* al = *(ushort *)in++ */
593 movb bits_r, %cl /* cl = bits, needs it for shifting */
594 addb $16, bits_r /* bits += 16 */
595 shll %cl, %eax
596 orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
597 movb %ch, %cl /* move op back to ecx */
598
599 .L_add_bits_to_dist:
600 movl $1, %eax
601 shll %cl, %eax
602 decl %eax /* (1 << op) - 1 */
603 subb %cl, bits_r
604 andl hold_r, %eax /* eax &= hold */
605 shrl %cl, hold_r
606 addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */
607 jmp .L_check_window
608
609 .L_check_window:
610 /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
611 * %ecx = nbytes
612 *
613 * nbytes = out - beg;
614 * if (dist <= nbytes) {
615 * from = out - dist;
616 * do {
617 * PUP(out) = PUP(from);
618 * } while (--len > 0) {
619 * }
620 */
621
622 movl in_r, in(%esp) /* save in so from can use it's reg */
623 movl out_r, %eax
624 subl beg(%esp), %eax /* nbytes = out - beg */
625
626 cmpl dist_r, %eax
627 jb .L_clip_window /* if (dist > nbytes) 4.2% */
628
629 movl len(%esp), %ecx
630 movl out_r, from_r
631 subl dist_r, from_r /* from = out - dist */
632
633 subl $3, %ecx
634 movb (from_r), %al
635 movb %al, (out_r)
636 movb 1(from_r), %al
637 movb 2(from_r), %dl
638 addl $3, from_r
639 movb %al, 1(out_r)
640 movb %dl, 2(out_r)
641 addl $3, out_r
642 rep movsb
643
644 movl in(%esp), in_r /* move in back to %esi, toss from */
645 jmp .L_while_test
646
647 .align 16,0x90
648 .L_check_dist_one:
649 cmpl $1, dist_r
650 jne .L_check_window
651 cmpl out_r, beg(%esp)
652 je .L_check_window
653
654 decl out_r
655 movl len(%esp), %ecx
656 movb (out_r), %al
657 subl $3, %ecx
658
659 movb %al, 1(out_r)
660 movb %al, 2(out_r)
661 movb %al, 3(out_r)
662 addl $4, out_r
663 rep stosb
664
665 jmp .L_while_test
666
667 .align 16,0x90
668 .L_test_for_second_level_length:
669 /* else if ((op & 64) == 0) {
670 * this = lcode[this.val + (hold & mask[op])];
671 * }
672 */
673 testb $64, %al
674 jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
675
676 movl $1, %eax
677 shll %cl, %eax
678 decl %eax
679 andl hold_r, %eax /* eax &= hold */
680 addl %edx, %eax /* eax += this.val */
681 movl lcode(%esp), %edx /* edx = lcode */
682 movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */
683 jmp .L_dolen
684
685 .align 16,0x90
686 .L_test_for_second_level_dist:
687 /* else if ((op & 64) == 0) {
688 * this = dcode[this.val + (hold & mask[op])];
689 * }
690 */
691 testb $64, %al
692 jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
693
694 movl $1, %eax
695 shll %cl, %eax
696 decl %eax
697 andl hold_r, %eax /* eax &= hold */
698 addl %edx, %eax /* eax += this.val */
699 movl dcode(%esp), %edx /* edx = dcode */
700 movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */
701 jmp .L_dodist
702
703 .align 16,0x90
704 .L_clip_window:
705 /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
706 * %ecx = nbytes
707 *
708 * else {
709 * if (dist > wsize) {
710 * invalid distance
711 * }
712 * from = window;
713 * nbytes = dist - nbytes;
714 * if (write == 0) {
715 * from += wsize - nbytes;
716 */
717 #define nbytes_r %ecx
718 movl %eax, nbytes_r
719 movl wsize(%esp), %eax /* prepare for dist compare */
720 negl nbytes_r /* nbytes = -nbytes */
721 movl window(%esp), from_r /* from = window */
722
723 cmpl dist_r, %eax
724 jb .L_invalid_distance_too_far /* if (dist > wsize) */
725
726 addl dist_r, nbytes_r /* nbytes = dist - nbytes */
727 cmpl $0, write(%esp)
728 jne .L_wrap_around_window /* if (write != 0) */
729
730 subl nbytes_r, %eax
731 addl %eax, from_r /* from += wsize - nbytes */
732
733 /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
734 * %ecx = nbytes, %eax = len
735 *
736 * if (nbytes < len) {
737 * len -= nbytes;
738 * do {
739 * PUP(out) = PUP(from);
740 * } while (--nbytes);
741 * from = out - dist;
742 * }
743 * }
744 */
745 #define len_r %eax
746 movl len(%esp), len_r
747 cmpl nbytes_r, len_r
748 jbe .L_do_copy1 /* if (nbytes >= len) */
749
750 subl nbytes_r, len_r /* len -= nbytes */
751 rep movsb
752 movl out_r, from_r
753 subl dist_r, from_r /* from = out - dist */
754 jmp .L_do_copy1
755
756 cmpl nbytes_r, len_r
757 jbe .L_do_copy1 /* if (nbytes >= len) */
758
759 subl nbytes_r, len_r /* len -= nbytes */
760 rep movsb
761 movl out_r, from_r
762 subl dist_r, from_r /* from = out - dist */
763 jmp .L_do_copy1
764
765 .L_wrap_around_window:
766 /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
767 * %ecx = nbytes, %eax = write, %eax = len
768 *
769 * else if (write < nbytes) {
770 * from += wsize + write - nbytes;
771 * nbytes -= write;
772 * if (nbytes < len) {
773 * len -= nbytes;
774 * do {
775 * PUP(out) = PUP(from);
776 * } while (--nbytes);
777 * from = window;
778 * nbytes = write;
779 * if (nbytes < len) {
780 * len -= nbytes;
781 * do {
782 * PUP(out) = PUP(from);
783 * } while(--nbytes);
784 * from = out - dist;
785 * }
786 * }
787 * }
788 */
789 #define write_r %eax
790 movl write(%esp), write_r
791 cmpl write_r, nbytes_r
792 jbe .L_contiguous_in_window /* if (write >= nbytes) */
793
794 addl wsize(%esp), from_r
795 addl write_r, from_r
796 subl nbytes_r, from_r /* from += wsize + write - nbytes */
797 subl write_r, nbytes_r /* nbytes -= write */
798 #undef write_r
799
800 movl len(%esp), len_r
801 cmpl nbytes_r, len_r
802 jbe .L_do_copy1 /* if (nbytes >= len) */
803
804 subl nbytes_r, len_r /* len -= nbytes */
805 rep movsb
806 movl window(%esp), from_r /* from = window */
807 movl write(%esp), nbytes_r /* nbytes = write */
808 cmpl nbytes_r, len_r
809 jbe .L_do_copy1 /* if (nbytes >= len) */
810
811 subl nbytes_r, len_r /* len -= nbytes */
812 rep movsb
813 movl out_r, from_r
814 subl dist_r, from_r /* from = out - dist */
815 jmp .L_do_copy1
816
817 .L_contiguous_in_window:
818 /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
819 * %ecx = nbytes, %eax = write, %eax = len
820 *
821 * else {
822 * from += write - nbytes;
823 * if (nbytes < len) {
824 * len -= nbytes;
825 * do {
826 * PUP(out) = PUP(from);
827 * } while (--nbytes);
828 * from = out - dist;
829 * }
830 * }
831 */
832 #define write_r %eax
833 addl write_r, from_r
834 subl nbytes_r, from_r /* from += write - nbytes */
835 #undef write_r
836
837 movl len(%esp), len_r
838 cmpl nbytes_r, len_r
839 jbe .L_do_copy1 /* if (nbytes >= len) */
840
841 subl nbytes_r, len_r /* len -= nbytes */
842 rep movsb
843 movl out_r, from_r
844 subl dist_r, from_r /* from = out - dist */
845
846 .L_do_copy1:
847 /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
848 * %eax = len
849 *
850 * while (len > 0) {
851 * PUP(out) = PUP(from);
852 * len--;
853 * }
854 * }
855 * } while (in < last && out < end);
856 */
857 #undef nbytes_r
858 #define in_r %esi
859 movl len_r, %ecx
860 rep movsb
861
862 movl in(%esp), in_r /* move in back to %esi, toss from */
863 jmp .L_while_test
864
865 #undef len_r
866 #undef dist_r
867
868 #endif /* NO_MMX || RUN_TIME_MMX */
869
870
871 /*** MMX code ***/
872
873 #if defined( USE_MMX ) || defined( RUN_TIME_MMX )
874
875 .align 32,0x90
876 .L_init_mmx:
877 emms
878
879 #undef bits_r
880 #undef bitslong_r
881 #define bitslong_r %ebp
882 #define hold_mm %mm0
883 movd %ebp, hold_mm
884 movl %ebx, bitslong_r
885
886 #define used_mm %mm1
887 #define dmask2_mm %mm2
888 #define lmask2_mm %mm3
889 #define lmask_mm %mm4
890 #define dmask_mm %mm5
891 #define tmp_mm %mm6
892
893 movd lmask(%esp), lmask_mm
894 movq lmask_mm, lmask2_mm
895 movd dmask(%esp), dmask_mm
896 movq dmask_mm, dmask2_mm
897 pxor used_mm, used_mm
898 movl lcode(%esp), %ebx /* ebx = lcode */
899 jmp .L_do_loop_mmx
900
901 .align 32,0x90
902 .L_while_test_mmx:
903 /* while (in < last && out < end)
904 */
905 cmpl out_r, end(%esp)
906 jbe .L_break_loop /* if (out >= end) */
907
908 cmpl in_r, last(%esp)
909 jbe .L_break_loop
910
911 .L_do_loop_mmx:
912 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
913
914 cmpl $32, bitslong_r
915 ja .L_get_length_code_mmx /* if (32 < bits) */
916
917 movd bitslong_r, tmp_mm
918 movd (in_r), %mm7
919 addl $4, in_r
920 psllq tmp_mm, %mm7
921 addl $32, bitslong_r
922 por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
923
924 .L_get_length_code_mmx:
925 pand hold_mm, lmask_mm
926 movd lmask_mm, %eax
927 movq lmask2_mm, lmask_mm
928 movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */
929
930 .L_dolen_mmx:
931 movzbl %ah, %ecx /* ecx = this.bits */
932 movd %ecx, used_mm
933 subl %ecx, bitslong_r /* bits -= this.bits */
934
935 testb %al, %al
936 jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */
937
938 shrl $16, %eax /* output this.val char */
939 stosb
940 jmp .L_while_test_mmx
941
942 .L_test_for_length_base_mmx:
943 #define len_r %edx
944 movl %eax, len_r /* len = this */
945 shrl $16, len_r /* len = this.val */
946
947 testb $16, %al
948 jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */
949 andl $15, %eax /* op &= 15 */
950 jz .L_decode_distance_mmx /* if (!op) */
951
952 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
953 movd %eax, used_mm
954 movd hold_mm, %ecx
955 subl %eax, bitslong_r
956 andl .L_mask(,%eax,4), %ecx
957 addl %ecx, len_r /* len += hold & mask[op] */
958
959 .L_decode_distance_mmx:
960 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
961
962 cmpl $32, bitslong_r
963 ja .L_get_dist_code_mmx /* if (32 < bits) */
964
965 movd bitslong_r, tmp_mm
966 movd (in_r), %mm7
967 addl $4, in_r
968 psllq tmp_mm, %mm7
969 addl $32, bitslong_r
970 por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
971
972 .L_get_dist_code_mmx:
973 movl dcode(%esp), %ebx /* ebx = dcode */
974 pand hold_mm, dmask_mm
975 movd dmask_mm, %eax
976 movq dmask2_mm, dmask_mm
977 movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */
978
979 .L_dodist_mmx:
980 #define dist_r %ebx
981 movzbl %ah, %ecx /* ecx = this.bits */
982 movl %eax, dist_r
983 shrl $16, dist_r /* dist = this.val */
984 subl %ecx, bitslong_r /* bits -= this.bits */
985 movd %ecx, used_mm
986
987 testb $16, %al /* if ((op & 16) == 0) */
988 jz .L_test_for_second_level_dist_mmx
989 andl $15, %eax /* op &= 15 */
990 jz .L_check_dist_one_mmx
991
992 .L_add_bits_to_dist_mmx:
993 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
994 movd %eax, used_mm /* save bit length of current op */
995 movd hold_mm, %ecx /* get the next bits on input stream */
996 subl %eax, bitslong_r /* bits -= op bits */
997 andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */
998 addl %ecx, dist_r /* dist += hold & mask[op] */
999
1000 .L_check_window_mmx:
1001 movl in_r, in(%esp) /* save in so from can use it's reg */
1002 movl out_r, %eax
1003 subl beg(%esp), %eax /* nbytes = out - beg */
1004
1005 cmpl dist_r, %eax
1006 jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */
1007
1008 movl len_r, %ecx
1009 movl out_r, from_r
1010 subl dist_r, from_r /* from = out - dist */
1011
1012 subl $3, %ecx
1013 movb (from_r), %al
1014 movb %al, (out_r)
1015 movb 1(from_r), %al
1016 movb 2(from_r), %dl
1017 addl $3, from_r
1018 movb %al, 1(out_r)
1019 movb %dl, 2(out_r)
1020 addl $3, out_r
1021 rep movsb
1022
1023 movl in(%esp), in_r /* move in back to %esi, toss from */
1024 movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
1025 jmp .L_while_test_mmx
1026
1027 .align 16,0x90
1028 .L_check_dist_one_mmx:
1029 cmpl $1, dist_r
1030 jne .L_check_window_mmx
1031 cmpl out_r, beg(%esp)
1032 je .L_check_window_mmx
1033
1034 decl out_r
1035 movl len_r, %ecx
1036 movb (out_r), %al
1037 subl $3, %ecx
1038
1039 movb %al, 1(out_r)
1040 movb %al, 2(out_r)
1041 movb %al, 3(out_r)
1042 addl $4, out_r
1043 rep stosb
1044
1045 movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
1046 jmp .L_while_test_mmx
1047
1048 .align 16,0x90
1049 .L_test_for_second_level_length_mmx:
1050 testb $64, %al
1051 jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
1052
1053 andl $15, %eax
1054 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
1055 movd hold_mm, %ecx
1056 andl .L_mask(,%eax,4), %ecx
1057 addl len_r, %ecx
1058 movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */
1059 jmp .L_dolen_mmx
1060
1061 .align 16,0x90
1062 .L_test_for_second_level_dist_mmx:
1063 testb $64, %al
1064 jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
1065
1066 andl $15, %eax
1067 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
1068 movd hold_mm, %ecx
1069 andl .L_mask(,%eax,4), %ecx
1070 movl dcode(%esp), %eax /* ecx = dcode */
1071 addl dist_r, %ecx
1072 movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */
1073 jmp .L_dodist_mmx
1074
1075 .align 16,0x90
1076 .L_clip_window_mmx:
1077 #define nbytes_r %ecx
1078 movl %eax, nbytes_r
1079 movl wsize(%esp), %eax /* prepare for dist compare */
1080 negl nbytes_r /* nbytes = -nbytes */
1081 movl window(%esp), from_r /* from = window */
1082
1083 cmpl dist_r, %eax
1084 jb .L_invalid_distance_too_far /* if (dist > wsize) */
1085
1086 addl dist_r, nbytes_r /* nbytes = dist - nbytes */
1087 cmpl $0, write(%esp)
1088 jne .L_wrap_around_window_mmx /* if (write != 0) */
1089
1090 subl nbytes_r, %eax
1091 addl %eax, from_r /* from += wsize - nbytes */
1092
1093 cmpl nbytes_r, len_r
1094 jbe .L_do_copy1_mmx /* if (nbytes >= len) */
1095
1096 subl nbytes_r, len_r /* len -= nbytes */
1097 rep movsb
1098 movl out_r, from_r
1099 subl dist_r, from_r /* from = out - dist */
1100 jmp .L_do_copy1_mmx
1101
1102 cmpl nbytes_r, len_r
1103 jbe .L_do_copy1_mmx /* if (nbytes >= len) */
1104
1105 subl nbytes_r, len_r /* len -= nbytes */
1106 rep movsb
1107 movl out_r, from_r
1108 subl dist_r, from_r /* from = out - dist */
1109 jmp .L_do_copy1_mmx
1110
1111 .L_wrap_around_window_mmx:
1112 #define write_r %eax
1113 movl write(%esp), write_r
1114 cmpl write_r, nbytes_r
1115 jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */
1116
1117 addl wsize(%esp), from_r
1118 addl write_r, from_r
1119 subl nbytes_r, from_r /* from += wsize + write - nbytes */
1120 subl write_r, nbytes_r /* nbytes -= write */
1121 #undef write_r
1122
1123 cmpl nbytes_r, len_r
1124 jbe .L_do_copy1_mmx /* if (nbytes >= len) */
1125
1126 subl nbytes_r, len_r /* len -= nbytes */
1127 rep movsb
1128 movl window(%esp), from_r /* from = window */
1129 movl write(%esp), nbytes_r /* nbytes = write */
1130 cmpl nbytes_r, len_r
1131 jbe .L_do_copy1_mmx /* if (nbytes >= len) */
1132
1133 subl nbytes_r, len_r /* len -= nbytes */
1134 rep movsb
1135 movl out_r, from_r
1136 subl dist_r, from_r /* from = out - dist */
1137 jmp .L_do_copy1_mmx
1138
1139 .L_contiguous_in_window_mmx:
1140 #define write_r %eax
1141 addl write_r, from_r
1142 subl nbytes_r, from_r /* from += write - nbytes */
1143 #undef write_r
1144
1145 cmpl nbytes_r, len_r
1146 jbe .L_do_copy1_mmx /* if (nbytes >= len) */
1147
1148 subl nbytes_r, len_r /* len -= nbytes */
1149 rep movsb
1150 movl out_r, from_r
1151 subl dist_r, from_r /* from = out - dist */
1152
1153 .L_do_copy1_mmx:
1154 #undef nbytes_r
1155 #define in_r %esi
1156 movl len_r, %ecx
1157 rep movsb
1158
1159 movl in(%esp), in_r /* move in back to %esi, toss from */
1160 movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
1161 jmp .L_while_test_mmx
1162
1163 #undef hold_r
1164 #undef bitslong_r
1165
1166 #endif /* USE_MMX || RUN_TIME_MMX */
1167
1168
1169 /*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/
1170
1171 .L_invalid_distance_code:
1172 /* else {
1173 * strm->msg = "invalid distance code";
1174 * state->mode = BAD;
1175 * }
1176 */
1177 movl $.L_invalid_distance_code_msg, %ecx
1178 movl $INFLATE_MODE_BAD, %edx
1179 jmp .L_update_stream_state
1180
1181 .L_test_for_end_of_block:
1182 /* else if (op & 32) {
1183 * state->mode = TYPE;
1184 * break;
1185 * }
1186 */
1187 testb $32, %al
1188 jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */
1189
1190 movl $0, %ecx
1191 movl $INFLATE_MODE_TYPE, %edx
1192 jmp .L_update_stream_state
1193
1194 .L_invalid_literal_length_code:
1195 /* else {
1196 * strm->msg = "invalid literal/length code";
1197 * state->mode = BAD;
1198 * }
1199 */
1200 movl $.L_invalid_literal_length_code_msg, %ecx
1201 movl $INFLATE_MODE_BAD, %edx
1202 jmp .L_update_stream_state
1203
1204 .L_invalid_distance_too_far:
1205 /* strm->msg = "invalid distance too far back";
1206 * state->mode = BAD;
1207 */
1208 movl in(%esp), in_r /* from_r has in's reg, put in back */
1209 movl $.L_invalid_distance_too_far_msg, %ecx
1210 movl $INFLATE_MODE_BAD, %edx
1211 jmp .L_update_stream_state
1212
1213 .L_update_stream_state:
1214 /* set strm->msg = %ecx, strm->state->mode = %edx */
1215 movl strm_sp(%esp), %eax
1216 testl %ecx, %ecx /* if (msg != NULL) */
1217 jz .L_skip_msg
1218 movl %ecx, msg_strm(%eax) /* strm->msg = msg */
1219 .L_skip_msg:
1220 movl state_strm(%eax), %eax /* state = strm->state */
1221 movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */
1222 jmp .L_break_loop
1223
1224 .align 32,0x90
1225 .L_break_loop:
1226
1227 /*
1228 * Regs:
1229 *
1230 * bits = %ebp when mmx, and in %ebx when non-mmx
1231 * hold = %hold_mm when mmx, and in %ebp when non-mmx
1232 * in = %esi
1233 * out = %edi
1234 */
1235
1236 #if defined( USE_MMX ) || defined( RUN_TIME_MMX )
1237
1238 #if defined( RUN_TIME_MMX )
1239
1240 cmpl $DO_USE_MMX, inflate_fast_use_mmx
1241 jne .L_update_next_in
1242
1243 #endif /* RUN_TIME_MMX */
1244
1245 movl %ebp, %ebx
1246
1247 .L_update_next_in:
1248
1249 #endif
1250
1251 #define strm_r %eax
1252 #define state_r %edx
1253
1254 /* len = bits >> 3;
1255 * in -= len;
1256 * bits -= len << 3;
1257 * hold &= (1U << bits) - 1;
1258 * state->hold = hold;
1259 * state->bits = bits;
1260 * strm->next_in = in;
1261 * strm->next_out = out;
1262 */
1263 movl strm_sp(%esp), strm_r
1264 movl %ebx, %ecx
1265 movl state_strm(strm_r), state_r
1266 shrl $3, %ecx
1267 subl %ecx, in_r
1268 shll $3, %ecx
1269 subl %ecx, %ebx
1270 movl out_r, next_out_strm(strm_r)
1271 movl %ebx, bits_state(state_r)
1272 movl %ebx, %ecx
1273
1274 leal buf(%esp), %ebx
1275 cmpl %ebx, last(%esp)
1276 jne .L_buf_not_used /* if buf != last */
1277
1278 subl %ebx, in_r /* in -= buf */
1279 movl next_in_strm(strm_r), %ebx
1280 movl %ebx, last(%esp) /* last = strm->next_in */
1281 addl %ebx, in_r /* in += strm->next_in */
1282 movl avail_in_strm(strm_r), %ebx
1283 subl $11, %ebx
1284 addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */
1285
1286 .L_buf_not_used:
1287 movl in_r, next_in_strm(strm_r)
1288
1289 movl $1, %ebx
1290 shll %cl, %ebx
1291 decl %ebx
1292
1293 #if defined( USE_MMX ) || defined( RUN_TIME_MMX )
1294
1295 #if defined( RUN_TIME_MMX )
1296
1297 cmpl $DO_USE_MMX, inflate_fast_use_mmx
1298 jne .L_update_hold
1299
1300 #endif /* RUN_TIME_MMX */
1301
1302 psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
1303 movd hold_mm, %ebp
1304
1305 emms
1306
1307 .L_update_hold:
1308
1309 #endif /* USE_MMX || RUN_TIME_MMX */
1310
1311 andl %ebx, %ebp
1312 movl %ebp, hold_state(state_r)
1313
1314 #define last_r %ebx
1315
1316 /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */
1317 movl last(%esp), last_r
1318 cmpl in_r, last_r
1319 jbe .L_last_is_smaller /* if (in >= last) */
1320
1321 subl in_r, last_r /* last -= in */
1322 addl $11, last_r /* last += 11 */
1323 movl last_r, avail_in_strm(strm_r)
1324 jmp .L_fixup_out
1325 .L_last_is_smaller:
1326 subl last_r, in_r /* in -= last */
1327 negl in_r /* in = -in */
1328 addl $11, in_r /* in += 11 */
1329 movl in_r, avail_in_strm(strm_r)
1330
1331 #undef last_r
1332 #define end_r %ebx
1333
1334 .L_fixup_out:
1335 /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
1336 movl end(%esp), end_r
1337 cmpl out_r, end_r
1338 jbe .L_end_is_smaller /* if (out >= end) */
1339
1340 subl out_r, end_r /* end -= out */
1341 addl $257, end_r /* end += 257 */
1342 movl end_r, avail_out_strm(strm_r)
1343 jmp .L_done
1344 .L_end_is_smaller:
1345 subl end_r, out_r /* out -= end */
1346 negl out_r /* out = -out */
1347 addl $257, out_r /* out += 257 */
1348 movl out_r, avail_out_strm(strm_r)
1349
1350 #undef end_r
1351 #undef strm_r
1352 #undef state_r
1353
1354 .L_done:
1355 addl $local_var_size, %esp
1356 popf
1357 popl %ebx
1358 popl %ebp
1359 popl %esi
1360 popl %edi
1361 ret
1362
1363 #if defined( GAS_ELF )
1364 /* elf info */
1365 .type inflate_fast,@function
1366 .size inflate_fast,.-inflate_fast
1367 #endif
0
1 #include "zfstream.h"
2
3 int main() {
4
5 // Construct a stream object with this filebuffer. Anything sent
6 // to this stream will go to standard out.
7 gzofstream os( 1, ios::out );
8
9 // This text is getting compressed and sent to stdout.
10 // To prove this, run 'test | zcat'.
11 os << "Hello, Mommy" << endl;
12
13 os << setcompressionlevel( Z_NO_COMPRESSION );
14 os << "hello, hello, hi, ho!" << endl;
15
16 setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
17 << "I'm compressing again" << endl;
18
19 os.close();
20
21 return 0;
22
23 }
0
1 #include "zfstream.h"
2
3 gzfilebuf::gzfilebuf() :
4 file(NULL),
5 mode(0),
6 own_file_descriptor(0)
7 { }
8
9 gzfilebuf::~gzfilebuf() {
10
11 sync();
12 if ( own_file_descriptor )
13 close();
14
15 }
16
17 gzfilebuf *gzfilebuf::open( const char *name,
18 int io_mode ) {
19
20 if ( is_open() )
21 return NULL;
22
23 char char_mode[10];
24 char *p = char_mode;
25
26 if ( io_mode & ios::in ) {
27 mode = ios::in;
28 *p++ = 'r';
29 } else if ( io_mode & ios::app ) {
30 mode = ios::app;
31 *p++ = 'a';
32 } else {
33 mode = ios::out;
34 *p++ = 'w';
35 }
36
37 if ( io_mode & ios::binary ) {
38 mode |= ios::binary;
39 *p++ = 'b';
40 }
41
42 // Hard code the compression level
43 if ( io_mode & (ios::out|ios::app )) {
44 *p++ = '9';
45 }
46
47 // Put the end-of-string indicator
48 *p = '\0';
49
50 if ( (file = gzopen(name, char_mode)) == NULL )
51 return NULL;
52
53 own_file_descriptor = 1;
54
55 return this;
56
57 }
58
59 gzfilebuf *gzfilebuf::attach( int file_descriptor,
60 int io_mode ) {
61
62 if ( is_open() )
63 return NULL;
64
65 char char_mode[10];
66 char *p = char_mode;
67
68 if ( io_mode & ios::in ) {
69 mode = ios::in;
70 *p++ = 'r';
71 } else if ( io_mode & ios::app ) {
72 mode = ios::app;
73 *p++ = 'a';
74 } else {
75 mode = ios::out;
76 *p++ = 'w';
77 }
78
79 if ( io_mode & ios::binary ) {
80 mode |= ios::binary;
81 *p++ = 'b';
82 }
83
84 // Hard code the compression level
85 if ( io_mode & (ios::out|ios::app )) {
86 *p++ = '9';
87 }
88
89 // Put the end-of-string indicator
90 *p = '\0';
91
92 if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
93 return NULL;
94
95 own_file_descriptor = 0;
96
97 return this;
98
99 }
100
101 gzfilebuf *gzfilebuf::close() {
102
103 if ( is_open() ) {
104
105 sync();
106 gzclose( file );
107 file = NULL;
108
109 }
110
111 return this;
112
113 }
114
115 int gzfilebuf::setcompressionlevel( int comp_level ) {
116
117 return gzsetparams(file, comp_level, -2);
118
119 }
120
121 int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
122
123 return gzsetparams(file, -2, comp_strategy);
124
125 }
126
127
128 streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
129
130 return streampos(EOF);
131
132 }
133
134 int gzfilebuf::underflow() {
135
136 // If the file hasn't been opened for reading, error.
137 if ( !is_open() || !(mode & ios::in) )
138 return EOF;
139
140 // if a buffer doesn't exists, allocate one.
141 if ( !base() ) {
142
143 if ( (allocate()) == EOF )
144 return EOF;
145 setp(0,0);
146
147 } else {
148
149 if ( in_avail() )
150 return (unsigned char) *gptr();
151
152 if ( out_waiting() ) {
153 if ( flushbuf() == EOF )
154 return EOF;
155 }
156
157 }
158
159 // Attempt to fill the buffer.
160
161 int result = fillbuf();
162 if ( result == EOF ) {
163 // disable get area
164 setg(0,0,0);
165 return EOF;
166 }
167
168 return (unsigned char) *gptr();
169
170 }
171
172 int gzfilebuf::overflow( int c ) {
173
174 if ( !is_open() || !(mode & ios::out) )
175 return EOF;
176
177 if ( !base() ) {
178 if ( allocate() == EOF )
179 return EOF;
180 setg(0,0,0);
181 } else {
182 if (in_avail()) {
183 return EOF;
184 }
185 if (out_waiting()) {
186 if (flushbuf() == EOF)
187 return EOF;
188 }
189 }
190
191 int bl = blen();
192 setp( base(), base() + bl);
193
194 if ( c != EOF ) {
195
196 *pptr() = c;
197 pbump(1);
198
199 }
200
201 return 0;
202
203 }
204
205 int gzfilebuf::sync() {
206
207 if ( !is_open() )
208 return EOF;
209
210 if ( out_waiting() )
211 return flushbuf();
212
213 return 0;
214
215 }
216
217 int gzfilebuf::flushbuf() {
218
219 int n;
220 char *q;
221
222 q = pbase();
223 n = pptr() - q;
224
225 if ( gzwrite( file, q, n) < n )
226 return EOF;
227
228 setp(0,0);
229
230 return 0;
231
232 }
233
234 int gzfilebuf::fillbuf() {
235
236 int required;
237 char *p;
238
239 p = base();
240
241 required = blen();
242
243 int t = gzread( file, p, required );
244
245 if ( t <= 0) return EOF;
246
247 setg( base(), base(), base()+t);
248
249 return t;
250
251 }
252
253 gzfilestream_common::gzfilestream_common() :
254 ios( gzfilestream_common::rdbuf() )
255 { }
256
257 gzfilestream_common::~gzfilestream_common()
258 { }
259
260 void gzfilestream_common::attach( int fd, int io_mode ) {
261
262 if ( !buffer.attach( fd, io_mode) )
263 clear( ios::failbit | ios::badbit );
264 else
265 clear();
266
267 }
268
269 void gzfilestream_common::open( const char *name, int io_mode ) {
270
271 if ( !buffer.open( name, io_mode ) )
272 clear( ios::failbit | ios::badbit );
273 else
274 clear();
275
276 }
277
278 void gzfilestream_common::close() {
279
280 if ( !buffer.close() )
281 clear( ios::failbit | ios::badbit );
282
283 }
284
285 gzfilebuf *gzfilestream_common::rdbuf()
286 {
287 return &buffer;
288 }
289
290 gzifstream::gzifstream() :
291 ios( gzfilestream_common::rdbuf() )
292 {
293 clear( ios::badbit );
294 }
295
296 gzifstream::gzifstream( const char *name, int io_mode ) :
297 ios( gzfilestream_common::rdbuf() )
298 {
299 gzfilestream_common::open( name, io_mode );
300 }
301
302 gzifstream::gzifstream( int fd, int io_mode ) :
303 ios( gzfilestream_common::rdbuf() )
304 {
305 gzfilestream_common::attach( fd, io_mode );
306 }
307
308 gzifstream::~gzifstream() { }
309
310 gzofstream::gzofstream() :
311 ios( gzfilestream_common::rdbuf() )
312 {
313 clear( ios::badbit );
314 }
315
316 gzofstream::gzofstream( const char *name, int io_mode ) :
317 ios( gzfilestream_common::rdbuf() )
318 {
319 gzfilestream_common::open( name, io_mode );
320 }
321
322 gzofstream::gzofstream( int fd, int io_mode ) :
323 ios( gzfilestream_common::rdbuf() )
324 {
325 gzfilestream_common::attach( fd, io_mode );
326 }
327
328 gzofstream::~gzofstream() { }
0
1 #ifndef zfstream_h
2 #define zfstream_h
3
4 #include <fstream.h>
5 #include "zlib.h"
6
7 class gzfilebuf : public streambuf {
8
9 public:
10
11 gzfilebuf( );
12 virtual ~gzfilebuf();
13
14 gzfilebuf *open( const char *name, int io_mode );
15 gzfilebuf *attach( int file_descriptor, int io_mode );
16 gzfilebuf *close();
17
18 int setcompressionlevel( int comp_level );
19 int setcompressionstrategy( int comp_strategy );
20
21 inline int is_open() const { return (file !=NULL); }
22
23 virtual streampos seekoff( streamoff, ios::seek_dir, int );
24
25 virtual int sync();
26
27 protected:
28
29 virtual int underflow();
30 virtual int overflow( int = EOF );
31
32 private:
33
34 gzFile file;
35 short mode;
36 short own_file_descriptor;
37
38 int flushbuf();
39 int fillbuf();
40
41 };
42
43 class gzfilestream_common : virtual public ios {
44
45 friend class gzifstream;
46 friend class gzofstream;
47 friend gzofstream &setcompressionlevel( gzofstream &, int );
48 friend gzofstream &setcompressionstrategy( gzofstream &, int );
49
50 public:
51 virtual ~gzfilestream_common();
52
53 void attach( int fd, int io_mode );
54 void open( const char *name, int io_mode );
55 void close();
56
57 protected:
58 gzfilestream_common();
59
60 private:
61 gzfilebuf *rdbuf();
62
63 gzfilebuf buffer;
64
65 };
66
67 class gzifstream : public gzfilestream_common, public istream {
68
69 public:
70
71 gzifstream();
72 gzifstream( const char *name, int io_mode = ios::in );
73 gzifstream( int fd, int io_mode = ios::in );
74
75 virtual ~gzifstream();
76
77 };
78
79 class gzofstream : public gzfilestream_common, public ostream {
80
81 public:
82
83 gzofstream();
84 gzofstream( const char *name, int io_mode = ios::out );
85 gzofstream( int fd, int io_mode = ios::out );
86
87 virtual ~gzofstream();
88
89 };
90
91 template<class T> class gzomanip {
92 friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
93 public:
94 gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
95 private:
96 gzofstream &(*func)(gzofstream &, T);
97 T val;
98 };
99
100 template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
101 {
102 return (*m.func)(s, m.val);
103 }
104
105 inline gzofstream &setcompressionlevel( gzofstream &s, int l )
106 {
107 (s.rdbuf())->setcompressionlevel(l);
108 return s;
109 }
110
111 inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
112 {
113 (s.rdbuf())->setcompressionstrategy(l);
114 return s;
115 }
116
117 inline gzomanip<int> setcompressionlevel(int l)
118 {
119 return gzomanip<int>(&setcompressionlevel,l);
120 }
121
122 inline gzomanip<int> setcompressionstrategy(int l)
123 {
124 return gzomanip<int>(&setcompressionstrategy,l);
125 }
126
127 #endif
0 /*
1 *
2 * Copyright (c) 1997
3 * Christian Michelsen Research AS
4 * Advanced Computing
5 * Fantoftvegen 38, 5036 BERGEN, Norway
6 * http://www.cmr.no
7 *
8 * Permission to use, copy, modify, distribute and sell this software
9 * and its documentation for any purpose is hereby granted without fee,
10 * provided that the above copyright notice appear in all copies and
11 * that both that copyright notice and this permission notice appear
12 * in supporting documentation. Christian Michelsen Research AS makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
15 *
16 */
17
18 #ifndef ZSTREAM__H
19 #define ZSTREAM__H
20
21 /*
22 * zstream.h - C++ interface to the 'zlib' general purpose compression library
23 * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
24 */
25
26 #include <strstream.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include "zlib.h"
30
31 #if defined(_WIN32)
32 # include <fcntl.h>
33 # include <io.h>
34 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
35 #else
36 # define SET_BINARY_MODE(file)
37 #endif
38
39 class zstringlen {
40 public:
41 zstringlen(class izstream&);
42 zstringlen(class ozstream&, const char*);
43 size_t value() const { return val.word; }
44 private:
45 struct Val { unsigned char byte; size_t word; } val;
46 };
47
48 // ----------------------------- izstream -----------------------------
49
50 class izstream
51 {
52 public:
53 izstream() : m_fp(0) {}
54 izstream(FILE* fp) : m_fp(0) { open(fp); }
55 izstream(const char* name) : m_fp(0) { open(name); }
56 ~izstream() { close(); }
57
58 /* Opens a gzip (.gz) file for reading.
59 * open() can be used to read a file which is not in gzip format;
60 * in this case read() will directly read from the file without
61 * decompression. errno can be checked to distinguish two error
62 * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
63 */
64 void open(const char* name) {
65 if (m_fp) close();
66 m_fp = ::gzopen(name, "rb");
67 }
68
69 void open(FILE* fp) {
70 SET_BINARY_MODE(fp);
71 if (m_fp) close();
72 m_fp = ::gzdopen(fileno(fp), "rb");
73 }
74
75 /* Flushes all pending input if necessary, closes the compressed file
76 * and deallocates all the (de)compression state. The return value is
77 * the zlib error number (see function error() below).
78 */
79 int close() {
80 int r = ::gzclose(m_fp);
81 m_fp = 0; return r;
82 }
83
84 /* Binary read the given number of bytes from the compressed file.
85 */
86 int read(void* buf, size_t len) {
87 return ::gzread(m_fp, buf, len);
88 }
89
90 /* Returns the error message for the last error which occurred on the
91 * given compressed file. errnum is set to zlib error number. If an
92 * error occurred in the file system and not in the compression library,
93 * errnum is set to Z_ERRNO and the application may consult errno
94 * to get the exact error code.
95 */
96 const char* error(int* errnum) {
97 return ::gzerror(m_fp, errnum);
98 }
99
100 gzFile fp() { return m_fp; }
101
102 private:
103 gzFile m_fp;
104 };
105
106 /*
107 * Binary read the given (array of) object(s) from the compressed file.
108 * If the input file was not in gzip format, read() copies the objects number
109 * of bytes into the buffer.
110 * returns the number of uncompressed bytes actually read
111 * (0 for end of file, -1 for error).
112 */
113 template <class T, class Items>
114 inline int read(izstream& zs, T* x, Items items) {
115 return ::gzread(zs.fp(), x, items*sizeof(T));
116 }
117
118 /*
119 * Binary input with the '>' operator.
120 */
121 template <class T>
122 inline izstream& operator>(izstream& zs, T& x) {
123 ::gzread(zs.fp(), &x, sizeof(T));
124 return zs;
125 }
126
127
128 inline zstringlen::zstringlen(izstream& zs) {
129 zs > val.byte;
130 if (val.byte == 255) zs > val.word;
131 else val.word = val.byte;
132 }
133
134 /*
135 * Read length of string + the string with the '>' operator.
136 */
137 inline izstream& operator>(izstream& zs, char* x) {
138 zstringlen len(zs);
139 ::gzread(zs.fp(), x, len.value());
140 x[len.value()] = '\0';
141 return zs;
142 }
143
144 inline char* read_string(izstream& zs) {
145 zstringlen len(zs);
146 char* x = new char[len.value()+1];
147 ::gzread(zs.fp(), x, len.value());
148 x[len.value()] = '\0';
149 return x;
150 }
151
152 // ----------------------------- ozstream -----------------------------
153
154 class ozstream
155 {
156 public:
157 ozstream() : m_fp(0), m_os(0) {
158 }
159 ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
160 : m_fp(0), m_os(0) {
161 open(fp, level);
162 }
163 ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
164 : m_fp(0), m_os(0) {
165 open(name, level);
166 }
167 ~ozstream() {
168 close();
169 }
170
171 /* Opens a gzip (.gz) file for writing.
172 * The compression level parameter should be in 0..9
173 * errno can be checked to distinguish two error cases
174 * (if errno is zero, the zlib error is Z_MEM_ERROR).
175 */
176 void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
177 char mode[4] = "wb\0";
178 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
179 if (m_fp) close();
180 m_fp = ::gzopen(name, mode);
181 }
182
183 /* open from a FILE pointer.
184 */
185 void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
186 SET_BINARY_MODE(fp);
187 char mode[4] = "wb\0";
188 if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
189 if (m_fp) close();
190 m_fp = ::gzdopen(fileno(fp), mode);
191 }
192
193 /* Flushes all pending output if necessary, closes the compressed file
194 * and deallocates all the (de)compression state. The return value is
195 * the zlib error number (see function error() below).
196 */
197 int close() {
198 if (m_os) {
199 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
200 delete[] m_os->str(); delete m_os; m_os = 0;
201 }
202 int r = ::gzclose(m_fp); m_fp = 0; return r;
203 }
204
205 /* Binary write the given number of bytes into the compressed file.
206 */
207 int write(const void* buf, size_t len) {
208 return ::gzwrite(m_fp, (voidp) buf, len);
209 }
210
211 /* Flushes all pending output into the compressed file. The parameter
212 * _flush is as in the deflate() function. The return value is the zlib
213 * error number (see function gzerror below). flush() returns Z_OK if
214 * the flush_ parameter is Z_FINISH and all output could be flushed.
215 * flush() should be called only when strictly necessary because it can
216 * degrade compression.
217 */
218 int flush(int _flush) {
219 os_flush();
220 return ::gzflush(m_fp, _flush);
221 }
222
223 /* Returns the error message for the last error which occurred on the
224 * given compressed file. errnum is set to zlib error number. If an
225 * error occurred in the file system and not in the compression library,
226 * errnum is set to Z_ERRNO and the application may consult errno
227 * to get the exact error code.
228 */
229 const char* error(int* errnum) {
230 return ::gzerror(m_fp, errnum);
231 }
232
233 gzFile fp() { return m_fp; }
234
235 ostream& os() {
236 if (m_os == 0) m_os = new ostrstream;
237 return *m_os;
238 }
239
240 void os_flush() {
241 if (m_os && m_os->pcount()>0) {
242 ostrstream* oss = new ostrstream;
243 oss->fill(m_os->fill());
244 oss->flags(m_os->flags());
245 oss->precision(m_os->precision());
246 oss->width(m_os->width());
247 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
248 delete[] m_os->str(); delete m_os; m_os = oss;
249 }
250 }
251
252 private:
253 gzFile m_fp;
254 ostrstream* m_os;
255 };
256
257 /*
258 * Binary write the given (array of) object(s) into the compressed file.
259 * returns the number of uncompressed bytes actually written
260 * (0 in case of error).
261 */
262 template <class T, class Items>
263 inline int write(ozstream& zs, const T* x, Items items) {
264 return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
265 }
266
267 /*
268 * Binary output with the '<' operator.
269 */
270 template <class T>
271 inline ozstream& operator<(ozstream& zs, const T& x) {
272 ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
273 return zs;
274 }
275
276 inline zstringlen::zstringlen(ozstream& zs, const char* x) {
277 val.byte = 255; val.word = ::strlen(x);
278 if (val.word < 255) zs < (val.byte = val.word);
279 else zs < val;
280 }
281
282 /*
283 * Write length of string + the string with the '<' operator.
284 */
285 inline ozstream& operator<(ozstream& zs, const char* x) {
286 zstringlen len(zs, x);
287 ::gzwrite(zs.fp(), (voidp) x, len.value());
288 return zs;
289 }
290
291 #ifdef _MSC_VER
292 inline ozstream& operator<(ozstream& zs, char* const& x) {
293 return zs < (const char*) x;
294 }
295 #endif
296
297 /*
298 * Ascii write with the << operator;
299 */
300 template <class T>
301 inline ostream& operator<<(ozstream& zs, const T& x) {
302 zs.os_flush();
303 return zs.os() << x;
304 }
305
306 #endif
0 #include "zstream.h"
1 #include <math.h>
2 #include <stdlib.h>
3 #include <iomanip.h>
4
5 void main() {
6 char h[256] = "Hello";
7 char* g = "Goodbye";
8 ozstream out("temp.gz");
9 out < "This works well" < h < g;
10 out.close();
11
12 izstream in("temp.gz"); // read it back
13 char *x = read_string(in), *y = new char[256], z[256];
14 in > y > z;
15 in.close();
16 cout << x << endl << y << endl << z << endl;
17
18 out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
19 out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
20 out << z << endl << y << endl << x << endl;
21 out << 1.1234567890123456789 << endl;
22
23 delete[] x; delete[] y;
24 }
0 These classes provide a C++ stream interface to the zlib library. It allows you
1 to do things like:
2
3 gzofstream outf("blah.gz");
4 outf << "These go into the gzip file " << 123 << endl;
5
6 It does this by deriving a specialized stream buffer for gzipped files, which is
7 the way Stroustrup would have done it. :->
8
9 The gzifstream and gzofstream classes were originally written by Kevin Ruland
10 and made available in the zlib contrib/iostream directory. The older version still
11 compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
12 this version.
13
14 The new classes are as standard-compliant as possible, closely following the
15 approach of the standard library's fstream classes. It compiles under gcc versions
16 3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
17 library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
18 from the previous one in the following respects:
19 - added showmanyc
20 - added setbuf, with support for unbuffered output via setbuf(0,0)
21 - a few bug fixes of stream behavior
22 - gzipped output file opened with default compression level instead of maximum level
23 - setcompressionlevel()/strategy() members replaced by single setcompression()
24
25 The code is provided "as is", with the permission to use, copy, modify, distribute
26 and sell it for any purpose without fee.
27
28 Ludwig Schwardt
29 <schwardt@sun.ac.za>
30
31 DSP Lab
32 Electrical & Electronic Engineering Department
33 University of Stellenbosch
34 South Africa
0 Possible upgrades to gzfilebuf:
1
2 - The ability to do putback (e.g. putbackfail)
3
4 - The ability to seek (zlib supports this, but could be slow/tricky)
5
6 - Simultaneous read/write access (does it make sense?)
7
8 - Support for ios_base::ate open mode
9
10 - Locale support?
11
12 - Check public interface to see which calls give problems
13 (due to dependence on library internals)
14
15 - Override operator<<(ostream&, gzfilebuf*) to allow direct copying
16 of stream buffer to stream ( i.e. os << is.rdbuf(); )
0 /*
1 * Test program for gzifstream and gzofstream
2 *
3 * by Ludwig Schwardt <schwardt@sun.ac.za>
4 * original version by Kevin Ruland <kevin@rodin.wustl.edu>
5 */
6
7 #include "zfstream.h"
8 #include <iostream> // for cout
9
10 int main() {
11
12 gzofstream outf;
13 gzifstream inf;
14 char buf[80];
15
16 outf.open("test1.txt.gz");
17 outf << "The quick brown fox sidestepped the lazy canine\n"
18 << 1.3 << "\nPlan " << 9 << std::endl;
19 outf.close();
20 std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
21 << "The quick brown fox sidestepped the lazy canine\n"
22 << 1.3 << "\nPlan " << 9 << std::endl;
23
24 std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
25 inf.open("test1.txt.gz");
26 while (inf.getline(buf,80,'\n')) {
27 std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
28 }
29 inf.close();
30
31 outf.rdbuf()->pubsetbuf(0,0);
32 outf.open("test2.txt.gz");
33 outf << setcompression(Z_NO_COMPRESSION)
34 << "The quick brown fox sidestepped the lazy canine\n"
35 << 1.3 << "\nPlan " << 9 << std::endl;
36 outf.close();
37 std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
38
39 std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
40 inf.rdbuf()->pubsetbuf(0,0);
41 inf.open("test2.txt.gz");
42 while (inf.getline(buf,80,'\n')) {
43 std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
44 }
45 inf.close();
46
47 return 0;
48
49 }
0 /*
1 * A C++ I/O streams interface to the zlib gz* functions
2 *
3 * by Ludwig Schwardt <schwardt@sun.ac.za>
4 * original version by Kevin Ruland <kevin@rodin.wustl.edu>
5 *
6 * This version is standard-compliant and compatible with gcc 3.x.
7 */
8
9 #include "zfstream.h"
10 #include <cstring> // for strcpy, strcat, strlen (mode strings)
11 #include <cstdio> // for BUFSIZ
12
13 // Internal buffer sizes (default and "unbuffered" versions)
14 #define BIGBUFSIZE BUFSIZ
15 #define SMALLBUFSIZE 1
16
17 /*****************************************************************************/
18
19 // Default constructor
20 gzfilebuf::gzfilebuf()
21 : file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
22 buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
23 {
24 // No buffers to start with
25 this->disable_buffer();
26 }
27
28 // Destructor
29 gzfilebuf::~gzfilebuf()
30 {
31 // Sync output buffer and close only if responsible for file
32 // (i.e. attached streams should be left open at this stage)
33 this->sync();
34 if (own_fd)
35 this->close();
36 // Make sure internal buffer is deallocated
37 this->disable_buffer();
38 }
39
40 // Set compression level and strategy
41 int
42 gzfilebuf::setcompression(int comp_level,
43 int comp_strategy)
44 {
45 return gzsetparams(file, comp_level, comp_strategy);
46 }
47
48 // Open gzipped file
49 gzfilebuf*
50 gzfilebuf::open(const char *name,
51 std::ios_base::openmode mode)
52 {
53 // Fail if file already open
54 if (this->is_open())
55 return NULL;
56 // Don't support simultaneous read/write access (yet)
57 if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
58 return NULL;
59
60 // Build mode string for gzopen and check it [27.8.1.3.2]
61 char char_mode[6] = "\0\0\0\0\0";
62 if (!this->open_mode(mode, char_mode))
63 return NULL;
64
65 // Attempt to open file
66 if ((file = gzopen(name, char_mode)) == NULL)
67 return NULL;
68
69 // On success, allocate internal buffer and set flags
70 this->enable_buffer();
71 io_mode = mode;
72 own_fd = true;
73 return this;
74 }
75
76 // Attach to gzipped file
77 gzfilebuf*
78 gzfilebuf::attach(int fd,
79 std::ios_base::openmode mode)
80 {
81 // Fail if file already open
82 if (this->is_open())
83 return NULL;
84 // Don't support simultaneous read/write access (yet)
85 if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
86 return NULL;
87
88 // Build mode string for gzdopen and check it [27.8.1.3.2]
89 char char_mode[6] = "\0\0\0\0\0";
90 if (!this->open_mode(mode, char_mode))
91 return NULL;
92
93 // Attempt to attach to file
94 if ((file = gzdopen(fd, char_mode)) == NULL)
95 return NULL;
96
97 // On success, allocate internal buffer and set flags
98 this->enable_buffer();
99 io_mode = mode;
100 own_fd = false;
101 return this;
102 }
103
104 // Close gzipped file
105 gzfilebuf*
106 gzfilebuf::close()
107 {
108 // Fail immediately if no file is open
109 if (!this->is_open())
110 return NULL;
111 // Assume success
112 gzfilebuf* retval = this;
113 // Attempt to sync and close gzipped file
114 if (this->sync() == -1)
115 retval = NULL;
116 if (gzclose(file) < 0)
117 retval = NULL;
118 // File is now gone anyway (postcondition [27.8.1.3.8])
119 file = NULL;
120 own_fd = false;
121 // Destroy internal buffer if it exists
122 this->disable_buffer();
123 return retval;
124 }
125
126 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
127
128 // Convert int open mode to mode string
129 bool
130 gzfilebuf::open_mode(std::ios_base::openmode mode,
131 char* c_mode) const
132 {
133 bool testb = mode & std::ios_base::binary;
134 bool testi = mode & std::ios_base::in;
135 bool testo = mode & std::ios_base::out;
136 bool testt = mode & std::ios_base::trunc;
137 bool testa = mode & std::ios_base::app;
138
139 // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
140 // Original zfstream hardcoded the compression level to maximum here...
141 // Double the time for less than 1% size improvement seems
142 // excessive though - keeping it at the default level
143 // To change back, just append "9" to the next three mode strings
144 if (!testi && testo && !testt && !testa)
145 strcpy(c_mode, "w");
146 if (!testi && testo && !testt && testa)
147 strcpy(c_mode, "a");
148 if (!testi && testo && testt && !testa)
149 strcpy(c_mode, "w");
150 if (testi && !testo && !testt && !testa)
151 strcpy(c_mode, "r");
152 // No read/write mode yet
153 // if (testi && testo && !testt && !testa)
154 // strcpy(c_mode, "r+");
155 // if (testi && testo && testt && !testa)
156 // strcpy(c_mode, "w+");
157
158 // Mode string should be empty for invalid combination of flags
159 if (strlen(c_mode) == 0)
160 return false;
161 if (testb)
162 strcat(c_mode, "b");
163 return true;
164 }
165
166 // Determine number of characters in internal get buffer
167 std::streamsize
168 gzfilebuf::showmanyc()
169 {
170 // Calls to underflow will fail if file not opened for reading
171 if (!this->is_open() || !(io_mode & std::ios_base::in))
172 return -1;
173 // Make sure get area is in use
174 if (this->gptr() && (this->gptr() < this->egptr()))
175 return std::streamsize(this->egptr() - this->gptr());
176 else
177 return 0;
178 }
179
180 // Fill get area from gzipped file
181 gzfilebuf::int_type
182 gzfilebuf::underflow()
183 {
184 // If something is left in the get area by chance, return it
185 // (this shouldn't normally happen, as underflow is only supposed
186 // to be called when gptr >= egptr, but it serves as error check)
187 if (this->gptr() && (this->gptr() < this->egptr()))
188 return traits_type::to_int_type(*(this->gptr()));
189
190 // If the file hasn't been opened for reading, produce error
191 if (!this->is_open() || !(io_mode & std::ios_base::in))
192 return traits_type::eof();
193
194 // Attempt to fill internal buffer from gzipped file
195 // (buffer must be guaranteed to exist...)
196 int bytes_read = gzread(file, buffer, buffer_size);
197 // Indicates error or EOF
198 if (bytes_read <= 0)
199 {
200 // Reset get area
201 this->setg(buffer, buffer, buffer);
202 return traits_type::eof();
203 }
204 // Make all bytes read from file available as get area
205 this->setg(buffer, buffer, buffer + bytes_read);
206
207 // Return next character in get area
208 return traits_type::to_int_type(*(this->gptr()));
209 }
210
211 // Write put area to gzipped file
212 gzfilebuf::int_type
213 gzfilebuf::overflow(int_type c)
214 {
215 // Determine whether put area is in use
216 if (this->pbase())
217 {
218 // Double-check pointer range
219 if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
220 return traits_type::eof();
221 // Add extra character to buffer if not EOF
222 if (!traits_type::eq_int_type(c, traits_type::eof()))
223 {
224 *(this->pptr()) = traits_type::to_char_type(c);
225 this->pbump(1);
226 }
227 // Number of characters to write to file
228 int bytes_to_write = this->pptr() - this->pbase();
229 // Overflow doesn't fail if nothing is to be written
230 if (bytes_to_write > 0)
231 {
232 // If the file hasn't been opened for writing, produce error
233 if (!this->is_open() || !(io_mode & std::ios_base::out))
234 return traits_type::eof();
235 // If gzipped file won't accept all bytes written to it, fail
236 if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
237 return traits_type::eof();
238 // Reset next pointer to point to pbase on success
239 this->pbump(-bytes_to_write);
240 }
241 }
242 // Write extra character to file if not EOF
243 else if (!traits_type::eq_int_type(c, traits_type::eof()))
244 {
245 // If the file hasn't been opened for writing, produce error
246 if (!this->is_open() || !(io_mode & std::ios_base::out))
247 return traits_type::eof();
248 // Impromptu char buffer (allows "unbuffered" output)
249 char_type last_char = traits_type::to_char_type(c);
250 // If gzipped file won't accept this character, fail
251 if (gzwrite(file, &last_char, 1) != 1)
252 return traits_type::eof();
253 }
254
255 // If you got here, you have succeeded (even if c was EOF)
256 // The return value should therefore be non-EOF
257 if (traits_type::eq_int_type(c, traits_type::eof()))
258 return traits_type::not_eof(c);
259 else
260 return c;
261 }
262
263 // Assign new buffer
264 std::streambuf*
265 gzfilebuf::setbuf(char_type* p,
266 std::streamsize n)
267 {
268 // First make sure stuff is sync'ed, for safety
269 if (this->sync() == -1)
270 return NULL;
271 // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
272 // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
273 // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
274 // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
275 if (!p || !n)
276 {
277 // Replace existing buffer (if any) with small internal buffer
278 this->disable_buffer();
279 buffer = NULL;
280 buffer_size = 0;
281 own_buffer = true;
282 this->enable_buffer();
283 }
284 else
285 {
286 // Replace existing buffer (if any) with external buffer
287 this->disable_buffer();
288 buffer = p;
289 buffer_size = n;
290 own_buffer = false;
291 this->enable_buffer();
292 }
293 return this;
294 }
295
296 // Write put area to gzipped file (i.e. ensures that put area is empty)
297 int
298 gzfilebuf::sync()
299 {
300 return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
301 }
302
303 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
304
305 // Allocate internal buffer
306 void
307 gzfilebuf::enable_buffer()
308 {
309 // If internal buffer required, allocate one
310 if (own_buffer && !buffer)
311 {
312 // Check for buffered vs. "unbuffered"
313 if (buffer_size > 0)
314 {
315 // Allocate internal buffer
316 buffer = new char_type[buffer_size];
317 // Get area starts empty and will be expanded by underflow as need arises
318 this->setg(buffer, buffer, buffer);
319 // Setup entire internal buffer as put area.
320 // The one-past-end pointer actually points to the last element of the buffer,
321 // so that overflow(c) can safely add the extra character c to the sequence.
322 // These pointers remain in place for the duration of the buffer
323 this->setp(buffer, buffer + buffer_size - 1);
324 }
325 else
326 {
327 // Even in "unbuffered" case, (small?) get buffer is still required
328 buffer_size = SMALLBUFSIZE;
329 buffer = new char_type[buffer_size];
330 this->setg(buffer, buffer, buffer);
331 // "Unbuffered" means no put buffer
332 this->setp(0, 0);
333 }
334 }
335 else
336 {
337 // If buffer already allocated, reset buffer pointers just to make sure no
338 // stale chars are lying around
339 this->setg(buffer, buffer, buffer);
340 this->setp(buffer, buffer + buffer_size - 1);
341 }
342 }
343
344 // Destroy internal buffer
345 void
346 gzfilebuf::disable_buffer()
347 {
348 // If internal buffer exists, deallocate it
349 if (own_buffer && buffer)
350 {
351 // Preserve unbuffered status by zeroing size
352 if (!this->pbase())
353 buffer_size = 0;
354 delete[] buffer;
355 buffer = NULL;
356 this->setg(0, 0, 0);
357 this->setp(0, 0);
358 }
359 else
360 {
361 // Reset buffer pointers to initial state if external buffer exists
362 this->setg(buffer, buffer, buffer);
363 if (buffer)
364 this->setp(buffer, buffer + buffer_size - 1);
365 else
366 this->setp(0, 0);
367 }
368 }
369
370 /*****************************************************************************/
371
372 // Default constructor initializes stream buffer
373 gzifstream::gzifstream()
374 : std::istream(NULL), sb()
375 { this->init(&sb); }
376
377 // Initialize stream buffer and open file
378 gzifstream::gzifstream(const char* name,
379 std::ios_base::openmode mode)
380 : std::istream(NULL), sb()
381 {
382 this->init(&sb);
383 this->open(name, mode);
384 }
385
386 // Initialize stream buffer and attach to file
387 gzifstream::gzifstream(int fd,
388 std::ios_base::openmode mode)
389 : std::istream(NULL), sb()
390 {
391 this->init(&sb);
392 this->attach(fd, mode);
393 }
394
395 // Open file and go into fail() state if unsuccessful
396 void
397 gzifstream::open(const char* name,
398 std::ios_base::openmode mode)
399 {
400 if (!sb.open(name, mode | std::ios_base::in))
401 this->setstate(std::ios_base::failbit);
402 else
403 this->clear();
404 }
405
406 // Attach to file and go into fail() state if unsuccessful
407 void
408 gzifstream::attach(int fd,
409 std::ios_base::openmode mode)
410 {
411 if (!sb.attach(fd, mode | std::ios_base::in))
412 this->setstate(std::ios_base::failbit);
413 else
414 this->clear();
415 }
416
417 // Close file
418 void
419 gzifstream::close()
420 {
421 if (!sb.close())
422 this->setstate(std::ios_base::failbit);
423 }
424
425 /*****************************************************************************/
426
427 // Default constructor initializes stream buffer
428 gzofstream::gzofstream()
429 : std::ostream(NULL), sb()
430 { this->init(&sb); }
431
432 // Initialize stream buffer and open file
433 gzofstream::gzofstream(const char* name,
434 std::ios_base::openmode mode)
435 : std::ostream(NULL), sb()
436 {
437 this->init(&sb);
438 this->open(name, mode);
439 }
440
441 // Initialize stream buffer and attach to file
442 gzofstream::gzofstream(int fd,
443 std::ios_base::openmode mode)
444 : std::ostream(NULL), sb()
445 {
446 this->init(&sb);
447 this->attach(fd, mode);
448 }
449
450 // Open file and go into fail() state if unsuccessful
451 void
452 gzofstream::open(const char* name,
453 std::ios_base::openmode mode)
454 {
455 if (!sb.open(name, mode | std::ios_base::out))
456 this->setstate(std::ios_base::failbit);
457 else
458 this->clear();
459 }
460
461 // Attach to file and go into fail() state if unsuccessful
462 void
463 gzofstream::attach(int fd,
464 std::ios_base::openmode mode)
465 {
466 if (!sb.attach(fd, mode | std::ios_base::out))
467 this->setstate(std::ios_base::failbit);
468 else
469 this->clear();
470 }
471
472 // Close file
473 void
474 gzofstream::close()
475 {
476 if (!sb.close())
477 this->setstate(std::ios_base::failbit);
478 }
0 /*
1 * A C++ I/O streams interface to the zlib gz* functions
2 *
3 * by Ludwig Schwardt <schwardt@sun.ac.za>
4 * original version by Kevin Ruland <kevin@rodin.wustl.edu>
5 *
6 * This version is standard-compliant and compatible with gcc 3.x.
7 */
8
9 #ifndef ZFSTREAM_H
10 #define ZFSTREAM_H
11
12 #include <istream> // not iostream, since we don't need cin/cout
13 #include <ostream>
14 #include "zlib.h"
15
16 /*****************************************************************************/
17
18 /**
19 * @brief Gzipped file stream buffer class.
20 *
21 * This class implements basic_filebuf for gzipped files. It doesn't yet support
22 * seeking (allowed by zlib but slow/limited), putback and read/write access
23 * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
24 * file streambuf.
25 */
26 class gzfilebuf : public std::streambuf
27 {
28 public:
29 // Default constructor.
30 gzfilebuf();
31
32 // Destructor.
33 virtual
34 ~gzfilebuf();
35
36 /**
37 * @brief Set compression level and strategy on the fly.
38 * @param comp_level Compression level (see zlib.h for allowed values)
39 * @param comp_strategy Compression strategy (see zlib.h for allowed values)
40 * @return Z_OK on success, Z_STREAM_ERROR otherwise.
41 *
42 * Unfortunately, these parameters cannot be modified separately, as the
43 * previous zfstream version assumed. Since the strategy is seldom changed,
44 * it can default and setcompression(level) then becomes like the old
45 * setcompressionlevel(level).
46 */
47 int
48 setcompression(int comp_level,
49 int comp_strategy = Z_DEFAULT_STRATEGY);
50
51 /**
52 * @brief Check if file is open.
53 * @return True if file is open.
54 */
55 bool
56 is_open() const { return (file != NULL); }
57
58 /**
59 * @brief Open gzipped file.
60 * @param name File name.
61 * @param mode Open mode flags.
62 * @return @c this on success, NULL on failure.
63 */
64 gzfilebuf*
65 open(const char* name,
66 std::ios_base::openmode mode);
67
68 /**
69 * @brief Attach to already open gzipped file.
70 * @param fd File descriptor.
71 * @param mode Open mode flags.
72 * @return @c this on success, NULL on failure.
73 */
74 gzfilebuf*
75 attach(int fd,
76 std::ios_base::openmode mode);
77
78 /**
79 * @brief Close gzipped file.
80 * @return @c this on success, NULL on failure.
81 */
82 gzfilebuf*
83 close();
84
85 protected:
86 /**
87 * @brief Convert ios open mode int to mode string used by zlib.
88 * @return True if valid mode flag combination.
89 */
90 bool
91 open_mode(std::ios_base::openmode mode,
92 char* c_mode) const;
93
94 /**
95 * @brief Number of characters available in stream buffer.
96 * @return Number of characters.
97 *
98 * This indicates number of characters in get area of stream buffer.
99 * These characters can be read without accessing the gzipped file.
100 */
101 virtual std::streamsize
102 showmanyc();
103
104 /**
105 * @brief Fill get area from gzipped file.
106 * @return First character in get area on success, EOF on error.
107 *
108 * This actually reads characters from gzipped file to stream
109 * buffer. Always buffered.
110 */
111 virtual int_type
112 underflow();
113
114 /**
115 * @brief Write put area to gzipped file.
116 * @param c Extra character to add to buffer contents.
117 * @return Non-EOF on success, EOF on error.
118 *
119 * This actually writes characters in stream buffer to
120 * gzipped file. With unbuffered output this is done one
121 * character at a time.
122 */
123 virtual int_type
124 overflow(int_type c = traits_type::eof());
125
126 /**
127 * @brief Installs external stream buffer.
128 * @param p Pointer to char buffer.
129 * @param n Size of external buffer.
130 * @return @c this on success, NULL on failure.
131 *
132 * Call setbuf(0,0) to enable unbuffered output.
133 */
134 virtual std::streambuf*
135 setbuf(char_type* p,
136 std::streamsize n);
137
138 /**
139 * @brief Flush stream buffer to file.
140 * @return 0 on success, -1 on error.
141 *
142 * This calls underflow(EOF) to do the job.
143 */
144 virtual int
145 sync();
146
147 //
148 // Some future enhancements
149 //
150 // virtual int_type uflow();
151 // virtual int_type pbackfail(int_type c = traits_type::eof());
152 // virtual pos_type
153 // seekoff(off_type off,
154 // std::ios_base::seekdir way,
155 // std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
156 // virtual pos_type
157 // seekpos(pos_type sp,
158 // std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
159
160 private:
161 /**
162 * @brief Allocate internal buffer.
163 *
164 * This function is safe to call multiple times. It will ensure
165 * that a proper internal buffer exists if it is required. If the
166 * buffer already exists or is external, the buffer pointers will be
167 * reset to their original state.
168 */
169 void
170 enable_buffer();
171
172 /**
173 * @brief Destroy internal buffer.
174 *
175 * This function is safe to call multiple times. It will ensure
176 * that the internal buffer is deallocated if it exists. In any
177 * case, it will also reset the buffer pointers.
178 */
179 void
180 disable_buffer();
181
182 /**
183 * Underlying file pointer.
184 */
185 gzFile file;
186
187 /**
188 * Mode in which file was opened.
189 */
190 std::ios_base::openmode io_mode;
191
192 /**
193 * @brief True if this object owns file descriptor.
194 *
195 * This makes the class responsible for closing the file
196 * upon destruction.
197 */
198 bool own_fd;
199
200 /**
201 * @brief Stream buffer.
202 *
203 * For simplicity this remains allocated on the free store for the
204 * entire life span of the gzfilebuf object, unless replaced by setbuf.
205 */
206 char_type* buffer;
207
208 /**
209 * @brief Stream buffer size.
210 *
211 * Defaults to system default buffer size (typically 8192 bytes).
212 * Modified by setbuf.
213 */
214 std::streamsize buffer_size;
215
216 /**
217 * @brief True if this object owns stream buffer.
218 *
219 * This makes the class responsible for deleting the buffer
220 * upon destruction.
221 */
222 bool own_buffer;
223 };
224
225 /*****************************************************************************/
226
227 /**
228 * @brief Gzipped file input stream class.
229 *
230 * This class implements ifstream for gzipped files. Seeking and putback
231 * is not supported yet.
232 */
233 class gzifstream : public std::istream
234 {
235 public:
236 // Default constructor
237 gzifstream();
238
239 /**
240 * @brief Construct stream on gzipped file to be opened.
241 * @param name File name.
242 * @param mode Open mode flags (forced to contain ios::in).
243 */
244 explicit
245 gzifstream(const char* name,
246 std::ios_base::openmode mode = std::ios_base::in);
247
248 /**
249 * @brief Construct stream on already open gzipped file.
250 * @param fd File descriptor.
251 * @param mode Open mode flags (forced to contain ios::in).
252 */
253 explicit
254 gzifstream(int fd,
255 std::ios_base::openmode mode = std::ios_base::in);
256
257 /**
258 * Obtain underlying stream buffer.
259 */
260 gzfilebuf*
261 rdbuf() const
262 { return const_cast<gzfilebuf*>(&sb); }
263
264 /**
265 * @brief Check if file is open.
266 * @return True if file is open.
267 */
268 bool
269 is_open() { return sb.is_open(); }
270
271 /**
272 * @brief Open gzipped file.
273 * @param name File name.
274 * @param mode Open mode flags (forced to contain ios::in).
275 *
276 * Stream will be in state good() if file opens successfully;
277 * otherwise in state fail(). This differs from the behavior of
278 * ifstream, which never sets the state to good() and therefore
279 * won't allow you to reuse the stream for a second file unless
280 * you manually clear() the state. The choice is a matter of
281 * convenience.
282 */
283 void
284 open(const char* name,
285 std::ios_base::openmode mode = std::ios_base::in);
286
287 /**
288 * @brief Attach to already open gzipped file.
289 * @param fd File descriptor.
290 * @param mode Open mode flags (forced to contain ios::in).
291 *
292 * Stream will be in state good() if attach succeeded; otherwise
293 * in state fail().
294 */
295 void
296 attach(int fd,
297 std::ios_base::openmode mode = std::ios_base::in);
298
299 /**
300 * @brief Close gzipped file.
301 *
302 * Stream will be in state fail() if close failed.
303 */
304 void
305 close();
306
307 private:
308 /**
309 * Underlying stream buffer.
310 */
311 gzfilebuf sb;
312 };
313
314 /*****************************************************************************/
315
316 /**
317 * @brief Gzipped file output stream class.
318 *
319 * This class implements ofstream for gzipped files. Seeking and putback
320 * is not supported yet.
321 */
322 class gzofstream : public std::ostream
323 {
324 public:
325 // Default constructor
326 gzofstream();
327
328 /**
329 * @brief Construct stream on gzipped file to be opened.
330 * @param name File name.
331 * @param mode Open mode flags (forced to contain ios::out).
332 */
333 explicit
334 gzofstream(const char* name,
335 std::ios_base::openmode mode = std::ios_base::out);
336
337 /**
338 * @brief Construct stream on already open gzipped file.
339 * @param fd File descriptor.
340 * @param mode Open mode flags (forced to contain ios::out).
341 */
342 explicit
343 gzofstream(int fd,
344 std::ios_base::openmode mode = std::ios_base::out);
345
346 /**
347 * Obtain underlying stream buffer.
348 */
349 gzfilebuf*
350 rdbuf() const
351 { return const_cast<gzfilebuf*>(&sb); }
352
353 /**
354 * @brief Check if file is open.
355 * @return True if file is open.
356 */
357 bool
358 is_open() { return sb.is_open(); }
359
360 /**
361 * @brief Open gzipped file.
362 * @param name File name.
363 * @param mode Open mode flags (forced to contain ios::out).
364 *
365 * Stream will be in state good() if file opens successfully;
366 * otherwise in state fail(). This differs from the behavior of
367 * ofstream, which never sets the state to good() and therefore
368 * won't allow you to reuse the stream for a second file unless
369 * you manually clear() the state. The choice is a matter of
370 * convenience.
371 */
372 void
373 open(const char* name,
374 std::ios_base::openmode mode = std::ios_base::out);
375
376 /**
377 * @brief Attach to already open gzipped file.
378 * @param fd File descriptor.
379 * @param mode Open mode flags (forced to contain ios::out).
380 *
381 * Stream will be in state good() if attach succeeded; otherwise
382 * in state fail().
383 */
384 void
385 attach(int fd,
386 std::ios_base::openmode mode = std::ios_base::out);
387
388 /**
389 * @brief Close gzipped file.
390 *
391 * Stream will be in state fail() if close failed.
392 */
393 void
394 close();
395
396 private:
397 /**
398 * Underlying stream buffer.
399 */
400 gzfilebuf sb;
401 };
402
403 /*****************************************************************************/
404
405 /**
406 * @brief Gzipped file output stream manipulator class.
407 *
408 * This class defines a two-argument manipulator for gzofstream. It is used
409 * as base for the setcompression(int,int) manipulator.
410 */
411 template<typename T1, typename T2>
412 class gzomanip2
413 {
414 public:
415 // Allows insertor to peek at internals
416 template <typename Ta, typename Tb>
417 friend gzofstream&
418 operator<<(gzofstream&,
419 const gzomanip2<Ta,Tb>&);
420
421 // Constructor
422 gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
423 T1 v1,
424 T2 v2);
425 private:
426 // Underlying manipulator function
427 gzofstream&
428 (*func)(gzofstream&, T1, T2);
429
430 // Arguments for manipulator function
431 T1 val1;
432 T2 val2;
433 };
434
435 /*****************************************************************************/
436
437 // Manipulator function thunks through to stream buffer
438 inline gzofstream&
439 setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
440 {
441 (gzs.rdbuf())->setcompression(l, s);
442 return gzs;
443 }
444
445 // Manipulator constructor stores arguments
446 template<typename T1, typename T2>
447 inline
448 gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
449 T1 v1,
450 T2 v2)
451 : func(f), val1(v1), val2(v2)
452 { }
453
454 // Insertor applies underlying manipulator function to stream
455 template<typename T1, typename T2>
456 inline gzofstream&
457 operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
458 { return (*m.func)(s, m.val1, m.val2); }
459
460 // Insert this onto stream to simplify setting of compression level
461 inline gzomanip2<int,int>
462 setcompression(int l, int s = Z_DEFAULT_STRATEGY)
463 { return gzomanip2<int,int>(&setcompression, l, s); }
464
465 #endif // ZFSTREAM_H
0
1 ; match.asm -- Pentium-Pro optimized version of longest_match()
2 ;
3 ; Updated for zlib 1.1.3 and converted to MASM 6.1x
4 ; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
5 ; and Chuck Walbourn <chuckw@kinesoft.com>
6 ; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
7 ;
8 ; This is free software; you can redistribute it and/or modify it
9 ; under the terms of the GNU General Public License.
10
11 ; Based on match.S
12 ; Written for zlib 1.1.2
13 ; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
14
15 .686P
16 .MODEL FLAT
17
18 ;===========================================================================
19 ; EQUATES
20 ;===========================================================================
21
22 MAX_MATCH EQU 258
23 MIN_MATCH EQU 3
24 MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1)
25 MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7))
26
27 ;===========================================================================
28 ; STRUCTURES
29 ;===========================================================================
30
31 ; This STRUCT assumes a 4-byte alignment
32
33 DEFLATE_STATE STRUCT
34 ds_strm dd ?
35 ds_status dd ?
36 ds_pending_buf dd ?
37 ds_pending_buf_size dd ?
38 ds_pending_out dd ?
39 ds_pending dd ?
40 ds_wrap dd ?
41 ds_data_type db ?
42 ds_method db ?
43 db ? ; padding
44 db ? ; padding
45 ds_last_flush dd ?
46 ds_w_size dd ? ; used
47 ds_w_bits dd ?
48 ds_w_mask dd ? ; used
49 ds_window dd ? ; used
50 ds_window_size dd ?
51 ds_prev dd ? ; used
52 ds_head dd ?
53 ds_ins_h dd ?
54 ds_hash_size dd ?
55 ds_hash_bits dd ?
56 ds_hash_mask dd ?
57 ds_hash_shift dd ?
58 ds_block_start dd ?
59 ds_match_length dd ? ; used
60 ds_prev_match dd ? ; used
61 ds_match_available dd ?
62 ds_strstart dd ? ; used
63 ds_match_start dd ? ; used
64 ds_lookahead dd ? ; used
65 ds_prev_length dd ? ; used
66 ds_max_chain_length dd ? ; used
67 ds_max_laxy_match dd ?
68 ds_level dd ?
69 ds_strategy dd ?
70 ds_good_match dd ? ; used
71 ds_nice_match dd ? ; used
72
73 ; Don't need anymore of the struct for match
74 DEFLATE_STATE ENDS
75
76 ;===========================================================================
77 ; CODE
78 ;===========================================================================
79 _TEXT SEGMENT
80
81 ;---------------------------------------------------------------------------
82 ; match_init
83 ;---------------------------------------------------------------------------
84 ALIGN 4
85 PUBLIC _match_init
86 _match_init PROC
87 ; no initialization needed
88 ret
89 _match_init ENDP
90
91 ;---------------------------------------------------------------------------
92 ; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
93 ;---------------------------------------------------------------------------
94 ALIGN 4
95
96 PUBLIC _longest_match
97 _longest_match PROC
98
99 ; Since this code uses EBP for a scratch register, the stack frame must
100 ; be manually constructed and referenced relative to the ESP register.
101
102 ; Stack image
103 ; Variables
104 chainlenwmask = 0 ; high word: current chain len
105 ; low word: s->wmask
106 window = 4 ; local copy of s->window
107 windowbestlen = 8 ; s->window + bestlen
108 scanend = 12 ; last two bytes of string
109 scanstart = 16 ; first two bytes of string
110 scanalign = 20 ; dword-misalignment of string
111 nicematch = 24 ; a good enough match size
112 bestlen = 28 ; size of best match so far
113 scan = 32 ; ptr to string wanting match
114 varsize = 36 ; number of bytes (also offset to last saved register)
115
116 ; Saved Registers (actually pushed into place)
117 ebx_save = 36
118 edi_save = 40
119 esi_save = 44
120 ebp_save = 48
121
122 ; Parameters
123 retaddr = 52
124 deflatestate = 56
125 curmatch = 60
126
127 ; Save registers that the compiler may be using
128 push ebp
129 push edi
130 push esi
131 push ebx
132
133 ; Allocate local variable space
134 sub esp,varsize
135
136 ; Retrieve the function arguments. ecx will hold cur_match
137 ; throughout the entire function. edx will hold the pointer to the
138 ; deflate_state structure during the function's setup (before
139 ; entering the main loop).
140
141 mov edx, [esp+deflatestate]
142 ASSUME edx:PTR DEFLATE_STATE
143
144 mov ecx, [esp+curmatch]
145
146 ; uInt wmask = s->w_mask;
147 ; unsigned chain_length = s->max_chain_length;
148 ; if (s->prev_length >= s->good_match) {
149 ; chain_length >>= 2;
150 ; }
151
152 mov eax, [edx].ds_prev_length
153 mov ebx, [edx].ds_good_match
154 cmp eax, ebx
155 mov eax, [edx].ds_w_mask
156 mov ebx, [edx].ds_max_chain_length
157 jl SHORT LastMatchGood
158 shr ebx, 2
159 LastMatchGood:
160
161 ; chainlen is decremented once beforehand so that the function can
162 ; use the sign flag instead of the zero flag for the exit test.
163 ; It is then shifted into the high word, to make room for the wmask
164 ; value, which it will always accompany.
165
166 dec ebx
167 shl ebx, 16
168 or ebx, eax
169 mov [esp+chainlenwmask], ebx
170
171 ; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
172
173 mov eax, [edx].ds_nice_match
174 mov ebx, [edx].ds_lookahead
175 cmp ebx, eax
176 jl SHORT LookaheadLess
177 mov ebx, eax
178 LookaheadLess:
179 mov [esp+nicematch], ebx
180
181 ;/* register Bytef *scan = s->window + s->strstart; */
182
183 mov esi, [edx].ds_window
184 mov [esp+window], esi
185 mov ebp, [edx].ds_strstart
186 lea edi, [esi+ebp]
187 mov [esp+scan],edi
188
189 ;/* Determine how many bytes the scan ptr is off from being */
190 ;/* dword-aligned. */
191
192 mov eax, edi
193 neg eax
194 and eax, 3
195 mov [esp+scanalign], eax
196
197 ;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
198 ;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
199
200 mov eax, [edx].ds_w_size
201 sub eax, MIN_LOOKAHEAD
202 sub ebp, eax
203 jg SHORT LimitPositive
204 xor ebp, ebp
205 LimitPositive:
206
207 ;/* int best_len = s->prev_length; */
208
209 mov eax, [edx].ds_prev_length
210 mov [esp+bestlen], eax
211
212 ;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
213
214 add esi, eax
215 mov [esp+windowbestlen], esi
216
217 ;/* register ush scan_start = *(ushf*)scan; */
218 ;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
219 ;/* Posf *prev = s->prev; */
220
221 movzx ebx, WORD PTR[edi]
222 mov [esp+scanstart], ebx
223 movzx ebx, WORD PTR[eax+edi-1]
224 mov [esp+scanend], ebx
225 mov edi, [edx].ds_prev
226
227 ;/* Jump into the main loop. */
228
229 mov edx, [esp+chainlenwmask]
230 jmp SHORT LoopEntry
231
232 ;/* do {
233 ; * match = s->window + cur_match;
234 ; * if (*(ushf*)(match+best_len-1) != scan_end ||
235 ; * *(ushf*)match != scan_start) continue;
236 ; * [...]
237 ; * } while ((cur_match = prev[cur_match & wmask]) > limit
238 ; * && --chain_length != 0);
239 ; *
240 ; * Here is the inner loop of the function. The function will spend the
241 ; * majority of its time in this loop, and majority of that time will
242 ; * be spent in the first ten instructions.
243 ; *
244 ; * Within this loop:
245 ; * %ebx = scanend
246 ; * %ecx = curmatch
247 ; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
248 ; * %esi = windowbestlen - i.e., (window + bestlen)
249 ; * %edi = prev
250 ; * %ebp = limit
251 ; */
252
253 ALIGN 4
254 LookupLoop:
255 and ecx, edx
256 movzx ecx, WORD PTR[edi+ecx*2]
257 cmp ecx, ebp
258 jbe LeaveNow
259 sub edx, 000010000H
260 js LeaveNow
261
262 LoopEntry:
263 movzx eax, WORD PTR[esi+ecx-1]
264 cmp eax, ebx
265 jnz SHORT LookupLoop
266
267 mov eax, [esp+window]
268 movzx eax, WORD PTR[eax+ecx]
269 cmp eax, [esp+scanstart]
270 jnz SHORT LookupLoop
271
272 ;/* Store the current value of chainlen. */
273
274 mov [esp+chainlenwmask], edx
275
276 ;/* Point %edi to the string under scrutiny, and %esi to the string we */
277 ;/* are hoping to match it up with. In actuality, %esi and %edi are */
278 ;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
279 ;/* initialized to -(MAX_MATCH_8 - scanalign). */
280
281 mov esi, [esp+window]
282 mov edi, [esp+scan]
283 add esi, ecx
284 mov eax, [esp+scanalign]
285 mov edx, -MAX_MATCH_8
286 lea edi, [edi+eax+MAX_MATCH_8]
287 lea esi, [esi+eax+MAX_MATCH_8]
288
289 ;/* Test the strings for equality, 8 bytes at a time. At the end,
290 ; * adjust %edx so that it is offset to the exact byte that mismatched.
291 ; *
292 ; * We already know at this point that the first three bytes of the
293 ; * strings match each other, and they can be safely passed over before
294 ; * starting the compare loop. So what this code does is skip over 0-3
295 ; * bytes, as much as necessary in order to dword-align the %edi
296 ; * pointer. (%esi will still be misaligned three times out of four.)
297 ; *
298 ; * It should be confessed that this loop usually does not represent
299 ; * much of the total running time. Replacing it with a more
300 ; * straightforward "rep cmpsb" would not drastically degrade
301 ; * performance.
302 ; */
303
304 LoopCmps:
305 mov eax, DWORD PTR[esi+edx]
306 xor eax, DWORD PTR[edi+edx]
307 jnz SHORT LeaveLoopCmps
308
309 mov eax, DWORD PTR[esi+edx+4]
310 xor eax, DWORD PTR[edi+edx+4]
311 jnz SHORT LeaveLoopCmps4
312
313 add edx, 8
314 jnz SHORT LoopCmps
315 jmp LenMaximum
316 ALIGN 4
317
318 LeaveLoopCmps4:
319 add edx, 4
320
321 LeaveLoopCmps:
322 test eax, 00000FFFFH
323 jnz SHORT LenLower
324
325 add edx, 2
326 shr eax, 16
327
328 LenLower:
329 sub al, 1
330 adc edx, 0
331
332 ;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
333 ;/* then automatically accept it as the best possible match and leave. */
334
335 lea eax, [edi+edx]
336 mov edi, [esp+scan]
337 sub eax, edi
338 cmp eax, MAX_MATCH
339 jge SHORT LenMaximum
340
341 ;/* If the length of the match is not longer than the best match we */
342 ;/* have so far, then forget it and return to the lookup loop. */
343
344 mov edx, [esp+deflatestate]
345 mov ebx, [esp+bestlen]
346 cmp eax, ebx
347 jg SHORT LongerMatch
348 mov esi, [esp+windowbestlen]
349 mov edi, [edx].ds_prev
350 mov ebx, [esp+scanend]
351 mov edx, [esp+chainlenwmask]
352 jmp LookupLoop
353 ALIGN 4
354
355 ;/* s->match_start = cur_match; */
356 ;/* best_len = len; */
357 ;/* if (len >= nice_match) break; */
358 ;/* scan_end = *(ushf*)(scan+best_len-1); */
359
360 LongerMatch:
361 mov ebx, [esp+nicematch]
362 mov [esp+bestlen], eax
363 mov [edx].ds_match_start, ecx
364 cmp eax, ebx
365 jge SHORT LeaveNow
366 mov esi, [esp+window]
367 add esi, eax
368 mov [esp+windowbestlen], esi
369 movzx ebx, WORD PTR[edi+eax-1]
370 mov edi, [edx].ds_prev
371 mov [esp+scanend], ebx
372 mov edx, [esp+chainlenwmask]
373 jmp LookupLoop
374 ALIGN 4
375
376 ;/* Accept the current string, with the maximum possible length. */
377
378 LenMaximum:
379 mov edx, [esp+deflatestate]
380 mov DWORD PTR[esp+bestlen], MAX_MATCH
381 mov [edx].ds_match_start, ecx
382
383 ;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
384 ;/* return s->lookahead; */
385
386 LeaveNow:
387 mov edx, [esp+deflatestate]
388 mov ebx, [esp+bestlen]
389 mov eax, [edx].ds_lookahead
390 cmp ebx, eax
391 jg SHORT LookaheadRet
392 mov eax, ebx
393 LookaheadRet:
394
395 ; Restore the stack and return from whence we came.
396
397 add esp, varsize
398 pop ebx
399 pop esi
400 pop edi
401 pop ebp
402 ret
403
404 _longest_match ENDP
405
406 _TEXT ENDS
407 END
0 ;
1 ; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
2 ; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
3 ; File written by Gilles Vollant, by modifiying the longest_match
4 ; from Jean-loup Gailly in deflate.c
5 ; It need wmask == 0x7fff
6 ; (assembly code is faster with a fixed wmask)
7 ;
8 ; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK)
9 ; I compile with : "ml /coff /Zi /c gvmat32.asm"
10 ;
11
12 ;uInt longest_match_7fff(s, cur_match)
13 ; deflate_state *s;
14 ; IPos cur_match; /* current match */
15
16 NbStack equ 76
17 cur_match equ dword ptr[esp+NbStack-0]
18 str_s equ dword ptr[esp+NbStack-4]
19 ; 5 dword on top (ret,ebp,esi,edi,ebx)
20 adrret equ dword ptr[esp+NbStack-8]
21 pushebp equ dword ptr[esp+NbStack-12]
22 pushedi equ dword ptr[esp+NbStack-16]
23 pushesi equ dword ptr[esp+NbStack-20]
24 pushebx equ dword ptr[esp+NbStack-24]
25
26 chain_length equ dword ptr [esp+NbStack-28]
27 limit equ dword ptr [esp+NbStack-32]
28 best_len equ dword ptr [esp+NbStack-36]
29 window equ dword ptr [esp+NbStack-40]
30 prev equ dword ptr [esp+NbStack-44]
31 scan_start equ word ptr [esp+NbStack-48]
32 wmask equ dword ptr [esp+NbStack-52]
33 match_start_ptr equ dword ptr [esp+NbStack-56]
34 nice_match equ dword ptr [esp+NbStack-60]
35 scan equ dword ptr [esp+NbStack-64]
36
37 windowlen equ dword ptr [esp+NbStack-68]
38 match_start equ dword ptr [esp+NbStack-72]
39 strend equ dword ptr [esp+NbStack-76]
40 NbStackAdd equ (NbStack-24)
41
42 .386p
43
44 name gvmatch
45 .MODEL FLAT
46
47
48
49 ; all the +addstr offsets are due to the addition of pending_buf_size in zlib 1.04
50 ; and adding gzhead and gzindex in zlib 1.2.2.1
51 ; in the deflate_state structure since the asm code was first written
52 ; (if you compile with zlib 1.0.4 or older, set addstr to 0).
53 ; (if you compiler with zlib between 1.04 and 1.2.1, set addstr to 4)
54 ; Note : these value are good with a 8 bytes boundary pack structure
55
56 addstr equ 4+8
57 dep_chain_length equ 70h+addstr
58 dep_window equ 2ch+addstr
59 dep_strstart equ 60h+addstr
60 dep_prev_length equ 6ch+addstr
61 dep_nice_match equ 84h+addstr
62 dep_w_size equ 20h+addstr
63 dep_prev equ 34h+addstr
64 dep_w_mask equ 28h+addstr
65 dep_good_match equ 80h+addstr
66 dep_match_start equ 64h+addstr
67 dep_lookahead equ 68h+addstr
68
69
70 _TEXT segment
71
72 IFDEF NOUNDERLINE
73 public longest_match_7fff
74 public longest_match_686
75 ; public match_init
76 ELSE
77 public _longest_match_7fff
78 public _longest_match_686
79 ; public _match_init
80 ENDIF
81
82 MAX_MATCH equ 258
83 MIN_MATCH equ 3
84 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
85
86
87
88 IFDEF NOUNDERLINE
89 ;match_init proc near
90 ; ret
91 ;match_init endp
92 ELSE
93 ;_match_init proc near
94 ; ret
95 ;_match_init endp
96 ENDIF
97
98
99 IFDEF NOUNDERLINE
100 longest_match_7fff proc near
101 ELSE
102 _longest_match_7fff proc near
103 ENDIF
104
105 mov edx,[esp+4]
106
107
108
109 push ebp
110 push edi
111 push esi
112 push ebx
113
114 sub esp,NbStackAdd
115
116 ; initialize or check the variables used in match.asm.
117 mov ebp,edx
118
119 ; chain_length = s->max_chain_length
120 ; if (prev_length>=good_match) chain_length >>= 2
121 mov edx,[ebp+dep_chain_length]
122 mov ebx,[ebp+dep_prev_length]
123 cmp [ebp+dep_good_match],ebx
124 ja noshr
125 shr edx,2
126 noshr:
127 ; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
128 inc edx
129 mov edi,[ebp+dep_nice_match]
130 mov chain_length,edx
131 mov eax,[ebp+dep_lookahead]
132 cmp eax,edi
133 ; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
134 jae nolookaheadnicematch
135 mov edi,eax
136 nolookaheadnicematch:
137 ; best_len = s->prev_length
138 mov best_len,ebx
139
140 ; window = s->window
141 mov esi,[ebp+dep_window]
142 mov ecx,[ebp+dep_strstart]
143 mov window,esi
144
145 mov nice_match,edi
146 ; scan = window + strstart
147 add esi,ecx
148 mov scan,esi
149 ; dx = *window
150 mov dx,word ptr [esi]
151 ; bx = *(window+best_len-1)
152 mov bx,word ptr [esi+ebx-1]
153 add esi,MAX_MATCH-1
154 ; scan_start = *scan
155 mov scan_start,dx
156 ; strend = scan + MAX_MATCH-1
157 mov strend,esi
158 ; bx = scan_end = *(window+best_len-1)
159
160 ; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
161 ; s->strstart - (IPos)MAX_DIST(s) : NIL;
162
163 mov esi,[ebp+dep_w_size]
164 sub esi,MIN_LOOKAHEAD
165 ; here esi = MAX_DIST(s)
166 sub ecx,esi
167 ja nodist
168 xor ecx,ecx
169 nodist:
170 mov limit,ecx
171
172 ; prev = s->prev
173 mov edx,[ebp+dep_prev]
174 mov prev,edx
175
176 ;
177 mov edx,dword ptr [ebp+dep_match_start]
178 mov bp,scan_start
179 mov eax,cur_match
180 mov match_start,edx
181
182 mov edx,window
183 mov edi,edx
184 add edi,best_len
185 mov esi,prev
186 dec edi
187 ; windowlen = window + best_len -1
188 mov windowlen,edi
189
190 jmp beginloop2
191 align 4
192
193 ; here, in the loop
194 ; eax = ax = cur_match
195 ; ecx = limit
196 ; bx = scan_end
197 ; bp = scan_start
198 ; edi = windowlen (window + best_len -1)
199 ; esi = prev
200
201
202 ;// here; chain_length <=16
203 normalbeg0add16:
204 add chain_length,16
205 jz exitloop
206 normalbeg0:
207 cmp word ptr[edi+eax],bx
208 je normalbeg2noroll
209 rcontlabnoroll:
210 ; cur_match = prev[cur_match & wmask]
211 and eax,7fffh
212 mov ax,word ptr[esi+eax*2]
213 ; if cur_match > limit, go to exitloop
214 cmp ecx,eax
215 jnb exitloop
216 ; if --chain_length != 0, go to exitloop
217 dec chain_length
218 jnz normalbeg0
219 jmp exitloop
220
221 normalbeg2noroll:
222 ; if (scan_start==*(cur_match+window)) goto normalbeg2
223 cmp bp,word ptr[edx+eax]
224 jne rcontlabnoroll
225 jmp normalbeg2
226
227 contloop3:
228 mov edi,windowlen
229
230 ; cur_match = prev[cur_match & wmask]
231 and eax,7fffh
232 mov ax,word ptr[esi+eax*2]
233 ; if cur_match > limit, go to exitloop
234 cmp ecx,eax
235 jnbexitloopshort1:
236 jnb exitloop
237 ; if --chain_length != 0, go to exitloop
238
239
240 ; begin the main loop
241 beginloop2:
242 sub chain_length,16+1
243 ; if chain_length <=16, don't use the unrolled loop
244 jna normalbeg0add16
245
246 do16:
247 cmp word ptr[edi+eax],bx
248 je normalbeg2dc0
249
250 maccn MACRO lab
251 and eax,7fffh
252 mov ax,word ptr[esi+eax*2]
253 cmp ecx,eax
254 jnb exitloop
255 cmp word ptr[edi+eax],bx
256 je lab
257 ENDM
258
259 rcontloop0:
260 maccn normalbeg2dc1
261
262 rcontloop1:
263 maccn normalbeg2dc2
264
265 rcontloop2:
266 maccn normalbeg2dc3
267
268 rcontloop3:
269 maccn normalbeg2dc4
270
271 rcontloop4:
272 maccn normalbeg2dc5
273
274 rcontloop5:
275 maccn normalbeg2dc6
276
277 rcontloop6:
278 maccn normalbeg2dc7
279
280 rcontloop7:
281 maccn normalbeg2dc8
282
283 rcontloop8:
284 maccn normalbeg2dc9
285
286 rcontloop9:
287 maccn normalbeg2dc10
288
289 rcontloop10:
290 maccn short normalbeg2dc11
291
292 rcontloop11:
293 maccn short normalbeg2dc12
294
295 rcontloop12:
296 maccn short normalbeg2dc13
297
298 rcontloop13:
299 maccn short normalbeg2dc14
300
301 rcontloop14:
302 maccn short normalbeg2dc15
303
304 rcontloop15:
305 and eax,7fffh
306 mov ax,word ptr[esi+eax*2]
307 cmp ecx,eax
308 jnb exitloop
309
310 sub chain_length,16
311 ja do16
312 jmp normalbeg0add16
313
314 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
315
316 normbeg MACRO rcontlab,valsub
317 ; if we are here, we know that *(match+best_len-1) == scan_end
318 cmp bp,word ptr[edx+eax]
319 ; if (match != scan_start) goto rcontlab
320 jne rcontlab
321 ; calculate the good chain_length, and we'll compare scan and match string
322 add chain_length,16-valsub
323 jmp iseq
324 ENDM
325
326
327 normalbeg2dc11:
328 normbeg rcontloop11,11
329
330 normalbeg2dc12:
331 normbeg short rcontloop12,12
332
333 normalbeg2dc13:
334 normbeg short rcontloop13,13
335
336 normalbeg2dc14:
337 normbeg short rcontloop14,14
338
339 normalbeg2dc15:
340 normbeg short rcontloop15,15
341
342 normalbeg2dc10:
343 normbeg rcontloop10,10
344
345 normalbeg2dc9:
346 normbeg rcontloop9,9
347
348 normalbeg2dc8:
349 normbeg rcontloop8,8
350
351 normalbeg2dc7:
352 normbeg rcontloop7,7
353
354 normalbeg2dc6:
355 normbeg rcontloop6,6
356
357 normalbeg2dc5:
358 normbeg rcontloop5,5
359
360 normalbeg2dc4:
361 normbeg rcontloop4,4
362
363 normalbeg2dc3:
364 normbeg rcontloop3,3
365
366 normalbeg2dc2:
367 normbeg rcontloop2,2
368
369 normalbeg2dc1:
370 normbeg rcontloop1,1
371
372 normalbeg2dc0:
373 normbeg rcontloop0,0
374
375
376 ; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
377
378 normalbeg2:
379 mov edi,window
380
381 cmp bp,word ptr[edi+eax]
382 jne contloop3 ; if *(ushf*)match != scan_start, continue
383
384 iseq:
385 ; if we are here, we know that *(match+best_len-1) == scan_end
386 ; and (match == scan_start)
387
388 mov edi,edx
389 mov esi,scan ; esi = scan
390 add edi,eax ; edi = window + cur_match = match
391
392 mov edx,[esi+3] ; compare manually dword at match+3
393 xor edx,[edi+3] ; and scan +3
394
395 jz begincompare ; if equal, go to long compare
396
397 ; we will determine the unmatch byte and calculate len (in esi)
398 or dl,dl
399 je eq1rr
400 mov esi,3
401 jmp trfinval
402 eq1rr:
403 or dx,dx
404 je eq1
405
406 mov esi,4
407 jmp trfinval
408 eq1:
409 and edx,0ffffffh
410 jz eq11
411 mov esi,5
412 jmp trfinval
413 eq11:
414 mov esi,6
415 jmp trfinval
416
417 begincompare:
418 ; here we now scan and match begin same
419 add edi,6
420 add esi,6
421 mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
422 repe cmpsd ; loop until mismatch
423
424 je trfin ; go to trfin if not unmatch
425 ; we determine the unmatch byte
426 sub esi,4
427 mov edx,[edi-4]
428 xor edx,[esi]
429
430 or dl,dl
431 jnz trfin
432 inc esi
433
434 or dx,dx
435 jnz trfin
436 inc esi
437
438 and edx,0ffffffh
439 jnz trfin
440 inc esi
441
442 trfin:
443 sub esi,scan ; esi = len
444 trfinval:
445 ; here we have finised compare, and esi contain len of equal string
446 cmp esi,best_len ; if len > best_len, go newbestlen
447 ja short newbestlen
448 ; now we restore edx, ecx and esi, for the big loop
449 mov esi,prev
450 mov ecx,limit
451 mov edx,window
452 jmp contloop3
453
454 newbestlen:
455 mov best_len,esi ; len become best_len
456
457 mov match_start,eax ; save new position as match_start
458 cmp esi,nice_match ; if best_len >= nice_match, exit
459 jae exitloop
460 mov ecx,scan
461 mov edx,window ; restore edx=window
462 add ecx,esi
463 add esi,edx
464
465 dec esi
466 mov windowlen,esi ; windowlen = window + best_len-1
467 mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
468
469 ; now we restore ecx and esi, for the big loop :
470 mov esi,prev
471 mov ecx,limit
472 jmp contloop3
473
474 exitloop:
475 ; exit : s->match_start=match_start
476 mov ebx,match_start
477 mov ebp,str_s
478 mov ecx,best_len
479 mov dword ptr [ebp+dep_match_start],ebx
480 mov eax,dword ptr [ebp+dep_lookahead]
481 cmp ecx,eax
482 ja minexlo
483 mov eax,ecx
484 minexlo:
485 ; return min(best_len,s->lookahead)
486
487 ; restore stack and register ebx,esi,edi,ebp
488 add esp,NbStackAdd
489
490 pop ebx
491 pop esi
492 pop edi
493 pop ebp
494 ret
495 InfoAuthor:
496 ; please don't remove this string !
497 ; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
498 db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
499
500
501
502 IFDEF NOUNDERLINE
503 longest_match_7fff endp
504 ELSE
505 _longest_match_7fff endp
506 ENDIF
507
508
509 IFDEF NOUNDERLINE
510 cpudetect32 proc near
511 ELSE
512 _cpudetect32 proc near
513 ENDIF
514
515 push ebx
516
517 pushfd ; push original EFLAGS
518 pop eax ; get original EFLAGS
519 mov ecx, eax ; save original EFLAGS
520 xor eax, 40000h ; flip AC bit in EFLAGS
521 push eax ; save new EFLAGS value on stack
522 popfd ; replace current EFLAGS value
523 pushfd ; get new EFLAGS
524 pop eax ; store new EFLAGS in EAX
525 xor eax, ecx ; can’t toggle AC bit, processor=80386
526 jz end_cpu_is_386 ; jump if 80386 processor
527 push ecx
528 popfd ; restore AC bit in EFLAGS first
529
530 pushfd
531 pushfd
532 pop ecx
533
534 mov eax, ecx ; get original EFLAGS
535 xor eax, 200000h ; flip ID bit in EFLAGS
536 push eax ; save new EFLAGS value on stack
537 popfd ; replace current EFLAGS value
538 pushfd ; get new EFLAGS
539 pop eax ; store new EFLAGS in EAX
540 popfd ; restore original EFLAGS
541 xor eax, ecx ; can’t toggle ID bit,
542 je is_old_486 ; processor=old
543
544 mov eax,1
545 db 0fh,0a2h ;CPUID
546
547 exitcpudetect:
548 pop ebx
549 ret
550
551 end_cpu_is_386:
552 mov eax,0300h
553 jmp exitcpudetect
554
555 is_old_486:
556 mov eax,0400h
557 jmp exitcpudetect
558
559 IFDEF NOUNDERLINE
560 cpudetect32 endp
561 ELSE
562 _cpudetect32 endp
563 ENDIF
564
565
566
567
568 MAX_MATCH equ 258
569 MIN_MATCH equ 3
570 MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
571 MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
572
573
574 ;;; stack frame offsets
575
576 chainlenwmask equ esp + 0 ; high word: current chain len
577 ; low word: s->wmask
578 window equ esp + 4 ; local copy of s->window
579 windowbestlen equ esp + 8 ; s->window + bestlen
580 scanstart equ esp + 16 ; first two bytes of string
581 scanend equ esp + 12 ; last two bytes of string
582 scanalign equ esp + 20 ; dword-misalignment of string
583 nicematch equ esp + 24 ; a good enough match size
584 bestlen equ esp + 28 ; size of best match so far
585 scan equ esp + 32 ; ptr to string wanting match
586
587 LocalVarsSize equ 36
588 ; saved ebx byte esp + 36
589 ; saved edi byte esp + 40
590 ; saved esi byte esp + 44
591 ; saved ebp byte esp + 48
592 ; return address byte esp + 52
593 deflatestate equ esp + 56 ; the function arguments
594 curmatch equ esp + 60
595
596 ;;; Offsets for fields in the deflate_state structure. These numbers
597 ;;; are calculated from the definition of deflate_state, with the
598 ;;; assumption that the compiler will dword-align the fields. (Thus,
599 ;;; changing the definition of deflate_state could easily cause this
600 ;;; program to crash horribly, without so much as a warning at
601 ;;; compile time. Sigh.)
602
603 dsWSize equ 36+addstr-4
604 dsWMask equ 44+addstr-4
605 dsWindow equ 48+addstr-4
606 dsPrev equ 56+addstr-4
607 dsMatchLen equ 88+addstr-4
608 dsPrevMatch equ 92+addstr-4
609 dsStrStart equ 100+addstr-4
610 dsMatchStart equ 104+addstr-4
611 dsLookahead equ 108+addstr-4
612 dsPrevLen equ 112+addstr-4
613 dsMaxChainLen equ 116+addstr-4
614 dsGoodMatch equ 132+addstr-4
615 dsNiceMatch equ 136+addstr-4
616
617
618 ;;; match.asm -- Pentium-Pro-optimized version of longest_match()
619 ;;; Written for zlib 1.1.2
620 ;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
621 ;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
622 ;;;
623 ;;; This is free software; you can redistribute it and/or modify it
624 ;;; under the terms of the GNU General Public License.
625
626 ;GLOBAL _longest_match, _match_init
627
628
629 ;SECTION .text
630
631 ;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
632
633 ;_longest_match:
634 IFDEF NOUNDERLINE
635 longest_match_686 proc near
636 ELSE
637 _longest_match_686 proc near
638 ENDIF
639
640
641 ;;; Save registers that the compiler may be using, and adjust esp to
642 ;;; make room for our stack frame.
643
644 push ebp
645 push edi
646 push esi
647 push ebx
648 sub esp, LocalVarsSize
649
650 ;;; Retrieve the function arguments. ecx will hold cur_match
651 ;;; throughout the entire function. edx will hold the pointer to the
652 ;;; deflate_state structure during the function's setup (before
653 ;;; entering the main loop.
654
655 mov edx, [deflatestate]
656 mov ecx, [curmatch]
657
658 ;;; uInt wmask = s->w_mask;
659 ;;; unsigned chain_length = s->max_chain_length;
660 ;;; if (s->prev_length >= s->good_match) {
661 ;;; chain_length >>= 2;
662 ;;; }
663
664 mov eax, [edx + dsPrevLen]
665 mov ebx, [edx + dsGoodMatch]
666 cmp eax, ebx
667 mov eax, [edx + dsWMask]
668 mov ebx, [edx + dsMaxChainLen]
669 jl LastMatchGood
670 shr ebx, 2
671 LastMatchGood:
672
673 ;;; chainlen is decremented once beforehand so that the function can
674 ;;; use the sign flag instead of the zero flag for the exit test.
675 ;;; It is then shifted into the high word, to make room for the wmask
676 ;;; value, which it will always accompany.
677
678 dec ebx
679 shl ebx, 16
680 or ebx, eax
681 mov [chainlenwmask], ebx
682
683 ;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
684
685 mov eax, [edx + dsNiceMatch]
686 mov ebx, [edx + dsLookahead]
687 cmp ebx, eax
688 jl LookaheadLess
689 mov ebx, eax
690 LookaheadLess: mov [nicematch], ebx
691
692 ;;; register Bytef *scan = s->window + s->strstart;
693
694 mov esi, [edx + dsWindow]
695 mov [window], esi
696 mov ebp, [edx + dsStrStart]
697 lea edi, [esi + ebp]
698 mov [scan], edi
699
700 ;;; Determine how many bytes the scan ptr is off from being
701 ;;; dword-aligned.
702
703 mov eax, edi
704 neg eax
705 and eax, 3
706 mov [scanalign], eax
707
708 ;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
709 ;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
710
711 mov eax, [edx + dsWSize]
712 sub eax, MIN_LOOKAHEAD
713 sub ebp, eax
714 jg LimitPositive
715 xor ebp, ebp
716 LimitPositive:
717
718 ;;; int best_len = s->prev_length;
719
720 mov eax, [edx + dsPrevLen]
721 mov [bestlen], eax
722
723 ;;; Store the sum of s->window + best_len in esi locally, and in esi.
724
725 add esi, eax
726 mov [windowbestlen], esi
727
728 ;;; register ush scan_start = *(ushf*)scan;
729 ;;; register ush scan_end = *(ushf*)(scan+best_len-1);
730 ;;; Posf *prev = s->prev;
731
732 movzx ebx, word ptr [edi]
733 mov [scanstart], ebx
734 movzx ebx, word ptr [edi + eax - 1]
735 mov [scanend], ebx
736 mov edi, [edx + dsPrev]
737
738 ;;; Jump into the main loop.
739
740 mov edx, [chainlenwmask]
741 jmp short LoopEntry
742
743 align 4
744
745 ;;; do {
746 ;;; match = s->window + cur_match;
747 ;;; if (*(ushf*)(match+best_len-1) != scan_end ||
748 ;;; *(ushf*)match != scan_start) continue;
749 ;;; [...]
750 ;;; } while ((cur_match = prev[cur_match & wmask]) > limit
751 ;;; && --chain_length != 0);
752 ;;;
753 ;;; Here is the inner loop of the function. The function will spend the
754 ;;; majority of its time in this loop, and majority of that time will
755 ;;; be spent in the first ten instructions.
756 ;;;
757 ;;; Within this loop:
758 ;;; ebx = scanend
759 ;;; ecx = curmatch
760 ;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
761 ;;; esi = windowbestlen - i.e., (window + bestlen)
762 ;;; edi = prev
763 ;;; ebp = limit
764
765 LookupLoop:
766 and ecx, edx
767 movzx ecx, word ptr [edi + ecx*2]
768 cmp ecx, ebp
769 jbe LeaveNow
770 sub edx, 00010000h
771 js LeaveNow
772 LoopEntry: movzx eax, word ptr [esi + ecx - 1]
773 cmp eax, ebx
774 jnz LookupLoop
775 mov eax, [window]
776 movzx eax, word ptr [eax + ecx]
777 cmp eax, [scanstart]
778 jnz LookupLoop
779
780 ;;; Store the current value of chainlen.
781
782 mov [chainlenwmask], edx
783
784 ;;; Point edi to the string under scrutiny, and esi to the string we
785 ;;; are hoping to match it up with. In actuality, esi and edi are
786 ;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
787 ;;; initialized to -(MAX_MATCH_8 - scanalign).
788
789 mov esi, [window]
790 mov edi, [scan]
791 add esi, ecx
792 mov eax, [scanalign]
793 mov edx, 0fffffef8h; -(MAX_MATCH_8)
794 lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
795 lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
796
797 ;;; Test the strings for equality, 8 bytes at a time. At the end,
798 ;;; adjust edx so that it is offset to the exact byte that mismatched.
799 ;;;
800 ;;; We already know at this point that the first three bytes of the
801 ;;; strings match each other, and they can be safely passed over before
802 ;;; starting the compare loop. So what this code does is skip over 0-3
803 ;;; bytes, as much as necessary in order to dword-align the edi
804 ;;; pointer. (esi will still be misaligned three times out of four.)
805 ;;;
806 ;;; It should be confessed that this loop usually does not represent
807 ;;; much of the total running time. Replacing it with a more
808 ;;; straightforward "rep cmpsb" would not drastically degrade
809 ;;; performance.
810
811 LoopCmps:
812 mov eax, [esi + edx]
813 xor eax, [edi + edx]
814 jnz LeaveLoopCmps
815 mov eax, [esi + edx + 4]
816 xor eax, [edi + edx + 4]
817 jnz LeaveLoopCmps4
818 add edx, 8
819 jnz LoopCmps
820 jmp short LenMaximum
821 LeaveLoopCmps4: add edx, 4
822 LeaveLoopCmps: test eax, 0000FFFFh
823 jnz LenLower
824 add edx, 2
825 shr eax, 16
826 LenLower: sub al, 1
827 adc edx, 0
828
829 ;;; Calculate the length of the match. If it is longer than MAX_MATCH,
830 ;;; then automatically accept it as the best possible match and leave.
831
832 lea eax, [edi + edx]
833 mov edi, [scan]
834 sub eax, edi
835 cmp eax, MAX_MATCH
836 jge LenMaximum
837
838 ;;; If the length of the match is not longer than the best match we
839 ;;; have so far, then forget it and return to the lookup loop.
840
841 mov edx, [deflatestate]
842 mov ebx, [bestlen]
843 cmp eax, ebx
844 jg LongerMatch
845 mov esi, [windowbestlen]
846 mov edi, [edx + dsPrev]
847 mov ebx, [scanend]
848 mov edx, [chainlenwmask]
849 jmp LookupLoop
850
851 ;;; s->match_start = cur_match;
852 ;;; best_len = len;
853 ;;; if (len >= nice_match) break;
854 ;;; scan_end = *(ushf*)(scan+best_len-1);
855
856 LongerMatch: mov ebx, [nicematch]
857 mov [bestlen], eax
858 mov [edx + dsMatchStart], ecx
859 cmp eax, ebx
860 jge LeaveNow
861 mov esi, [window]
862 add esi, eax
863 mov [windowbestlen], esi
864 movzx ebx, word ptr [edi + eax - 1]
865 mov edi, [edx + dsPrev]
866 mov [scanend], ebx
867 mov edx, [chainlenwmask]
868 jmp LookupLoop
869
870 ;;; Accept the current string, with the maximum possible length.
871
872 LenMaximum: mov edx, [deflatestate]
873 mov dword ptr [bestlen], MAX_MATCH
874 mov [edx + dsMatchStart], ecx
875
876 ;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
877 ;;; return s->lookahead;
878
879 LeaveNow:
880 mov edx, [deflatestate]
881 mov ebx, [bestlen]
882 mov eax, [edx + dsLookahead]
883 cmp ebx, eax
884 jg LookaheadRet
885 mov eax, ebx
886 LookaheadRet:
887
888 ;;; Restore the stack and return from whence we came.
889
890 add esp, LocalVarsSize
891 pop ebx
892 pop esi
893 pop edi
894 pop ebp
895
896 ret
897 ; please don't remove this string !
898 ; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
899 db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
900
901 IFDEF NOUNDERLINE
902 longest_match_686 endp
903 ELSE
904 _longest_match_686 endp
905 ENDIF
906
907 _TEXT ends
908 end
0 /* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
1 * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
2 * File written by Gilles Vollant, by modifiying the longest_match
3 * from Jean-loup Gailly in deflate.c
4 * it prepare all parameters and call the assembly longest_match_gvasm
5 * longest_match execute standard C code is wmask != 0x7fff
6 * (assembly code is faster with a fixed wmask)
7 *
8 */
9
10 #include "deflate.h"
11
12 #ifdef ASMV
13 #define NIL 0
14
15 #define UNALIGNED_OK
16
17
18 /* if your C compiler don't add underline before function name,
19 define ADD_UNDERLINE_ASMFUNC */
20 #ifdef ADD_UNDERLINE_ASMFUNC
21 #define longest_match_7fff _longest_match_7fff
22 #define longest_match_686 _longest_match_686
23 #define cpudetect32 _cpudetect32
24 #endif
25
26
27
28 void match_init()
29 {
30 }
31
32 unsigned long cpudetect32();
33
34 uInt longest_match_c(
35 deflate_state *s,
36 IPos cur_match); /* current match */
37
38
39 uInt longest_match_7fff(
40 deflate_state *s,
41 IPos cur_match); /* current match */
42
43 uInt longest_match_686(
44 deflate_state *s,
45 IPos cur_match); /* current match */
46
47 uInt longest_match(
48 deflate_state *s,
49 IPos cur_match) /* current match */
50 {
51 static uInt iIsPPro=2;
52
53 if ((s->w_mask == 0x7fff) && (iIsPPro==0))
54 return longest_match_7fff(s,cur_match);
55
56 if (iIsPPro==1)
57 return longest_match_686(s,cur_match);
58
59 if (iIsPPro==2)
60 iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
61
62 return longest_match_c(s,cur_match);
63 }
64
65
66
67 uInt longest_match_c(s, cur_match)
68 deflate_state *s;
69 IPos cur_match; /* current match */
70 {
71 unsigned chain_length = s->max_chain_length;/* max hash chain length */
72 register Bytef *scan = s->window + s->strstart; /* current string */
73 register Bytef *match; /* matched string */
74 register int len; /* length of current match */
75 int best_len = s->prev_length; /* best match length so far */
76 int nice_match = s->nice_match; /* stop if match long enough */
77 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
78 s->strstart - (IPos)MAX_DIST(s) : NIL;
79 /* Stop when cur_match becomes <= limit. To simplify the code,
80 * we prevent matches with the string of window index 0.
81 */
82 Posf *prev = s->prev;
83 uInt wmask = s->w_mask;
84
85 #ifdef UNALIGNED_OK
86 /* Compare two bytes at a time. Note: this is not always beneficial.
87 * Try with and without -DUNALIGNED_OK to check.
88 */
89 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
90 register ush scan_start = *(ushf*)scan;
91 register ush scan_end = *(ushf*)(scan+best_len-1);
92 #else
93 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
94 register Byte scan_end1 = scan[best_len-1];
95 register Byte scan_end = scan[best_len];
96 #endif
97
98 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
99 * It is easy to get rid of this optimization if necessary.
100 */
101 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
102
103 /* Do not waste too much time if we already have a good match: */
104 if (s->prev_length >= s->good_match) {
105 chain_length >>= 2;
106 }
107 /* Do not look for matches beyond the end of the input. This is necessary
108 * to make deflate deterministic.
109 */
110 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
111
112 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
113
114 do {
115 Assert(cur_match < s->strstart, "no future");
116 match = s->window + cur_match;
117
118 /* Skip to next match if the match length cannot increase
119 * or if the match length is less than 2:
120 */
121 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
122 /* This code assumes sizeof(unsigned short) == 2. Do not use
123 * UNALIGNED_OK if your compiler uses a different size.
124 */
125 if (*(ushf*)(match+best_len-1) != scan_end ||
126 *(ushf*)match != scan_start) continue;
127
128 /* It is not necessary to compare scan[2] and match[2] since they are
129 * always equal when the other bytes match, given that the hash keys
130 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
131 * strstart+3, +5, ... up to strstart+257. We check for insufficient
132 * lookahead only every 4th comparison; the 128th check will be made
133 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
134 * necessary to put more guard bytes at the end of the window, or
135 * to check more often for insufficient lookahead.
136 */
137 Assert(scan[2] == match[2], "scan[2]?");
138 scan++, match++;
139 do {
140 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
141 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
142 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
143 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
144 scan < strend);
145 /* The funny "do {}" generates better code on most compilers */
146
147 /* Here, scan <= window+strstart+257 */
148 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
149 if (*scan == *match) scan++;
150
151 len = (MAX_MATCH - 1) - (int)(strend-scan);
152 scan = strend - (MAX_MATCH-1);
153
154 #else /* UNALIGNED_OK */
155
156 if (match[best_len] != scan_end ||
157 match[best_len-1] != scan_end1 ||
158 *match != *scan ||
159 *++match != scan[1]) continue;
160
161 /* The check at best_len-1 can be removed because it will be made
162 * again later. (This heuristic is not always a win.)
163 * It is not necessary to compare scan[2] and match[2] since they
164 * are always equal when the other bytes match, given that
165 * the hash keys are equal and that HASH_BITS >= 8.
166 */
167 scan += 2, match++;
168 Assert(*scan == *match, "match[2]?");
169
170 /* We check for insufficient lookahead only every 8th comparison;
171 * the 256th check will be made at strstart+258.
172 */
173 do {
174 } while (*++scan == *++match && *++scan == *++match &&
175 *++scan == *++match && *++scan == *++match &&
176 *++scan == *++match && *++scan == *++match &&
177 *++scan == *++match && *++scan == *++match &&
178 scan < strend);
179
180 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
181
182 len = MAX_MATCH - (int)(strend - scan);
183 scan = strend - MAX_MATCH;
184
185 #endif /* UNALIGNED_OK */
186
187 if (len > best_len) {
188 s->match_start = cur_match;
189 best_len = len;
190 if (len >= nice_match) break;
191 #ifdef UNALIGNED_OK
192 scan_end = *(ushf*)(scan+best_len-1);
193 #else
194 scan_end1 = scan[best_len-1];
195 scan_end = scan[best_len];
196 #endif
197 }
198 } while ((cur_match = prev[cur_match & wmask]) > limit
199 && --chain_length != 0);
200
201 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
202 return s->lookahead;
203 }
204
205 #endif /* ASMV */
0 ; 75 "inffast.S"
1 ;FILE "inffast.S"
2
3 ;;;GLOBAL _inflate_fast
4
5 ;;;SECTION .text
6
7
8
9 .586p
10 .mmx
11
12 name inflate_fast_x86
13 .MODEL FLAT
14
15 _DATA segment
16 inflate_fast_use_mmx:
17 dd 1
18
19
20 _TEXT segment
21 PUBLIC _inflate_fast
22
23 ALIGN 4
24 _inflate_fast:
25 jmp inflate_fast_entry
26
27
28
29 ALIGN 4
30 db 'Fast decoding Code from Chris Anderson'
31 db 0
32
33 ALIGN 4
34 invalid_literal_length_code_msg:
35 db 'invalid literal/length code'
36 db 0
37
38 ALIGN 4
39 invalid_distance_code_msg:
40 db 'invalid distance code'
41 db 0
42
43 ALIGN 4
44 invalid_distance_too_far_msg:
45 db 'invalid distance too far back'
46 db 0
47
48
49 ALIGN 4
50 inflate_fast_mask:
51 dd 0
52 dd 1
53 dd 3
54 dd 7
55 dd 15
56 dd 31
57 dd 63
58 dd 127
59 dd 255
60 dd 511
61 dd 1023
62 dd 2047
63 dd 4095
64 dd 8191
65 dd 16383
66 dd 32767
67 dd 65535
68 dd 131071
69 dd 262143
70 dd 524287
71 dd 1048575
72 dd 2097151
73 dd 4194303
74 dd 8388607
75 dd 16777215
76 dd 33554431
77 dd 67108863
78 dd 134217727
79 dd 268435455
80 dd 536870911
81 dd 1073741823
82 dd 2147483647
83 dd 4294967295
84
85
86 ; head was added in zlib 1.2.2.1, so we add addstr
87 ; set addstr to 0 with zlib 1.2.1 of below
88 addstr equ 4
89
90 mode_state equ 0 ;/* state->mode */
91 wsize_state equ 32+addstr ;/* state->wsize */
92 write_state equ (36+4+addstr) ;/* state->write */
93 window_state equ (40+4+addstr) ;/* state->window */
94 hold_state equ (44+4+addstr) ;/* state->hold */
95 bits_state equ (48+4+addstr) ;/* state->bits */
96 lencode_state equ (64+4+addstr) ;/* state->lencode */
97 distcode_state equ (68+4+addstr) ;/* state->distcode */
98 lenbits_state equ (72+4+addstr) ;/* state->lenbits */
99 distbits_state equ (76+4+addstr) ;/* state->distbits */
100
101
102 ;;SECTION .text
103 ; 205 "inffast.S"
104 ;GLOBAL inflate_fast_use_mmx
105
106 ;SECTION .data
107
108
109 ; GLOBAL inflate_fast_use_mmx:object
110 ;.size inflate_fast_use_mmx, 4
111 ; 226 "inffast.S"
112 ;SECTION .text
113
114 ALIGN 4
115 inflate_fast_entry:
116 push edi
117 push esi
118 push ebp
119 push ebx
120 pushfd
121 sub esp,64
122 cld
123
124
125
126
127 mov esi, [esp+88]
128 mov edi, [esi+28]
129
130
131
132
133
134
135
136 mov edx, [esi+4]
137 mov eax, [esi+0]
138
139 add edx,eax
140 sub edx,11
141
142 mov [esp+44],eax
143 mov [esp+20],edx
144
145 mov ebp, [esp+92]
146 mov ecx, [esi+16]
147 mov ebx, [esi+12]
148
149 sub ebp,ecx
150 neg ebp
151 add ebp,ebx
152
153 sub ecx,257
154 add ecx,ebx
155
156 mov [esp+60],ebx
157 mov [esp+40],ebp
158 mov [esp+16],ecx
159 ; 285 "inffast.S"
160 mov eax, [edi+lencode_state]
161 mov ecx, [edi+distcode_state]
162
163 mov [esp+8],eax
164 mov [esp+12],ecx
165
166 mov eax,1
167 mov ecx, [edi+lenbits_state]
168 shl eax,cl
169 dec eax
170 mov [esp+0],eax
171
172 mov eax,1
173 mov ecx, [edi+distbits_state]
174 shl eax,cl
175 dec eax
176 mov [esp+4],eax
177
178 mov eax, [edi+wsize_state]
179 mov ecx, [edi+write_state]
180 mov edx, [edi+window_state]
181
182 mov [esp+52],eax
183 mov [esp+48],ecx
184 mov [esp+56],edx
185
186 mov ebp, [edi+hold_state]
187 mov ebx, [edi+bits_state]
188 ; 321 "inffast.S"
189 mov esi, [esp+44]
190 mov ecx, [esp+20]
191 cmp ecx,esi
192 ja L_align_long
193
194 add ecx,11
195 sub ecx,esi
196 mov eax,12
197 sub eax,ecx
198 lea edi, [esp+28]
199 rep movsb
200 mov ecx,eax
201 xor eax,eax
202 rep stosb
203 lea esi, [esp+28]
204 mov [esp+20],esi
205 jmp L_is_aligned
206
207
208 L_align_long:
209 test esi,3
210 jz L_is_aligned
211 xor eax,eax
212 mov al, [esi]
213 inc esi
214 mov ecx,ebx
215 add ebx,8
216 shl eax,cl
217 or ebp,eax
218 jmp L_align_long
219
220 L_is_aligned:
221 mov edi, [esp+60]
222 ; 366 "inffast.S"
223 L_check_mmx:
224 cmp dword ptr [inflate_fast_use_mmx],2
225 je L_init_mmx
226 ja L_do_loop
227
228 push eax
229 push ebx
230 push ecx
231 push edx
232 pushfd
233 mov eax, [esp]
234 xor dword ptr [esp],0200000h
235
236
237
238
239 popfd
240 pushfd
241 pop edx
242 xor edx,eax
243 jz L_dont_use_mmx
244 xor eax,eax
245 cpuid
246 cmp ebx,0756e6547h
247 jne L_dont_use_mmx
248 cmp ecx,06c65746eh
249 jne L_dont_use_mmx
250 cmp edx,049656e69h
251 jne L_dont_use_mmx
252 mov eax,1
253 cpuid
254 shr eax,8
255 and eax,15
256 cmp eax,6
257 jne L_dont_use_mmx
258 test edx,0800000h
259 jnz L_use_mmx
260 jmp L_dont_use_mmx
261 L_use_mmx:
262 mov dword ptr [inflate_fast_use_mmx],2
263 jmp L_check_mmx_pop
264 L_dont_use_mmx:
265 mov dword ptr [inflate_fast_use_mmx],3
266 L_check_mmx_pop:
267 pop edx
268 pop ecx
269 pop ebx
270 pop eax
271 jmp L_check_mmx
272 ; 426 "inffast.S"
273 ALIGN 4
274 L_do_loop:
275 ; 437 "inffast.S"
276 cmp bl,15
277 ja L_get_length_code
278
279 xor eax,eax
280 lodsw
281 mov cl,bl
282 add bl,16
283 shl eax,cl
284 or ebp,eax
285
286 L_get_length_code:
287 mov edx, [esp+0]
288 mov ecx, [esp+8]
289 and edx,ebp
290 mov eax, [ecx+edx*4]
291
292 L_dolen:
293
294
295
296
297
298
299 mov cl,ah
300 sub bl,ah
301 shr ebp,cl
302
303
304
305
306
307
308 test al,al
309 jnz L_test_for_length_base
310
311 shr eax,16
312 stosb
313
314 L_while_test:
315
316
317 cmp [esp+16],edi
318 jbe L_break_loop
319
320 cmp [esp+20],esi
321 ja L_do_loop
322 jmp L_break_loop
323
324 L_test_for_length_base:
325 ; 502 "inffast.S"
326 mov edx,eax
327 shr edx,16
328 mov cl,al
329
330 test al,16
331 jz L_test_for_second_level_length
332 and cl,15
333 jz L_save_len
334 cmp bl,cl
335 jae L_add_bits_to_len
336
337 mov ch,cl
338 xor eax,eax
339 lodsw
340 mov cl,bl
341 add bl,16
342 shl eax,cl
343 or ebp,eax
344 mov cl,ch
345
346 L_add_bits_to_len:
347 mov eax,1
348 shl eax,cl
349 dec eax
350 sub bl,cl
351 and eax,ebp
352 shr ebp,cl
353 add edx,eax
354
355 L_save_len:
356 mov [esp+24],edx
357
358
359 L_decode_distance:
360 ; 549 "inffast.S"
361 cmp bl,15
362 ja L_get_distance_code
363
364 xor eax,eax
365 lodsw
366 mov cl,bl
367 add bl,16
368 shl eax,cl
369 or ebp,eax
370
371 L_get_distance_code:
372 mov edx, [esp+4]
373 mov ecx, [esp+12]
374 and edx,ebp
375 mov eax, [ecx+edx*4]
376
377
378 L_dodist:
379 mov edx,eax
380 shr edx,16
381 mov cl,ah
382 sub bl,ah
383 shr ebp,cl
384 ; 584 "inffast.S"
385 mov cl,al
386
387 test al,16
388 jz L_test_for_second_level_dist
389 and cl,15
390 jz L_check_dist_one
391 cmp bl,cl
392 jae L_add_bits_to_dist
393
394 mov ch,cl
395 xor eax,eax
396 lodsw
397 mov cl,bl
398 add bl,16
399 shl eax,cl
400 or ebp,eax
401 mov cl,ch
402
403 L_add_bits_to_dist:
404 mov eax,1
405 shl eax,cl
406 dec eax
407 sub bl,cl
408 and eax,ebp
409 shr ebp,cl
410 add edx,eax
411 jmp L_check_window
412
413 L_check_window:
414 ; 625 "inffast.S"
415 mov [esp+44],esi
416 mov eax,edi
417 sub eax, [esp+40]
418
419 cmp eax,edx
420 jb L_clip_window
421
422 mov ecx, [esp+24]
423 mov esi,edi
424 sub esi,edx
425
426 sub ecx,3
427 mov al, [esi]
428 mov [edi],al
429 mov al, [esi+1]
430 mov dl, [esi+2]
431 add esi,3
432 mov [edi+1],al
433 mov [edi+2],dl
434 add edi,3
435 rep movsb
436
437 mov esi, [esp+44]
438 jmp L_while_test
439
440 ALIGN 4
441 L_check_dist_one:
442 cmp edx,1
443 jne L_check_window
444 cmp [esp+40],edi
445 je L_check_window
446
447 dec edi
448 mov ecx, [esp+24]
449 mov al, [edi]
450 sub ecx,3
451
452 mov [edi+1],al
453 mov [edi+2],al
454 mov [edi+3],al
455 add edi,4
456 rep stosb
457
458 jmp L_while_test
459
460 ALIGN 4
461 L_test_for_second_level_length:
462
463
464
465
466 test al,64
467 jnz L_test_for_end_of_block
468
469 mov eax,1
470 shl eax,cl
471 dec eax
472 and eax,ebp
473 add eax,edx
474 mov edx, [esp+8]
475 mov eax, [edx+eax*4]
476 jmp L_dolen
477
478 ALIGN 4
479 L_test_for_second_level_dist:
480
481
482
483
484 test al,64
485 jnz L_invalid_distance_code
486
487 mov eax,1
488 shl eax,cl
489 dec eax
490 and eax,ebp
491 add eax,edx
492 mov edx, [esp+12]
493 mov eax, [edx+eax*4]
494 jmp L_dodist
495
496 ALIGN 4
497 L_clip_window:
498 ; 721 "inffast.S"
499 mov ecx,eax
500 mov eax, [esp+52]
501 neg ecx
502 mov esi, [esp+56]
503
504 cmp eax,edx
505 jb L_invalid_distance_too_far
506
507 add ecx,edx
508 cmp dword ptr [esp+48],0
509 jne L_wrap_around_window
510
511 sub eax,ecx
512 add esi,eax
513 ; 749 "inffast.S"
514 mov eax, [esp+24]
515 cmp eax,ecx
516 jbe L_do_copy1
517
518 sub eax,ecx
519 rep movsb
520 mov esi,edi
521 sub esi,edx
522 jmp L_do_copy1
523
524 cmp eax,ecx
525 jbe L_do_copy1
526
527 sub eax,ecx
528 rep movsb
529 mov esi,edi
530 sub esi,edx
531 jmp L_do_copy1
532
533 L_wrap_around_window:
534 ; 793 "inffast.S"
535 mov eax, [esp+48]
536 cmp ecx,eax
537 jbe L_contiguous_in_window
538
539 add esi, [esp+52]
540 add esi,eax
541 sub esi,ecx
542 sub ecx,eax
543
544
545 mov eax, [esp+24]
546 cmp eax,ecx
547 jbe L_do_copy1
548
549 sub eax,ecx
550 rep movsb
551 mov esi, [esp+56]
552 mov ecx, [esp+48]
553 cmp eax,ecx
554 jbe L_do_copy1
555
556 sub eax,ecx
557 rep movsb
558 mov esi,edi
559 sub esi,edx
560 jmp L_do_copy1
561
562 L_contiguous_in_window:
563 ; 836 "inffast.S"
564 add esi,eax
565 sub esi,ecx
566
567
568 mov eax, [esp+24]
569 cmp eax,ecx
570 jbe L_do_copy1
571
572 sub eax,ecx
573 rep movsb
574 mov esi,edi
575 sub esi,edx
576
577 L_do_copy1:
578 ; 862 "inffast.S"
579 mov ecx,eax
580 rep movsb
581
582 mov esi, [esp+44]
583 jmp L_while_test
584 ; 878 "inffast.S"
585 ALIGN 4
586 L_init_mmx:
587 emms
588
589
590
591
592
593 movd mm0,ebp
594 mov ebp,ebx
595 ; 896 "inffast.S"
596 movd mm4,[esp+0]
597 movq mm3,mm4
598 movd mm5,[esp+4]
599 movq mm2,mm5
600 pxor mm1,mm1
601 mov ebx, [esp+8]
602 jmp L_do_loop_mmx
603
604 ALIGN 4
605 L_do_loop_mmx:
606 psrlq mm0,mm1
607
608 cmp ebp,32
609 ja L_get_length_code_mmx
610
611 movd mm6,ebp
612 movd mm7,[esi]
613 add esi,4
614 psllq mm7,mm6
615 add ebp,32
616 por mm0,mm7
617
618 L_get_length_code_mmx:
619 pand mm4,mm0
620 movd eax,mm4
621 movq mm4,mm3
622 mov eax, [ebx+eax*4]
623
624 L_dolen_mmx:
625 movzx ecx,ah
626 movd mm1,ecx
627 sub ebp,ecx
628
629 test al,al
630 jnz L_test_for_length_base_mmx
631
632 shr eax,16
633 stosb
634
635 L_while_test_mmx:
636
637
638 cmp [esp+16],edi
639 jbe L_break_loop
640
641 cmp [esp+20],esi
642 ja L_do_loop_mmx
643 jmp L_break_loop
644
645 L_test_for_length_base_mmx:
646
647 mov edx,eax
648 shr edx,16
649
650 test al,16
651 jz L_test_for_second_level_length_mmx
652 and eax,15
653 jz L_decode_distance_mmx
654
655 psrlq mm0,mm1
656 movd mm1,eax
657 movd ecx,mm0
658 sub ebp,eax
659 and ecx, [inflate_fast_mask+eax*4]
660 add edx,ecx
661
662 L_decode_distance_mmx:
663 psrlq mm0,mm1
664
665 cmp ebp,32
666 ja L_get_dist_code_mmx
667
668 movd mm6,ebp
669 movd mm7,[esi]
670 add esi,4
671 psllq mm7,mm6
672 add ebp,32
673 por mm0,mm7
674
675 L_get_dist_code_mmx:
676 mov ebx, [esp+12]
677 pand mm5,mm0
678 movd eax,mm5
679 movq mm5,mm2
680 mov eax, [ebx+eax*4]
681
682 L_dodist_mmx:
683
684 movzx ecx,ah
685 mov ebx,eax
686 shr ebx,16
687 sub ebp,ecx
688 movd mm1,ecx
689
690 test al,16
691 jz L_test_for_second_level_dist_mmx
692 and eax,15
693 jz L_check_dist_one_mmx
694
695 L_add_bits_to_dist_mmx:
696 psrlq mm0,mm1
697 movd mm1,eax
698 movd ecx,mm0
699 sub ebp,eax
700 and ecx, [inflate_fast_mask+eax*4]
701 add ebx,ecx
702
703 L_check_window_mmx:
704 mov [esp+44],esi
705 mov eax,edi
706 sub eax, [esp+40]
707
708 cmp eax,ebx
709 jb L_clip_window_mmx
710
711 mov ecx,edx
712 mov esi,edi
713 sub esi,ebx
714
715 sub ecx,3
716 mov al, [esi]
717 mov [edi],al
718 mov al, [esi+1]
719 mov dl, [esi+2]
720 add esi,3
721 mov [edi+1],al
722 mov [edi+2],dl
723 add edi,3
724 rep movsb
725
726 mov esi, [esp+44]
727 mov ebx, [esp+8]
728 jmp L_while_test_mmx
729
730 ALIGN 4
731 L_check_dist_one_mmx:
732 cmp ebx,1
733 jne L_check_window_mmx
734 cmp [esp+40],edi
735 je L_check_window_mmx
736
737 dec edi
738 mov ecx,edx
739 mov al, [edi]
740 sub ecx,3
741
742 mov [edi+1],al
743 mov [edi+2],al
744 mov [edi+3],al
745 add edi,4
746 rep stosb
747
748 mov ebx, [esp+8]
749 jmp L_while_test_mmx
750
751 ALIGN 4
752 L_test_for_second_level_length_mmx:
753 test al,64
754 jnz L_test_for_end_of_block
755
756 and eax,15
757 psrlq mm0,mm1
758 movd ecx,mm0
759 and ecx, [inflate_fast_mask+eax*4]
760 add ecx,edx
761 mov eax, [ebx+ecx*4]
762 jmp L_dolen_mmx
763
764 ALIGN 4
765 L_test_for_second_level_dist_mmx:
766 test al,64
767 jnz L_invalid_distance_code
768
769 and eax,15
770 psrlq mm0,mm1
771 movd ecx,mm0
772 and ecx, [inflate_fast_mask+eax*4]
773 mov eax, [esp+12]
774 add ecx,ebx
775 mov eax, [eax+ecx*4]
776 jmp L_dodist_mmx
777
778 ALIGN 4
779 L_clip_window_mmx:
780
781 mov ecx,eax
782 mov eax, [esp+52]
783 neg ecx
784 mov esi, [esp+56]
785
786 cmp eax,ebx
787 jb L_invalid_distance_too_far
788
789 add ecx,ebx
790 cmp dword ptr [esp+48],0
791 jne L_wrap_around_window_mmx
792
793 sub eax,ecx
794 add esi,eax
795
796 cmp edx,ecx
797 jbe L_do_copy1_mmx
798
799 sub edx,ecx
800 rep movsb
801 mov esi,edi
802 sub esi,ebx
803 jmp L_do_copy1_mmx
804
805 cmp edx,ecx
806 jbe L_do_copy1_mmx
807
808 sub edx,ecx
809 rep movsb
810 mov esi,edi
811 sub esi,ebx
812 jmp L_do_copy1_mmx
813
814 L_wrap_around_window_mmx:
815
816 mov eax, [esp+48]
817 cmp ecx,eax
818 jbe L_contiguous_in_window_mmx
819
820 add esi, [esp+52]
821 add esi,eax
822 sub esi,ecx
823 sub ecx,eax
824
825
826 cmp edx,ecx
827 jbe L_do_copy1_mmx
828
829 sub edx,ecx
830 rep movsb
831 mov esi, [esp+56]
832 mov ecx, [esp+48]
833 cmp edx,ecx
834 jbe L_do_copy1_mmx
835
836 sub edx,ecx
837 rep movsb
838 mov esi,edi
839 sub esi,ebx
840 jmp L_do_copy1_mmx
841
842 L_contiguous_in_window_mmx:
843
844 add esi,eax
845 sub esi,ecx
846
847
848 cmp edx,ecx
849 jbe L_do_copy1_mmx
850
851 sub edx,ecx
852 rep movsb
853 mov esi,edi
854 sub esi,ebx
855
856 L_do_copy1_mmx:
857
858
859 mov ecx,edx
860 rep movsb
861
862 mov esi, [esp+44]
863 mov ebx, [esp+8]
864 jmp L_while_test_mmx
865 ; 1174 "inffast.S"
866 L_invalid_distance_code:
867
868
869
870
871
872 mov ecx, invalid_distance_code_msg
873 mov edx,26
874 jmp L_update_stream_state
875
876 L_test_for_end_of_block:
877
878
879
880
881
882 test al,32
883 jz L_invalid_literal_length_code
884
885 mov ecx,0
886 mov edx,11
887 jmp L_update_stream_state
888
889 L_invalid_literal_length_code:
890
891
892
893
894
895 mov ecx, invalid_literal_length_code_msg
896 mov edx,26
897 jmp L_update_stream_state
898
899 L_invalid_distance_too_far:
900
901
902
903 mov esi, [esp+44]
904 mov ecx, invalid_distance_too_far_msg
905 mov edx,26
906 jmp L_update_stream_state
907
908 L_update_stream_state:
909
910 mov eax, [esp+88]
911 test ecx,ecx
912 jz L_skip_msg
913 mov [eax+24],ecx
914 L_skip_msg:
915 mov eax, [eax+28]
916 mov [eax+mode_state],edx
917 jmp L_break_loop
918
919 ALIGN 4
920 L_break_loop:
921 ; 1243 "inffast.S"
922 cmp dword ptr [inflate_fast_use_mmx],2
923 jne L_update_next_in
924
925
926
927 mov ebx,ebp
928
929 L_update_next_in:
930 ; 1266 "inffast.S"
931 mov eax, [esp+88]
932 mov ecx,ebx
933 mov edx, [eax+28]
934 shr ecx,3
935 sub esi,ecx
936 shl ecx,3
937 sub ebx,ecx
938 mov [eax+12],edi
939 mov [edx+bits_state],ebx
940 mov ecx,ebx
941
942 lea ebx, [esp+28]
943 cmp [esp+20],ebx
944 jne L_buf_not_used
945
946 sub esi,ebx
947 mov ebx, [eax+0]
948 mov [esp+20],ebx
949 add esi,ebx
950 mov ebx, [eax+4]
951 sub ebx,11
952 add [esp+20],ebx
953
954 L_buf_not_used:
955 mov [eax+0],esi
956
957 mov ebx,1
958 shl ebx,cl
959 dec ebx
960
961
962
963
964
965 cmp dword ptr [inflate_fast_use_mmx],2
966 jne L_update_hold
967
968
969
970 psrlq mm0,mm1
971 movd ebp,mm0
972
973 emms
974
975 L_update_hold:
976
977
978
979 and ebp,ebx
980 mov [edx+hold_state],ebp
981
982
983
984
985 mov ebx, [esp+20]
986 cmp ebx,esi
987 jbe L_last_is_smaller
988
989 sub ebx,esi
990 add ebx,11
991 mov [eax+4],ebx
992 jmp L_fixup_out
993 L_last_is_smaller:
994 sub esi,ebx
995 neg esi
996 add esi,11
997 mov [eax+4],esi
998
999
1000
1001
1002 L_fixup_out:
1003
1004 mov ebx, [esp+16]
1005 cmp ebx,edi
1006 jbe L_end_is_smaller
1007
1008 sub ebx,edi
1009 add ebx,257
1010 mov [eax+16],ebx
1011 jmp L_done
1012 L_end_is_smaller:
1013 sub edi,ebx
1014 neg edi
1015 add edi,257
1016 mov [eax+16],edi
1017
1018
1019
1020
1021
1022 L_done:
1023 add esp,64
1024 popfd
1025 pop ebx
1026 pop ebp
1027 pop esi
1028 pop edi
1029 ret
1030
1031
1032
1033
1034 _TEXT ends
1035 end
0 cl /DASMV /I..\.. /O2 /c gvmat32c.c
1 ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
2 ml /coff /Zi /c /Flinffas32.lst inffas32.asm
0
1 Summary
2 -------
3 This directory contains ASM implementations of the functions
4 longest_match() and inflate_fast().
5
6
7 Use instructions
8 ----------------
9 Copy these files into the zlib source directory, then run the
10 appropriate makefile, as suggested below.
11
12
13 Build instructions
14 ------------------
15 * With Microsoft C and MASM:
16 nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="gvmat32c.obj gvmat32.obj inffas32.obj"
17
18 * With Borland C and TASM:
19 make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="gvmat32c.obj gvmat32.obj inffas32.obj" OBJPA="+gvmat32c.obj+gvmat32.obj+inffas32.obj"
20
0 Change in 1.01b (20 may 04)
1 - Integrate patch from Debian package (submited by Mark Brown)
2 - Add tools mztools from Xavier Roche
3
4 Change in 1.01 (8 may 04)
5 - fix buffer overrun risk in unzip.c (Xavier Roche)
6 - fix a minor buffer insecurity in minizip.c (Mike Whittaker)
7
8 Change in 1.00: (10 sept 03)
9 - rename to 1.00
10 - cosmetic code change
11
12 Change in 0.22: (19 May 03)
13 - crypting support (unless you define NOCRYPT)
14 - append file in existing zipfile
15
16 Change in 0.21: (10 Mar 03)
17 - bug fixes
18
19 Change in 0.17: (27 Jan 02)
20 - bug fixes
21
22 Change in 0.16: (19 Jan 02)
23 - Support of ioapi for virtualize zip file access
24
25 Change in 0.15: (19 Mar 98)
26 - fix memory leak in minizip.c
27
28 Change in 0.14: (10 Mar 98)
29 - fix bugs in minizip.c sample for zipping big file
30 - fix problem in month in date handling
31 - fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
32 comment handling
33
34 Change in 0.13: (6 Mar 98)
35 - fix bugs in zip.c
36 - add real minizip sample
37
38 Change in 0.12: (4 Mar 98)
39 - add zip.c and zip.h for creates .zip file
40 - fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
41 - fix miniunz.c for file without specific record for directory
42
43 Change in 0.11: (3 Mar 98)
44 - fix bug in unzGetCurrentFileInfo for get extra field and comment
45 - enhance miniunz sample, remove the bad unztst.c sample
46
47 Change in 0.10: (2 Mar 98)
48 - fix bug in unzReadCurrentFile
49 - rename unzip* to unz* function and structure
50 - remove Windows-like hungary notation variable name
51 - modify some structure in unzip.h
52 - add somes comment in source
53 - remove unzipGetcCurrentFile function
54 - replace ZUNZEXPORT by ZEXPORT
55 - add unzGetLocalExtrafield for get the local extrafield info
56 - add a new sample, miniunz.c
57
58 Change in 0.4: (25 Feb 98)
59 - suppress the type unzipFileInZip.
60 Only on file in the zipfile can be open at the same time
61 - fix somes typo in code
62 - added tm_unz structure in unzip_file_info (date/time in readable format)
0 CC=cc
1 CFLAGS=-O -I../..
2
3 UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
4 ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
5
6 .c.o:
7 $(CC) -c $(CFLAGS) $*.c
8
9 all: miniunz minizip
10
11 miniunz: $(UNZ_OBJS)
12 $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
13
14 minizip: $(ZIP_OBJS)
15 $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
16
17 test: miniunz minizip
18 ./minizip test readme.txt
19 ./miniunz -l test.zip
20 mv readme.txt readme.old
21 ./miniunz test.zip
22
23 clean:
24 /bin/rm -f *.o *~ minizip miniunz
0 /* crypt.h -- base code for crypt/uncrypt ZIPfile
1
2
3 Version 1.01, May 8th, 2004
4
5 Copyright (C) 1998-2004 Gilles Vollant
6
7 This code is a modified version of crypting code in Infozip distribution
8
9 The encryption/decryption parts of this source code (as opposed to the
10 non-echoing password parts) were originally written in Europe. The
11 whole source package can be freely distributed, including from the USA.
12 (Prior to January 2000, re-export from the US was a violation of US law.)
13
14 This encryption code is a direct transcription of the algorithm from
15 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
16 file (appnote.txt) is distributed with the PKZIP program (even in the
17 version without encryption capabilities).
18
19 If you don't need crypting in your application, just define symbols
20 NOCRYPT and NOUNCRYPT.
21
22 This code support the "Traditional PKWARE Encryption".
23
24 The new AES encryption added on Zip format by Winzip (see the page
25 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
26 Encryption is not supported.
27 */
28
29 #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
30
31 /***********************************************************************
32 * Return the next byte in the pseudo-random sequence
33 */
34 static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
35 {
36 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
37 * unpredictable manner on 16-bit systems; not a problem
38 * with any known compiler so far, though */
39
40 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
41 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
42 }
43
44 /***********************************************************************
45 * Update the encryption keys with the next byte of plain text
46 */
47 static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
48 {
49 (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
50 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
51 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
52 {
53 register int keyshift = (int)((*(pkeys+1)) >> 24);
54 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
55 }
56 return c;
57 }
58
59
60 /***********************************************************************
61 * Initialize the encryption keys and the random header according to
62 * the given password.
63 */
64 static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
65 {
66 *(pkeys+0) = 305419896L;
67 *(pkeys+1) = 591751049L;
68 *(pkeys+2) = 878082192L;
69 while (*passwd != '\0') {
70 update_keys(pkeys,pcrc_32_tab,(int)*passwd);
71 passwd++;
72 }
73 }
74
75 #define zdecode(pkeys,pcrc_32_tab,c) \
76 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
77
78 #define zencode(pkeys,pcrc_32_tab,c,t) \
79 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
80
81 #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
82
83 #define RAND_HEAD_LEN 12
84 /* "last resort" source for second part of crypt seed pattern */
85 # ifndef ZCR_SEED2
86 # define ZCR_SEED2 3141592654UL /* use PI as default pattern */
87 # endif
88
89 static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
90 const char *passwd; /* password string */
91 unsigned char *buf; /* where to write header */
92 int bufSize;
93 unsigned long* pkeys;
94 const unsigned long* pcrc_32_tab;
95 unsigned long crcForCrypting;
96 {
97 int n; /* index in random header */
98 int t; /* temporary */
99 int c; /* random byte */
100 unsigned char header[RAND_HEAD_LEN-2]; /* random header */
101 static unsigned calls = 0; /* ensure different random header each time */
102
103 if (bufSize<RAND_HEAD_LEN)
104 return 0;
105
106 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
107 * output of rand() to get less predictability, since rand() is
108 * often poorly implemented.
109 */
110 if (++calls == 1)
111 {
112 srand((unsigned)(time(NULL) ^ ZCR_SEED2));
113 }
114 init_keys(passwd, pkeys, pcrc_32_tab);
115 for (n = 0; n < RAND_HEAD_LEN-2; n++)
116 {
117 c = (rand() >> 7) & 0xff;
118 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
119 }
120 /* Encrypt random header (last two bytes is high word of crc) */
121 init_keys(passwd, pkeys, pcrc_32_tab);
122 for (n = 0; n < RAND_HEAD_LEN-2; n++)
123 {
124 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
125 }
126 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
127 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
128 return n;
129 }
130
131 #endif
0 /* ioapi.c -- IO base function header for compress/uncompress .zip
1 files using zlib + zip or unzip API
2
3 Version 1.01, May 8th, 2004
4
5 Copyright (C) 1998-2004 Gilles Vollant
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "zlib.h"
13 #include "ioapi.h"
14
15
16
17 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
18
19 #ifndef SEEK_CUR
20 #define SEEK_CUR 1
21 #endif
22
23 #ifndef SEEK_END
24 #define SEEK_END 2
25 #endif
26
27 #ifndef SEEK_SET
28 #define SEEK_SET 0
29 #endif
30
31 voidpf ZCALLBACK fopen_file_func OF((
32 voidpf opaque,
33 const char* filename,
34 int mode));
35
36 uLong ZCALLBACK fread_file_func OF((
37 voidpf opaque,
38 voidpf stream,
39 void* buf,
40 uLong size));
41
42 uLong ZCALLBACK fwrite_file_func OF((
43 voidpf opaque,
44 voidpf stream,
45 const void* buf,
46 uLong size));
47
48 long ZCALLBACK ftell_file_func OF((
49 voidpf opaque,
50 voidpf stream));
51
52 long ZCALLBACK fseek_file_func OF((
53 voidpf opaque,
54 voidpf stream,
55 uLong offset,
56 int origin));
57
58 int ZCALLBACK fclose_file_func OF((
59 voidpf opaque,
60 voidpf stream));
61
62 int ZCALLBACK ferror_file_func OF((
63 voidpf opaque,
64 voidpf stream));
65
66
67 voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
68 voidpf opaque;
69 const char* filename;
70 int mode;
71 {
72 FILE* file = NULL;
73 const char* mode_fopen = NULL;
74 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
75 mode_fopen = "rb";
76 else
77 if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
78 mode_fopen = "r+b";
79 else
80 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
81 mode_fopen = "wb";
82
83 if ((filename!=NULL) && (mode_fopen != NULL))
84 file = fopen(filename, mode_fopen);
85 return file;
86 }
87
88
89 uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
90 voidpf opaque;
91 voidpf stream;
92 void* buf;
93 uLong size;
94 {
95 uLong ret;
96 ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
97 return ret;
98 }
99
100
101 uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
102 voidpf opaque;
103 voidpf stream;
104 const void* buf;
105 uLong size;
106 {
107 uLong ret;
108 ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
109 return ret;
110 }
111
112 long ZCALLBACK ftell_file_func (opaque, stream)
113 voidpf opaque;
114 voidpf stream;
115 {
116 long ret;
117 ret = ftell((FILE *)stream);
118 return ret;
119 }
120
121 long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
122 voidpf opaque;
123 voidpf stream;
124 uLong offset;
125 int origin;
126 {
127 int fseek_origin=0;
128 long ret;
129 switch (origin)
130 {
131 case ZLIB_FILEFUNC_SEEK_CUR :
132 fseek_origin = SEEK_CUR;
133 break;
134 case ZLIB_FILEFUNC_SEEK_END :
135 fseek_origin = SEEK_END;
136 break;
137 case ZLIB_FILEFUNC_SEEK_SET :
138 fseek_origin = SEEK_SET;
139 break;
140 default: return -1;
141 }
142 ret = 0;
143 fseek((FILE *)stream, offset, fseek_origin);
144 return ret;
145 }
146
147 int ZCALLBACK fclose_file_func (opaque, stream)
148 voidpf opaque;
149 voidpf stream;
150 {
151 int ret;
152 ret = fclose((FILE *)stream);
153 return ret;
154 }
155
156 int ZCALLBACK ferror_file_func (opaque, stream)
157 voidpf opaque;
158 voidpf stream;
159 {
160 int ret;
161 ret = ferror((FILE *)stream);
162 return ret;
163 }
164
165 void fill_fopen_filefunc (pzlib_filefunc_def)
166 zlib_filefunc_def* pzlib_filefunc_def;
167 {
168 pzlib_filefunc_def->zopen_file = fopen_file_func;
169 pzlib_filefunc_def->zread_file = fread_file_func;
170 pzlib_filefunc_def->zwrite_file = fwrite_file_func;
171 pzlib_filefunc_def->ztell_file = ftell_file_func;
172 pzlib_filefunc_def->zseek_file = fseek_file_func;
173 pzlib_filefunc_def->zclose_file = fclose_file_func;
174 pzlib_filefunc_def->zerror_file = ferror_file_func;
175 pzlib_filefunc_def->opaque = NULL;
176 }
0 /* ioapi.h -- IO base function header for compress/uncompress .zip
1 files using zlib + zip or unzip API
2
3 Version 1.01, May 8th, 2004
4
5 Copyright (C) 1998-2004 Gilles Vollant
6 */
7
8 #ifndef _ZLIBIOAPI_H
9 #define _ZLIBIOAPI_H
10
11
12 #define ZLIB_FILEFUNC_SEEK_CUR (1)
13 #define ZLIB_FILEFUNC_SEEK_END (2)
14 #define ZLIB_FILEFUNC_SEEK_SET (0)
15
16 #define ZLIB_FILEFUNC_MODE_READ (1)
17 #define ZLIB_FILEFUNC_MODE_WRITE (2)
18 #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
19
20 #define ZLIB_FILEFUNC_MODE_EXISTING (4)
21 #define ZLIB_FILEFUNC_MODE_CREATE (8)
22
23
24 #ifndef ZCALLBACK
25
26 #if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
27 #define ZCALLBACK CALLBACK
28 #else
29 #define ZCALLBACK
30 #endif
31 #endif
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
38 typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
39 typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
40 typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
41 typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
42 typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
43 typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
44
45 typedef struct zlib_filefunc_def_s
46 {
47 open_file_func zopen_file;
48 read_file_func zread_file;
49 write_file_func zwrite_file;
50 tell_file_func ztell_file;
51 seek_file_func zseek_file;
52 close_file_func zclose_file;
53 testerror_file_func zerror_file;
54 voidpf opaque;
55 } zlib_filefunc_def;
56
57
58
59 void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
60
61 #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
62 #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
63 #define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
64 #define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
65 #define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
66 #define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
67
68
69 #ifdef __cplusplus
70 }
71 #endif
72
73 #endif
74
0 /* iowin32.c -- IO base function header for compress/uncompress .zip
1 files using zlib + zip or unzip API
2 This IO API version uses the Win32 API (for Microsoft Windows)
3
4 Version 1.01, May 8th, 2004
5
6 Copyright (C) 1998-2004 Gilles Vollant
7 */
8
9 #include <stdlib.h>
10
11 #include "zlib.h"
12 #include "ioapi.h"
13 #include "iowin32.h"
14
15 #ifndef INVALID_HANDLE_VALUE
16 #define INVALID_HANDLE_VALUE (0xFFFFFFFF)
17 #endif
18
19 #ifndef INVALID_SET_FILE_POINTER
20 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
21 #endif
22
23 voidpf ZCALLBACK win32_open_file_func OF((
24 voidpf opaque,
25 const char* filename,
26 int mode));
27
28 uLong ZCALLBACK win32_read_file_func OF((
29 voidpf opaque,
30 voidpf stream,
31 void* buf,
32 uLong size));
33
34 uLong ZCALLBACK win32_write_file_func OF((
35 voidpf opaque,
36 voidpf stream,
37 const void* buf,
38 uLong size));
39
40 long ZCALLBACK win32_tell_file_func OF((
41 voidpf opaque,
42 voidpf stream));
43
44 long ZCALLBACK win32_seek_file_func OF((
45 voidpf opaque,
46 voidpf stream,
47 uLong offset,
48 int origin));
49
50 int ZCALLBACK win32_close_file_func OF((
51 voidpf opaque,
52 voidpf stream));
53
54 int ZCALLBACK win32_error_file_func OF((
55 voidpf opaque,
56 voidpf stream));
57
58 typedef struct
59 {
60 HANDLE hf;
61 int error;
62 } WIN32FILE_IOWIN;
63
64 voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
65 voidpf opaque;
66 const char* filename;
67 int mode;
68 {
69 const char* mode_fopen = NULL;
70 DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
71 HANDLE hFile = 0;
72 voidpf ret=NULL;
73
74 dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
75
76 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
77 {
78 dwDesiredAccess = GENERIC_READ;
79 dwCreationDisposition = OPEN_EXISTING;
80 dwShareMode = FILE_SHARE_READ;
81 }
82 else
83 if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
84 {
85 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
86 dwCreationDisposition = OPEN_EXISTING;
87 }
88 else
89 if (mode & ZLIB_FILEFUNC_MODE_CREATE)
90 {
91 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
92 dwCreationDisposition = CREATE_ALWAYS;
93 }
94
95 if ((filename!=NULL) && (dwDesiredAccess != 0))
96 hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
97 dwCreationDisposition, dwFlagsAndAttributes, NULL);
98
99 if (hFile == INVALID_HANDLE_VALUE)
100 hFile = NULL;
101
102 if (hFile != NULL)
103 {
104 WIN32FILE_IOWIN w32fiow;
105 w32fiow.hf = hFile;
106 w32fiow.error = 0;
107 ret = malloc(sizeof(WIN32FILE_IOWIN));
108 if (ret==NULL)
109 CloseHandle(hFile);
110 else *((WIN32FILE_IOWIN*)ret) = w32fiow;
111 }
112 return ret;
113 }
114
115
116 uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
117 voidpf opaque;
118 voidpf stream;
119 void* buf;
120 uLong size;
121 {
122 uLong ret=0;
123 HANDLE hFile = NULL;
124 if (stream!=NULL)
125 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
126 if (hFile != NULL)
127 if (!ReadFile(hFile, buf, size, &ret, NULL))
128 {
129 DWORD dwErr = GetLastError();
130 if (dwErr == ERROR_HANDLE_EOF)
131 dwErr = 0;
132 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
133 }
134
135 return ret;
136 }
137
138
139 uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
140 voidpf opaque;
141 voidpf stream;
142 const void* buf;
143 uLong size;
144 {
145 uLong ret=0;
146 HANDLE hFile = NULL;
147 if (stream!=NULL)
148 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
149
150 if (hFile !=NULL)
151 if (!WriteFile(hFile, buf, size, &ret, NULL))
152 {
153 DWORD dwErr = GetLastError();
154 if (dwErr == ERROR_HANDLE_EOF)
155 dwErr = 0;
156 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
157 }
158
159 return ret;
160 }
161
162 long ZCALLBACK win32_tell_file_func (opaque, stream)
163 voidpf opaque;
164 voidpf stream;
165 {
166 long ret=-1;
167 HANDLE hFile = NULL;
168 if (stream!=NULL)
169 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
170 if (hFile != NULL)
171 {
172 DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
173 if (dwSet == INVALID_SET_FILE_POINTER)
174 {
175 DWORD dwErr = GetLastError();
176 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
177 ret = -1;
178 }
179 else
180 ret=(long)dwSet;
181 }
182 return ret;
183 }
184
185 long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
186 voidpf opaque;
187 voidpf stream;
188 uLong offset;
189 int origin;
190 {
191 DWORD dwMoveMethod=0xFFFFFFFF;
192 HANDLE hFile = NULL;
193
194 long ret=-1;
195 if (stream!=NULL)
196 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
197 switch (origin)
198 {
199 case ZLIB_FILEFUNC_SEEK_CUR :
200 dwMoveMethod = FILE_CURRENT;
201 break;
202 case ZLIB_FILEFUNC_SEEK_END :
203 dwMoveMethod = FILE_END;
204 break;
205 case ZLIB_FILEFUNC_SEEK_SET :
206 dwMoveMethod = FILE_BEGIN;
207 break;
208 default: return -1;
209 }
210
211 if (hFile != NULL)
212 {
213 DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
214 if (dwSet == INVALID_SET_FILE_POINTER)
215 {
216 DWORD dwErr = GetLastError();
217 ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
218 ret = -1;
219 }
220 else
221 ret=0;
222 }
223 return ret;
224 }
225
226 int ZCALLBACK win32_close_file_func (opaque, stream)
227 voidpf opaque;
228 voidpf stream;
229 {
230 int ret=-1;
231
232 if (stream!=NULL)
233 {
234 HANDLE hFile;
235 hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
236 if (hFile != NULL)
237 {
238 CloseHandle(hFile);
239 ret=0;
240 }
241 free(stream);
242 }
243 return ret;
244 }
245
246 int ZCALLBACK win32_error_file_func (opaque, stream)
247 voidpf opaque;
248 voidpf stream;
249 {
250 int ret=-1;
251 if (stream!=NULL)
252 {
253 ret = ((WIN32FILE_IOWIN*)stream) -> error;
254 }
255 return ret;
256 }
257
258 void fill_win32_filefunc (pzlib_filefunc_def)
259 zlib_filefunc_def* pzlib_filefunc_def;
260 {
261 pzlib_filefunc_def->zopen_file = win32_open_file_func;
262 pzlib_filefunc_def->zread_file = win32_read_file_func;
263 pzlib_filefunc_def->zwrite_file = win32_write_file_func;
264 pzlib_filefunc_def->ztell_file = win32_tell_file_func;
265 pzlib_filefunc_def->zseek_file = win32_seek_file_func;
266 pzlib_filefunc_def->zclose_file = win32_close_file_func;
267 pzlib_filefunc_def->zerror_file = win32_error_file_func;
268 pzlib_filefunc_def->opaque=NULL;
269 }
0 /* iowin32.h -- IO base function header for compress/uncompress .zip
1 files using zlib + zip or unzip API
2 This IO API version uses the Win32 API (for Microsoft Windows)
3
4 Version 1.01, May 8th, 2004
5
6 Copyright (C) 1998-2004 Gilles Vollant
7 */
8
9 #include <windows.h>
10
11
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15
16 void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
17
18 #ifdef __cplusplus
19 }
20 #endif
0 /*
1 miniunz.c
2 Version 1.01b, May 30th, 2004
3
4 Copyright (C) 1998-2004 Gilles Vollant
5 */
6
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <errno.h>
13 #include <fcntl.h>
14
15 #ifdef unix
16 # include <unistd.h>
17 # include <utime.h>
18 #else
19 # include <direct.h>
20 # include <io.h>
21 #endif
22
23 #include "unzip.h"
24
25 #define CASESENSITIVITY (0)
26 #define WRITEBUFFERSIZE (8192)
27 #define MAXFILENAME (256)
28
29 #ifdef WIN32
30 #define USEWIN32IOAPI
31 #include "iowin32.h"
32 #endif
33 /*
34 mini unzip, demo of unzip package
35
36 usage :
37 Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
38
39 list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
40 if it exists
41 */
42
43
44 /* change_file_date : change the date/time of a file
45 filename : the filename of the file where date/time must be modified
46 dosdate : the new date at the MSDos format (4 bytes)
47 tmu_date : the SAME new date at the tm_unz format */
48 void change_file_date(filename,dosdate,tmu_date)
49 const char *filename;
50 uLong dosdate;
51 tm_unz tmu_date;
52 {
53 #ifdef WIN32
54 HANDLE hFile;
55 FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
56
57 hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
58 0,NULL,OPEN_EXISTING,0,NULL);
59 GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
60 DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
61 LocalFileTimeToFileTime(&ftLocal,&ftm);
62 SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
63 CloseHandle(hFile);
64 #else
65 #ifdef unix
66 struct utimbuf ut;
67 struct tm newdate;
68 newdate.tm_sec = tmu_date.tm_sec;
69 newdate.tm_min=tmu_date.tm_min;
70 newdate.tm_hour=tmu_date.tm_hour;
71 newdate.tm_mday=tmu_date.tm_mday;
72 newdate.tm_mon=tmu_date.tm_mon;
73 if (tmu_date.tm_year > 1900)
74 newdate.tm_year=tmu_date.tm_year - 1900;
75 else
76 newdate.tm_year=tmu_date.tm_year ;
77 newdate.tm_isdst=-1;
78
79 ut.actime=ut.modtime=mktime(&newdate);
80 utime(filename,&ut);
81 #endif
82 #endif
83 }
84
85
86 /* mymkdir and change_file_date are not 100 % portable
87 As I don't know well Unix, I wait feedback for the unix portion */
88
89 int mymkdir(dirname)
90 const char* dirname;
91 {
92 int ret=0;
93 #ifdef WIN32
94 ret = mkdir(dirname);
95 #else
96 #ifdef unix
97 ret = mkdir (dirname,0775);
98 #endif
99 #endif
100 return ret;
101 }
102
103 int makedir (newdir)
104 char *newdir;
105 {
106 char *buffer ;
107 char *p;
108 int len = (int)strlen(newdir);
109
110 if (len <= 0)
111 return 0;
112
113 buffer = (char*)malloc(len+1);
114 strcpy(buffer,newdir);
115
116 if (buffer[len-1] == '/') {
117 buffer[len-1] = '\0';
118 }
119 if (mymkdir(buffer) == 0)
120 {
121 free(buffer);
122 return 1;
123 }
124
125 p = buffer+1;
126 while (1)
127 {
128 char hold;
129
130 while(*p && *p != '\\' && *p != '/')
131 p++;
132 hold = *p;
133 *p = 0;
134 if ((mymkdir(buffer) == -1) && (errno == ENOENT))
135 {
136 printf("couldn't create directory %s\n",buffer);
137 free(buffer);
138 return 0;
139 }
140 if (hold == 0)
141 break;
142 *p++ = hold;
143 }
144 free(buffer);
145 return 1;
146 }
147
148 void do_banner()
149 {
150 printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
151 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
152 }
153
154 void do_help()
155 {
156 printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
157 " -e Extract without pathname (junk paths)\n" \
158 " -x Extract with pathname\n" \
159 " -v list files\n" \
160 " -l list files\n" \
161 " -d directory to extract into\n" \
162 " -o overwrite files without prompting\n" \
163 " -p extract crypted file using password\n\n");
164 }
165
166
167 int do_list(uf)
168 unzFile uf;
169 {
170 uLong i;
171 unz_global_info gi;
172 int err;
173
174 err = unzGetGlobalInfo (uf,&gi);
175 if (err!=UNZ_OK)
176 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
177 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
178 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
179 for (i=0;i<gi.number_entry;i++)
180 {
181 char filename_inzip[256];
182 unz_file_info file_info;
183 uLong ratio=0;
184 const char *string_method;
185 char charCrypt=' ';
186 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
187 if (err!=UNZ_OK)
188 {
189 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
190 break;
191 }
192 if (file_info.uncompressed_size>0)
193 ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
194
195 /* display a '*' if the file is crypted */
196 if ((file_info.flag & 1) != 0)
197 charCrypt='*';
198
199 if (file_info.compression_method==0)
200 string_method="Stored";
201 else
202 if (file_info.compression_method==Z_DEFLATED)
203 {
204 uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
205 if (iLevel==0)
206 string_method="Defl:N";
207 else if (iLevel==1)
208 string_method="Defl:X";
209 else if ((iLevel==2) || (iLevel==3))
210 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
211 }
212 else
213 string_method="Unkn. ";
214
215 printf("%7lu %6s%c%7lu %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
216 file_info.uncompressed_size,string_method,
217 charCrypt,
218 file_info.compressed_size,
219 ratio,
220 (uLong)file_info.tmu_date.tm_mon + 1,
221 (uLong)file_info.tmu_date.tm_mday,
222 (uLong)file_info.tmu_date.tm_year % 100,
223 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
224 (uLong)file_info.crc,filename_inzip);
225 if ((i+1)<gi.number_entry)
226 {
227 err = unzGoToNextFile(uf);
228 if (err!=UNZ_OK)
229 {
230 printf("error %d with zipfile in unzGoToNextFile\n",err);
231 break;
232 }
233 }
234 }
235
236 return 0;
237 }
238
239
240 int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
241 unzFile uf;
242 const int* popt_extract_without_path;
243 int* popt_overwrite;
244 const char* password;
245 {
246 char filename_inzip[256];
247 char* filename_withoutpath;
248 char* p;
249 int err=UNZ_OK;
250 FILE *fout=NULL;
251 void* buf;
252 uInt size_buf;
253
254 unz_file_info file_info;
255 uLong ratio=0;
256 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
257
258 if (err!=UNZ_OK)
259 {
260 printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
261 return err;
262 }
263
264 size_buf = WRITEBUFFERSIZE;
265 buf = (void*)malloc(size_buf);
266 if (buf==NULL)
267 {
268 printf("Error allocating memory\n");
269 return UNZ_INTERNALERROR;
270 }
271
272 p = filename_withoutpath = filename_inzip;
273 while ((*p) != '\0')
274 {
275 if (((*p)=='/') || ((*p)=='\\'))
276 filename_withoutpath = p+1;
277 p++;
278 }
279
280 if ((*filename_withoutpath)=='\0')
281 {
282 if ((*popt_extract_without_path)==0)
283 {
284 printf("creating directory: %s\n",filename_inzip);
285 mymkdir(filename_inzip);
286 }
287 }
288 else
289 {
290 const char* write_filename;
291 int skip=0;
292
293 if ((*popt_extract_without_path)==0)
294 write_filename = filename_inzip;
295 else
296 write_filename = filename_withoutpath;
297
298 err = unzOpenCurrentFilePassword(uf,password);
299 if (err!=UNZ_OK)
300 {
301 printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
302 }
303
304 if (((*popt_overwrite)==0) && (err==UNZ_OK))
305 {
306 char rep=0;
307 FILE* ftestexist;
308 ftestexist = fopen(write_filename,"rb");
309 if (ftestexist!=NULL)
310 {
311 fclose(ftestexist);
312 do
313 {
314 char answer[128];
315 int ret;
316
317 printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
318 ret = scanf("%1s",answer);
319 if (ret != 1)
320 {
321 exit(EXIT_FAILURE);
322 }
323 rep = answer[0] ;
324 if ((rep>='a') && (rep<='z'))
325 rep -= 0x20;
326 }
327 while ((rep!='Y') && (rep!='N') && (rep!='A'));
328 }
329
330 if (rep == 'N')
331 skip = 1;
332
333 if (rep == 'A')
334 *popt_overwrite=1;
335 }
336
337 if ((skip==0) && (err==UNZ_OK))
338 {
339 fout=fopen(write_filename,"wb");
340
341 /* some zipfile don't contain directory alone before file */
342 if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
343 (filename_withoutpath!=(char*)filename_inzip))
344 {
345 char c=*(filename_withoutpath-1);
346 *(filename_withoutpath-1)='\0';
347 makedir(write_filename);
348 *(filename_withoutpath-1)=c;
349 fout=fopen(write_filename,"wb");
350 }
351
352 if (fout==NULL)
353 {
354 printf("error opening %s\n",write_filename);
355 }
356 }
357
358 if (fout!=NULL)
359 {
360 printf(" extracting: %s\n",write_filename);
361
362 do
363 {
364 err = unzReadCurrentFile(uf,buf,size_buf);
365 if (err<0)
366 {
367 printf("error %d with zipfile in unzReadCurrentFile\n",err);
368 break;
369 }
370 if (err>0)
371 if (fwrite(buf,err,1,fout)!=1)
372 {
373 printf("error in writing extracted file\n");
374 err=UNZ_ERRNO;
375 break;
376 }
377 }
378 while (err>0);
379 if (fout)
380 fclose(fout);
381
382 if (err==0)
383 change_file_date(write_filename,file_info.dosDate,
384 file_info.tmu_date);
385 }
386
387 if (err==UNZ_OK)
388 {
389 err = unzCloseCurrentFile (uf);
390 if (err!=UNZ_OK)
391 {
392 printf("error %d with zipfile in unzCloseCurrentFile\n",err);
393 }
394 }
395 else
396 unzCloseCurrentFile(uf); /* don't lose the error */
397 }
398
399 free(buf);
400 return err;
401 }
402
403
404 int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
405 unzFile uf;
406 int opt_extract_without_path;
407 int opt_overwrite;
408 const char* password;
409 {
410 uLong i;
411 unz_global_info gi;
412 int err;
413 FILE* fout=NULL;
414
415 err = unzGetGlobalInfo (uf,&gi);
416 if (err!=UNZ_OK)
417 printf("error %d with zipfile in unzGetGlobalInfo \n",err);
418
419 for (i=0;i<gi.number_entry;i++)
420 {
421 if (do_extract_currentfile(uf,&opt_extract_without_path,
422 &opt_overwrite,
423 password) != UNZ_OK)
424 break;
425
426 if ((i+1)<gi.number_entry)
427 {
428 err = unzGoToNextFile(uf);
429 if (err!=UNZ_OK)
430 {
431 printf("error %d with zipfile in unzGoToNextFile\n",err);
432 break;
433 }
434 }
435 }
436
437 return 0;
438 }
439
440 int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
441 unzFile uf;
442 const char* filename;
443 int opt_extract_without_path;
444 int opt_overwrite;
445 const char* password;
446 {
447 int err = UNZ_OK;
448 if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
449 {
450 printf("file %s not found in the zipfile\n",filename);
451 return 2;
452 }
453
454 if (do_extract_currentfile(uf,&opt_extract_without_path,
455 &opt_overwrite,
456 password) == UNZ_OK)
457 return 0;
458 else
459 return 1;
460 }
461
462
463 int main(argc,argv)
464 int argc;
465 char *argv[];
466 {
467 const char *zipfilename=NULL;
468 const char *filename_to_extract=NULL;
469 const char *password=NULL;
470 char filename_try[MAXFILENAME+16] = "";
471 int i;
472 int opt_do_list=0;
473 int opt_do_extract=1;
474 int opt_do_extract_withoutpath=0;
475 int opt_overwrite=0;
476 int opt_extractdir=0;
477 const char *dirname=NULL;
478 unzFile uf=NULL;
479
480 do_banner();
481 if (argc==1)
482 {
483 do_help();
484 return 0;
485 }
486 else
487 {
488 for (i=1;i<argc;i++)
489 {
490 if ((*argv[i])=='-')
491 {
492 const char *p=argv[i]+1;
493
494 while ((*p)!='\0')
495 {
496 char c=*(p++);;
497 if ((c=='l') || (c=='L'))
498 opt_do_list = 1;
499 if ((c=='v') || (c=='V'))
500 opt_do_list = 1;
501 if ((c=='x') || (c=='X'))
502 opt_do_extract = 1;
503 if ((c=='e') || (c=='E'))
504 opt_do_extract = opt_do_extract_withoutpath = 1;
505 if ((c=='o') || (c=='O'))
506 opt_overwrite=1;
507 if ((c=='d') || (c=='D'))
508 {
509 opt_extractdir=1;
510 dirname=argv[i+1];
511 }
512
513 if (((c=='p') || (c=='P')) && (i+1<argc))
514 {
515 password=argv[i+1];
516 i++;
517 }
518 }
519 }
520 else
521 {
522 if (zipfilename == NULL)
523 zipfilename = argv[i];
524 else if ((filename_to_extract==NULL) && (!opt_extractdir))
525 filename_to_extract = argv[i] ;
526 }
527 }
528 }
529
530 if (zipfilename!=NULL)
531 {
532
533 # ifdef USEWIN32IOAPI
534 zlib_filefunc_def ffunc;
535 # endif
536
537 strncpy(filename_try, zipfilename,MAXFILENAME-1);
538 /* strncpy doesnt append the trailing NULL, of the string is too long. */
539 filename_try[ MAXFILENAME ] = '\0';
540
541 # ifdef USEWIN32IOAPI
542 fill_win32_filefunc(&ffunc);
543 uf = unzOpen2(zipfilename,&ffunc);
544 # else
545 uf = unzOpen(zipfilename);
546 # endif
547 if (uf==NULL)
548 {
549 strcat(filename_try,".zip");
550 # ifdef USEWIN32IOAPI
551 uf = unzOpen2(filename_try,&ffunc);
552 # else
553 uf = unzOpen(filename_try);
554 # endif
555 }
556 }
557
558 if (uf==NULL)
559 {
560 printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
561 return 1;
562 }
563 printf("%s opened\n",filename_try);
564
565 if (opt_do_list==1)
566 return do_list(uf);
567 else if (opt_do_extract==1)
568 {
569 if (opt_extractdir && chdir(dirname))
570 {
571 printf("Error changing into %s, aborting\n", dirname);
572 exit(-1);
573 }
574
575 if (filename_to_extract == NULL)
576 return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);
577 else
578 return do_extract_onefile(uf,filename_to_extract,
579 opt_do_extract_withoutpath,opt_overwrite,password);
580 }
581 unzCloseCurrentFile(uf);
582
583 return 0;
584 }
0 /*
1 minizip.c
2 Version 1.01b, May 30th, 2004
3
4 Copyright (C) 1998-2004 Gilles Vollant
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <time.h>
11 #include <errno.h>
12 #include <fcntl.h>
13
14 #ifdef unix
15 # include <unistd.h>
16 # include <utime.h>
17 # include <sys/types.h>
18 # include <sys/stat.h>
19 #else
20 # include <direct.h>
21 # include <io.h>
22 #endif
23
24 #include "zip.h"
25
26 #ifdef WIN32
27 #define USEWIN32IOAPI
28 #include "iowin32.h"
29 #endif
30
31
32
33 #define WRITEBUFFERSIZE (16384)
34 #define MAXFILENAME (256)
35
36 #ifdef WIN32
37 uLong filetime(f, tmzip, dt)
38 char *f; /* name of file to get info on */
39 tm_zip *tmzip; /* return value: access, modific. and creation times */
40 uLong *dt; /* dostime */
41 {
42 int ret = 0;
43 {
44 FILETIME ftLocal;
45 HANDLE hFind;
46 WIN32_FIND_DATA ff32;
47
48 hFind = FindFirstFile(f,&ff32);
49 if (hFind != INVALID_HANDLE_VALUE)
50 {
51 FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
52 FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
53 FindClose(hFind);
54 ret = 1;
55 }
56 }
57 return ret;
58 }
59 #else
60 #ifdef unix
61 uLong filetime(f, tmzip, dt)
62 char *f; /* name of file to get info on */
63 tm_zip *tmzip; /* return value: access, modific. and creation times */
64 uLong *dt; /* dostime */
65 {
66 int ret=0;
67 struct stat s; /* results of stat() */
68 struct tm* filedate;
69 time_t tm_t=0;
70
71 if (strcmp(f,"-")!=0)
72 {
73 char name[MAXFILENAME+1];
74 int len = strlen(f);
75 if (len > MAXFILENAME)
76 len = MAXFILENAME;
77
78 strncpy(name, f,MAXFILENAME-1);
79 /* strncpy doesnt append the trailing NULL, of the string is too long. */
80 name[ MAXFILENAME ] = '\0';
81
82 if (name[len - 1] == '/')
83 name[len - 1] = '\0';
84 /* not all systems allow stat'ing a file with / appended */
85 if (stat(name,&s)==0)
86 {
87 tm_t = s.st_mtime;
88 ret = 1;
89 }
90 }
91 filedate = localtime(&tm_t);
92
93 tmzip->tm_sec = filedate->tm_sec;
94 tmzip->tm_min = filedate->tm_min;
95 tmzip->tm_hour = filedate->tm_hour;
96 tmzip->tm_mday = filedate->tm_mday;
97 tmzip->tm_mon = filedate->tm_mon ;
98 tmzip->tm_year = filedate->tm_year;
99
100 return ret;
101 }
102 #else
103 uLong filetime(f, tmzip, dt)
104 char *f; /* name of file to get info on */
105 tm_zip *tmzip; /* return value: access, modific. and creation times */
106 uLong *dt; /* dostime */
107 {
108 return 0;
109 }
110 #endif
111 #endif
112
113
114
115
116 int check_exist_file(filename)
117 const char* filename;
118 {
119 FILE* ftestexist;
120 int ret = 1;
121 ftestexist = fopen(filename,"rb");
122 if (ftestexist==NULL)
123 ret = 0;
124 else
125 fclose(ftestexist);
126 return ret;
127 }
128
129 void do_banner()
130 {
131 printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n");
132 printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
133 }
134
135 void do_help()
136 {
137 printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \
138 " -o Overwrite existing file.zip\n" \
139 " -a Append to existing file.zip\n" \
140 " -0 Store only\n" \
141 " -1 Compress faster\n" \
142 " -9 Compress better\n\n");
143 }
144
145 /* calculate the CRC32 of a file,
146 because to encrypt a file, we need known the CRC32 of the file before */
147 int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
148 {
149 unsigned long calculate_crc=0;
150 int err=ZIP_OK;
151 FILE * fin = fopen(filenameinzip,"rb");
152 unsigned long size_read = 0;
153 unsigned long total_read = 0;
154 if (fin==NULL)
155 {
156 err = ZIP_ERRNO;
157 }
158
159 if (err == ZIP_OK)
160 do
161 {
162 err = ZIP_OK;
163 size_read = (int)fread(buf,1,size_buf,fin);
164 if (size_read < size_buf)
165 if (feof(fin)==0)
166 {
167 printf("error in reading %s\n",filenameinzip);
168 err = ZIP_ERRNO;
169 }
170
171 if (size_read>0)
172 calculate_crc = crc32(calculate_crc,buf,size_read);
173 total_read += size_read;
174
175 } while ((err == ZIP_OK) && (size_read>0));
176
177 if (fin)
178 fclose(fin);
179
180 *result_crc=calculate_crc;
181 printf("file %s crc %x\n",filenameinzip,calculate_crc);
182 return err;
183 }
184
185 int main(argc,argv)
186 int argc;
187 char *argv[];
188 {
189 int i;
190 int opt_overwrite=0;
191 int opt_compress_level=Z_DEFAULT_COMPRESSION;
192 int zipfilenamearg = 0;
193 char filename_try[MAXFILENAME+16];
194 int zipok;
195 int err=0;
196 int size_buf=0;
197 void* buf=NULL;
198 const char* password=NULL;
199
200
201 do_banner();
202 if (argc==1)
203 {
204 do_help();
205 return 0;
206 }
207 else
208 {
209 for (i=1;i<argc;i++)
210 {
211 if ((*argv[i])=='-')
212 {
213 const char *p=argv[i]+1;
214
215 while ((*p)!='\0')
216 {
217 char c=*(p++);;
218 if ((c=='o') || (c=='O'))
219 opt_overwrite = 1;
220 if ((c=='a') || (c=='A'))
221 opt_overwrite = 2;
222 if ((c>='0') && (c<='9'))
223 opt_compress_level = c-'0';
224
225 if (((c=='p') || (c=='P')) && (i+1<argc))
226 {
227 password=argv[i+1];
228 i++;
229 }
230 }
231 }
232 else
233 if (zipfilenamearg == 0)
234 zipfilenamearg = i ;
235 }
236 }
237
238 size_buf = WRITEBUFFERSIZE;
239 buf = (void*)malloc(size_buf);
240 if (buf==NULL)
241 {
242 printf("Error allocating memory\n");
243 return ZIP_INTERNALERROR;
244 }
245
246 if (zipfilenamearg==0)
247 zipok=0;
248 else
249 {
250 int i,len;
251 int dot_found=0;
252
253 zipok = 1 ;
254 strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
255 /* strncpy doesnt append the trailing NULL, of the string is too long. */
256 filename_try[ MAXFILENAME ] = '\0';
257
258 len=(int)strlen(filename_try);
259 for (i=0;i<len;i++)
260 if (filename_try[i]=='.')
261 dot_found=1;
262
263 if (dot_found==0)
264 strcat(filename_try,".zip");
265
266 if (opt_overwrite==2)
267 {
268 /* if the file don't exist, we not append file */
269 if (check_exist_file(filename_try)==0)
270 opt_overwrite=1;
271 }
272 else
273 if (opt_overwrite==0)
274 if (check_exist_file(filename_try)!=0)
275 {
276 char rep=0;
277 do
278 {
279 char answer[128];
280 int ret;
281 printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
282 ret = scanf("%1s",answer);
283 if (ret != 1)
284 {
285 exit(EXIT_FAILURE);
286 }
287 rep = answer[0] ;
288 if ((rep>='a') && (rep<='z'))
289 rep -= 0x20;
290 }
291 while ((rep!='Y') && (rep!='N') && (rep!='A'));
292 if (rep=='N')
293 zipok = 0;
294 if (rep=='A')
295 opt_overwrite = 2;
296 }
297 }
298
299 if (zipok==1)
300 {
301 zipFile zf;
302 int errclose;
303 # ifdef USEWIN32IOAPI
304 zlib_filefunc_def ffunc;
305 fill_win32_filefunc(&ffunc);
306 zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
307 # else
308 zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
309 # endif
310
311 if (zf == NULL)
312 {
313 printf("error opening %s\n",filename_try);
314 err= ZIP_ERRNO;
315 }
316 else
317 printf("creating %s\n",filename_try);
318
319 for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
320 {
321 if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
322 ((argv[i][1]=='o') || (argv[i][1]=='O') ||
323 (argv[i][1]=='a') || (argv[i][1]=='A') ||
324 (argv[i][1]=='p') || (argv[i][1]=='P') ||
325 ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
326 (strlen(argv[i]) == 2)))
327 {
328 FILE * fin;
329 int size_read;
330 const char* filenameinzip = argv[i];
331 zip_fileinfo zi;
332 unsigned long crcFile=0;
333
334 zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
335 zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
336 zi.dosDate = 0;
337 zi.internal_fa = 0;
338 zi.external_fa = 0;
339 filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
340
341 /*
342 err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
343 NULL,0,NULL,0,NULL / * comment * /,
344 (opt_compress_level != 0) ? Z_DEFLATED : 0,
345 opt_compress_level);
346 */
347 if ((password != NULL) && (err==ZIP_OK))
348 err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
349
350 err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,
351 NULL,0,NULL,0,NULL /* comment*/,
352 (opt_compress_level != 0) ? Z_DEFLATED : 0,
353 opt_compress_level,0,
354 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
355 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
356 password,crcFile);
357
358 if (err != ZIP_OK)
359 printf("error in opening %s in zipfile\n",filenameinzip);
360 else
361 {
362 fin = fopen(filenameinzip,"rb");
363 if (fin==NULL)
364 {
365 err=ZIP_ERRNO;
366 printf("error in opening %s for reading\n",filenameinzip);
367 }
368 }
369
370 if (err == ZIP_OK)
371 do
372 {
373 err = ZIP_OK;
374 size_read = (int)fread(buf,1,size_buf,fin);
375 if (size_read < size_buf)
376 if (feof(fin)==0)
377 {
378 printf("error in reading %s\n",filenameinzip);
379 err = ZIP_ERRNO;
380 }
381
382 if (size_read>0)
383 {
384 err = zipWriteInFileInZip (zf,buf,size_read);
385 if (err<0)
386 {
387 printf("error in writing %s in the zipfile\n",
388 filenameinzip);
389 }
390
391 }
392 } while ((err == ZIP_OK) && (size_read>0));
393
394 if (fin)
395 fclose(fin);
396
397 if (err<0)
398 err=ZIP_ERRNO;
399 else
400 {
401 err = zipCloseFileInZip(zf);
402 if (err!=ZIP_OK)
403 printf("error in closing %s in the zipfile\n",
404 filenameinzip);
405 }
406 }
407 }
408 errclose = zipClose(zf,NULL);
409 if (errclose != ZIP_OK)
410 printf("error in closing %s\n",filename_try);
411 }
412 else
413 {
414 do_help();
415 }
416
417 free(buf);
418 return 0;
419 }
0 /*
1 Additional tools for Minizip
2 Code: Xavier Roche '2004
3 License: Same as ZLIB (www.gzip.org)
4 */
5
6 /* Code */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "zlib.h"
11 #include "unzip.h"
12
13 #define READ_8(adr) ((unsigned char)*(adr))
14 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
15 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
16
17 #define WRITE_8(buff, n) do { \
18 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
19 } while(0)
20 #define WRITE_16(buff, n) do { \
21 WRITE_8((unsigned char*)(buff), n); \
22 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
23 } while(0)
24 #define WRITE_32(buff, n) do { \
25 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
26 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
27 } while(0)
28
29 extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
30 const char* file;
31 const char* fileOut;
32 const char* fileOutTmp;
33 uLong* nRecovered;
34 uLong* bytesRecovered;
35 {
36 int err = Z_OK;
37 FILE* fpZip = fopen(file, "rb");
38 FILE* fpOut = fopen(fileOut, "wb");
39 FILE* fpOutCD = fopen(fileOutTmp, "wb");
40 if (fpZip != NULL && fpOut != NULL) {
41 int entries = 0;
42 uLong totalBytes = 0;
43 char header[30];
44 char filename[256];
45 char extra[1024];
46 int offset = 0;
47 int offsetCD = 0;
48 while ( fread(header, 1, 30, fpZip) == 30 ) {
49 int currentOffset = offset;
50
51 /* File entry */
52 if (READ_32(header) == 0x04034b50) {
53 unsigned int version = READ_16(header + 4);
54 unsigned int gpflag = READ_16(header + 6);
55 unsigned int method = READ_16(header + 8);
56 unsigned int filetime = READ_16(header + 10);
57 unsigned int filedate = READ_16(header + 12);
58 unsigned int crc = READ_32(header + 14); /* crc */
59 unsigned int cpsize = READ_32(header + 18); /* compressed size */
60 unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
61 unsigned int fnsize = READ_16(header + 26); /* file name length */
62 unsigned int extsize = READ_16(header + 28); /* extra field length */
63 filename[0] = extra[0] = '\0';
64
65 /* Header */
66 if (fwrite(header, 1, 30, fpOut) == 30) {
67 offset += 30;
68 } else {
69 err = Z_ERRNO;
70 break;
71 }
72
73 /* Filename */
74 if (fnsize > 0) {
75 if (fread(filename, 1, fnsize, fpZip) == fnsize) {
76 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
77 offset += fnsize;
78 } else {
79 err = Z_ERRNO;
80 break;
81 }
82 } else {
83 err = Z_ERRNO;
84 break;
85 }
86 } else {
87 err = Z_STREAM_ERROR;
88 break;
89 }
90
91 /* Extra field */
92 if (extsize > 0) {
93 if (fread(extra, 1, extsize, fpZip) == extsize) {
94 if (fwrite(extra, 1, extsize, fpOut) == extsize) {
95 offset += extsize;
96 } else {
97 err = Z_ERRNO;
98 break;
99 }
100 } else {
101 err = Z_ERRNO;
102 break;
103 }
104 }
105
106 /* Data */
107 {
108 int dataSize = cpsize;
109 if (dataSize == 0) {
110 dataSize = uncpsize;
111 }
112 if (dataSize > 0) {
113 char* data = malloc(dataSize);
114 if (data != NULL) {
115 if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
116 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
117 offset += dataSize;
118 totalBytes += dataSize;
119 } else {
120 err = Z_ERRNO;
121 }
122 } else {
123 err = Z_ERRNO;
124 }
125 free(data);
126 if (err != Z_OK) {
127 break;
128 }
129 } else {
130 err = Z_MEM_ERROR;
131 break;
132 }
133 }
134 }
135
136 /* Central directory entry */
137 {
138 char header[46];
139 char* comment = "";
140 int comsize = (int) strlen(comment);
141 WRITE_32(header, 0x02014b50);
142 WRITE_16(header + 4, version);
143 WRITE_16(header + 6, version);
144 WRITE_16(header + 8, gpflag);
145 WRITE_16(header + 10, method);
146 WRITE_16(header + 12, filetime);
147 WRITE_16(header + 14, filedate);
148 WRITE_32(header + 16, crc);
149 WRITE_32(header + 20, cpsize);
150 WRITE_32(header + 24, uncpsize);
151 WRITE_16(header + 28, fnsize);
152 WRITE_16(header + 30, extsize);
153 WRITE_16(header + 32, comsize);
154 WRITE_16(header + 34, 0); /* disk # */
155 WRITE_16(header + 36, 0); /* int attrb */
156 WRITE_32(header + 38, 0); /* ext attrb */
157 WRITE_32(header + 42, currentOffset);
158 /* Header */
159 if (fwrite(header, 1, 46, fpOutCD) == 46) {
160 offsetCD += 46;
161
162 /* Filename */
163 if (fnsize > 0) {
164 if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
165 offsetCD += fnsize;
166 } else {
167 err = Z_ERRNO;
168 break;
169 }
170 } else {
171 err = Z_STREAM_ERROR;
172 break;
173 }
174
175 /* Extra field */
176 if (extsize > 0) {
177 if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
178 offsetCD += extsize;
179 } else {
180 err = Z_ERRNO;
181 break;
182 }
183 }
184
185 /* Comment field */
186 if (comsize > 0) {
187 if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
188 offsetCD += comsize;
189 } else {
190 err = Z_ERRNO;
191 break;
192 }
193 }
194
195
196 } else {
197 err = Z_ERRNO;
198 break;
199 }
200 }
201
202 /* Success */
203 entries++;
204
205 } else {
206 break;
207 }
208 }
209
210 /* Final central directory */
211 {
212 int entriesZip = entries;
213 char header[22];
214 char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
215 int comsize = (int) strlen(comment);
216 if (entriesZip > 0xffff) {
217 entriesZip = 0xffff;
218 }
219 WRITE_32(header, 0x06054b50);
220 WRITE_16(header + 4, 0); /* disk # */
221 WRITE_16(header + 6, 0); /* disk # */
222 WRITE_16(header + 8, entriesZip); /* hack */
223 WRITE_16(header + 10, entriesZip); /* hack */
224 WRITE_32(header + 12, offsetCD); /* size of CD */
225 WRITE_32(header + 16, offset); /* offset to CD */
226 WRITE_16(header + 20, comsize); /* comment */
227
228 /* Header */
229 if (fwrite(header, 1, 22, fpOutCD) == 22) {
230
231 /* Comment field */
232 if (comsize > 0) {
233 if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
234 err = Z_ERRNO;
235 }
236 }
237
238 } else {
239 err = Z_ERRNO;
240 }
241 }
242
243 /* Final merge (file + central directory) */
244 fclose(fpOutCD);
245 if (err == Z_OK) {
246 fpOutCD = fopen(fileOutTmp, "rb");
247 if (fpOutCD != NULL) {
248 int nRead;
249 char buffer[8192];
250 while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
251 if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
252 err = Z_ERRNO;
253 break;
254 }
255 }
256 fclose(fpOutCD);
257 }
258 }
259
260 /* Close */
261 fclose(fpZip);
262 fclose(fpOut);
263
264 /* Wipe temporary file */
265 (void)remove(fileOutTmp);
266
267 /* Number of recovered entries */
268 if (err == Z_OK) {
269 if (nRecovered != NULL) {
270 *nRecovered = entries;
271 }
272 if (bytesRecovered != NULL) {
273 *bytesRecovered = totalBytes;
274 }
275 }
276 } else {
277 err = Z_STREAM_ERROR;
278 }
279 return err;
280 }
0 /*
1 Additional tools for Minizip
2 Code: Xavier Roche '2004
3 License: Same as ZLIB (www.gzip.org)
4 */
5
6 #ifndef _zip_tools_H
7 #define _zip_tools_H
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 #ifndef _ZLIB_H
14 #include "zlib.h"
15 #endif
16
17 #include "unzip.h"
18
19 /* Repair a ZIP file (missing central directory)
20 file: file to recover
21 fileOut: output file after recovery
22 fileOutTmp: temporary file name used for recovery
23 */
24 extern int ZEXPORT unzRepair(const char* file,
25 const char* fileOut,
26 const char* fileOutTmp,
27 uLong* nRecovered,
28 uLong* bytesRecovered);
29
30 #endif
0 /* unzip.c -- IO for uncompress .zip files using zlib
1 Version 1.01d, September 22th, 2004
2
3 Copyright (C) 1998-2004 Gilles Vollant
4
5 Read unzip.h for more info
6 */
7
8 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
9 compatibility with older software. The following is from the original crypt.c. Code
10 woven in by Terry Thorsen 1/2003.
11 */
12 /*
13 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
14
15 See the accompanying file LICENSE, version 2000-Apr-09 or later
16 (the contents of which are also included in zip.h) for terms of use.
17 If, for some reason, all these files are missing, the Info-ZIP license
18 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
19 */
20 /*
21 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
22
23 The encryption/decryption parts of this source code (as opposed to the
24 non-echoing password parts) were originally written in Europe. The
25 whole source package can be freely distributed, including from the USA.
26 (Prior to January 2000, re-export from the US was a violation of US law.)
27 */
28
29 /*
30 This encryption code is a direct transcription of the algorithm from
31 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
32 file (appnote.txt) is distributed with the PKZIP program (even in the
33 version without encryption capabilities).
34 */
35
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include "zlib.h"
41 #include "unzip.h"
42
43 #ifdef STDC
44 # include <stddef.h>
45 # include <string.h>
46 # include <stdlib.h>
47 #endif
48 #ifdef NO_ERRNO_H
49 extern int errno;
50 #else
51 # include <errno.h>
52 #endif
53
54
55 #ifndef local
56 # define local static
57 #endif
58 /* compile with -Dlocal if your debugger can't find static symbols */
59
60
61 #ifndef CASESENSITIVITYDEFAULT_NO
62 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
63 # define CASESENSITIVITYDEFAULT_NO
64 # endif
65 #endif
66
67
68 #ifndef UNZ_BUFSIZE
69 #define UNZ_BUFSIZE (16384)
70 #endif
71
72 #ifndef UNZ_MAXFILENAMEINZIP
73 #define UNZ_MAXFILENAMEINZIP (256)
74 #endif
75
76 #ifndef ALLOC
77 # define ALLOC(size) (malloc(size))
78 #endif
79 #ifndef TRYFREE
80 # define TRYFREE(p) {if (p) free(p);}
81 #endif
82
83 #define SIZECENTRALDIRITEM (0x2e)
84 #define SIZEZIPLOCALHEADER (0x1e)
85
86
87
88
89 const char unz_copyright[] =
90 " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
91
92 /* unz_file_info_interntal contain internal info about a file in zipfile*/
93 typedef struct unz_file_info_internal_s
94 {
95 uLong offset_curfile;/* relative offset of local header 4 bytes */
96 } unz_file_info_internal;
97
98
99 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
100 when reading and decompress it */
101 typedef struct
102 {
103 char *read_buffer; /* internal buffer for compressed data */
104 z_stream stream; /* zLib stream structure for inflate */
105
106 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
107 uLong stream_initialised; /* flag set if stream structure is initialised*/
108
109 uLong offset_local_extrafield;/* offset of the local extra field */
110 uInt size_local_extrafield;/* size of the local extra field */
111 uLong pos_local_extrafield; /* position in the local extra field in read*/
112
113 uLong crc32; /* crc32 of all data uncompressed */
114 uLong crc32_wait; /* crc32 we must obtain after decompress all */
115 uLong rest_read_compressed; /* number of byte to be decompressed */
116 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
117 zlib_filefunc_def z_filefunc;
118 voidpf filestream; /* io structore of the zipfile */
119 uLong compression_method; /* compression method (0==store) */
120 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
121 int raw;
122 } file_in_zip_read_info_s;
123
124
125 /* unz_s contain internal information about the zipfile
126 */
127 typedef struct
128 {
129 zlib_filefunc_def z_filefunc;
130 voidpf filestream; /* io structore of the zipfile */
131 unz_global_info gi; /* public global information */
132 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
133 uLong num_file; /* number of the current file in the zipfile*/
134 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
135 uLong current_file_ok; /* flag about the usability of the current file*/
136 uLong central_pos; /* position of the beginning of the central dir*/
137
138 uLong size_central_dir; /* size of the central directory */
139 uLong offset_central_dir; /* offset of start of central directory with
140 respect to the starting disk number */
141
142 unz_file_info cur_file_info; /* public info about the current file in zip*/
143 unz_file_info_internal cur_file_info_internal; /* private info about it*/
144 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
145 file if we are decompressing it */
146 int encrypted;
147 # ifndef NOUNCRYPT
148 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
149 const unsigned long* pcrc_32_tab;
150 # endif
151 } unz_s;
152
153
154 #ifndef NOUNCRYPT
155 #include "crypt.h"
156 #endif
157
158 /* ===========================================================================
159 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
160 for end of file.
161 IN assertion: the stream s has been sucessfully opened for reading.
162 */
163
164
165 local int unzlocal_getByte OF((
166 const zlib_filefunc_def* pzlib_filefunc_def,
167 voidpf filestream,
168 int *pi));
169
170 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
171 const zlib_filefunc_def* pzlib_filefunc_def;
172 voidpf filestream;
173 int *pi;
174 {
175 unsigned char c;
176 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
177 if (err==1)
178 {
179 *pi = (int)c;
180 return UNZ_OK;
181 }
182 else
183 {
184 if (ZERROR(*pzlib_filefunc_def,filestream))
185 return UNZ_ERRNO;
186 else
187 return UNZ_EOF;
188 }
189 }
190
191
192 /* ===========================================================================
193 Reads a long in LSB order from the given gz_stream. Sets
194 */
195 local int unzlocal_getShort OF((
196 const zlib_filefunc_def* pzlib_filefunc_def,
197 voidpf filestream,
198 uLong *pX));
199
200 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
201 const zlib_filefunc_def* pzlib_filefunc_def;
202 voidpf filestream;
203 uLong *pX;
204 {
205 uLong x ;
206 int i;
207 int err;
208
209 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
210 x = (uLong)i;
211
212 if (err==UNZ_OK)
213 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
214 x += ((uLong)i)<<8;
215
216 if (err==UNZ_OK)
217 *pX = x;
218 else
219 *pX = 0;
220 return err;
221 }
222
223 local int unzlocal_getLong OF((
224 const zlib_filefunc_def* pzlib_filefunc_def,
225 voidpf filestream,
226 uLong *pX));
227
228 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
229 const zlib_filefunc_def* pzlib_filefunc_def;
230 voidpf filestream;
231 uLong *pX;
232 {
233 uLong x ;
234 int i;
235 int err;
236
237 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
238 x = (uLong)i;
239
240 if (err==UNZ_OK)
241 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
242 x += ((uLong)i)<<8;
243
244 if (err==UNZ_OK)
245 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
246 x += ((uLong)i)<<16;
247
248 if (err==UNZ_OK)
249 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
250 x += ((uLong)i)<<24;
251
252 if (err==UNZ_OK)
253 *pX = x;
254 else
255 *pX = 0;
256 return err;
257 }
258
259
260 /* My own strcmpi / strcasecmp */
261 local int strcmpcasenosensitive_internal (fileName1,fileName2)
262 const char* fileName1;
263 const char* fileName2;
264 {
265 for (;;)
266 {
267 char c1=*(fileName1++);
268 char c2=*(fileName2++);
269 if ((c1>='a') && (c1<='z'))
270 c1 -= 0x20;
271 if ((c2>='a') && (c2<='z'))
272 c2 -= 0x20;
273 if (c1=='\0')
274 return ((c2=='\0') ? 0 : -1);
275 if (c2=='\0')
276 return 1;
277 if (c1<c2)
278 return -1;
279 if (c1>c2)
280 return 1;
281 }
282 }
283
284
285 #ifdef CASESENSITIVITYDEFAULT_NO
286 #define CASESENSITIVITYDEFAULTVALUE 2
287 #else
288 #define CASESENSITIVITYDEFAULTVALUE 1
289 #endif
290
291 #ifndef STRCMPCASENOSENTIVEFUNCTION
292 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
293 #endif
294
295 /*
296 Compare two filename (fileName1,fileName2).
297 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
298 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
299 or strcasecmp)
300 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
301 (like 1 on Unix, 2 on Windows)
302
303 */
304 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
305 const char* fileName1;
306 const char* fileName2;
307 int iCaseSensitivity;
308 {
309 if (iCaseSensitivity==0)
310 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
311
312 if (iCaseSensitivity==1)
313 return strcmp(fileName1,fileName2);
314
315 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
316 }
317
318 #ifndef BUFREADCOMMENT
319 #define BUFREADCOMMENT (0x400)
320 #endif
321
322 /*
323 Locate the Central directory of a zipfile (at the end, just before
324 the global comment)
325 */
326 local uLong unzlocal_SearchCentralDir OF((
327 const zlib_filefunc_def* pzlib_filefunc_def,
328 voidpf filestream));
329
330 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
331 const zlib_filefunc_def* pzlib_filefunc_def;
332 voidpf filestream;
333 {
334 unsigned char* buf;
335 uLong uSizeFile;
336 uLong uBackRead;
337 uLong uMaxBack=0xffff; /* maximum size of global comment */
338 uLong uPosFound=0;
339
340 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
341 return 0;
342
343
344 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
345
346 if (uMaxBack>uSizeFile)
347 uMaxBack = uSizeFile;
348
349 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
350 if (buf==NULL)
351 return 0;
352
353 uBackRead = 4;
354 while (uBackRead<uMaxBack)
355 {
356 uLong uReadSize,uReadPos ;
357 int i;
358 if (uBackRead+BUFREADCOMMENT>uMaxBack)
359 uBackRead = uMaxBack;
360 else
361 uBackRead+=BUFREADCOMMENT;
362 uReadPos = uSizeFile-uBackRead ;
363
364 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
365 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
366 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
367 break;
368
369 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
370 break;
371
372 for (i=(int)uReadSize-3; (i--)>0;)
373 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
374 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
375 {
376 uPosFound = uReadPos+i;
377 break;
378 }
379
380 if (uPosFound!=0)
381 break;
382 }
383 TRYFREE(buf);
384 return uPosFound;
385 }
386
387 /*
388 Open a Zip file. path contain the full pathname (by example,
389 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
390 "zlib/zlib114.zip".
391 If the zipfile cannot be opened (file doesn't exist or in not valid), the
392 return value is NULL.
393 Else, the return value is a unzFile Handle, usable with other function
394 of this unzip package.
395 */
396 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
397 const char *path;
398 zlib_filefunc_def* pzlib_filefunc_def;
399 {
400 unz_s us;
401 unz_s *s;
402 uLong central_pos,uL;
403
404 uLong number_disk; /* number of the current dist, used for
405 spaning ZIP, unsupported, always 0*/
406 uLong number_disk_with_CD; /* number the the disk with central dir, used
407 for spaning ZIP, unsupported, always 0*/
408 uLong number_entry_CD; /* total number of entries in
409 the central dir
410 (same than number_entry on nospan) */
411
412 int err=UNZ_OK;
413
414 if (unz_copyright[0]!=' ')
415 return NULL;
416
417 if (pzlib_filefunc_def==NULL)
418 fill_fopen_filefunc(&us.z_filefunc);
419 else
420 us.z_filefunc = *pzlib_filefunc_def;
421
422 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
423 path,
424 ZLIB_FILEFUNC_MODE_READ |
425 ZLIB_FILEFUNC_MODE_EXISTING);
426 if (us.filestream==NULL)
427 return NULL;
428
429 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
430 if (central_pos==0)
431 err=UNZ_ERRNO;
432
433 if (ZSEEK(us.z_filefunc, us.filestream,
434 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
435 err=UNZ_ERRNO;
436
437 /* the signature, already checked */
438 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
439 err=UNZ_ERRNO;
440
441 /* number of this disk */
442 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
443 err=UNZ_ERRNO;
444
445 /* number of the disk with the start of the central directory */
446 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
447 err=UNZ_ERRNO;
448
449 /* total number of entries in the central dir on this disk */
450 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
451 err=UNZ_ERRNO;
452
453 /* total number of entries in the central dir */
454 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
455 err=UNZ_ERRNO;
456
457 if ((number_entry_CD!=us.gi.number_entry) ||
458 (number_disk_with_CD!=0) ||
459 (number_disk!=0))
460 err=UNZ_BADZIPFILE;
461
462 /* size of the central directory */
463 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
464 err=UNZ_ERRNO;
465
466 /* offset of start of central directory with respect to the
467 starting disk number */
468 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
469 err=UNZ_ERRNO;
470
471 /* zipfile comment length */
472 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
473 err=UNZ_ERRNO;
474
475 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
476 (err==UNZ_OK))
477 err=UNZ_BADZIPFILE;
478
479 if (err!=UNZ_OK)
480 {
481 ZCLOSE(us.z_filefunc, us.filestream);
482 return NULL;
483 }
484
485 us.byte_before_the_zipfile = central_pos -
486 (us.offset_central_dir+us.size_central_dir);
487 us.central_pos = central_pos;
488 us.pfile_in_zip_read = NULL;
489 us.encrypted = 0;
490
491
492 s=(unz_s*)ALLOC(sizeof(unz_s));
493 *s=us;
494 unzGoToFirstFile((unzFile)s);
495 return (unzFile)s;
496 }
497
498
499 extern unzFile ZEXPORT unzOpen (path)
500 const char *path;
501 {
502 return unzOpen2(path, NULL);
503 }
504
505 /*
506 Close a ZipFile opened with unzipOpen.
507 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
508 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
509 return UNZ_OK if there is no problem. */
510 extern int ZEXPORT unzClose (file)
511 unzFile file;
512 {
513 unz_s* s;
514 if (file==NULL)
515 return UNZ_PARAMERROR;
516 s=(unz_s*)file;
517
518 if (s->pfile_in_zip_read!=NULL)
519 unzCloseCurrentFile(file);
520
521 ZCLOSE(s->z_filefunc, s->filestream);
522 TRYFREE(s);
523 return UNZ_OK;
524 }
525
526
527 /*
528 Write info about the ZipFile in the *pglobal_info structure.
529 No preparation of the structure is needed
530 return UNZ_OK if there is no problem. */
531 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
532 unzFile file;
533 unz_global_info *pglobal_info;
534 {
535 unz_s* s;
536 if (file==NULL)
537 return UNZ_PARAMERROR;
538 s=(unz_s*)file;
539 *pglobal_info=s->gi;
540 return UNZ_OK;
541 }
542
543
544 /*
545 Translate date/time from Dos format to tm_unz (readable more easilty)
546 */
547 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
548 uLong ulDosDate;
549 tm_unz* ptm;
550 {
551 uLong uDate;
552 uDate = (uLong)(ulDosDate>>16);
553 ptm->tm_mday = (uInt)(uDate&0x1f) ;
554 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
555 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
556
557 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
558 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
559 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
560 }
561
562 /*
563 Get Info about the current file in the zipfile, with internal only info
564 */
565 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
566 unz_file_info *pfile_info,
567 unz_file_info_internal
568 *pfile_info_internal,
569 char *szFileName,
570 uLong fileNameBufferSize,
571 void *extraField,
572 uLong extraFieldBufferSize,
573 char *szComment,
574 uLong commentBufferSize));
575
576 local int unzlocal_GetCurrentFileInfoInternal (file,
577 pfile_info,
578 pfile_info_internal,
579 szFileName, fileNameBufferSize,
580 extraField, extraFieldBufferSize,
581 szComment, commentBufferSize)
582 unzFile file;
583 unz_file_info *pfile_info;
584 unz_file_info_internal *pfile_info_internal;
585 char *szFileName;
586 uLong fileNameBufferSize;
587 void *extraField;
588 uLong extraFieldBufferSize;
589 char *szComment;
590 uLong commentBufferSize;
591 {
592 unz_s* s;
593 unz_file_info file_info;
594 unz_file_info_internal file_info_internal;
595 int err=UNZ_OK;
596 uLong uMagic;
597 long lSeek=0;
598
599 if (file==NULL)
600 return UNZ_PARAMERROR;
601 s=(unz_s*)file;
602 if (ZSEEK(s->z_filefunc, s->filestream,
603 s->pos_in_central_dir+s->byte_before_the_zipfile,
604 ZLIB_FILEFUNC_SEEK_SET)!=0)
605 err=UNZ_ERRNO;
606
607
608 /* we check the magic */
609 if (err==UNZ_OK)
610 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
611 err=UNZ_ERRNO;
612 else if (uMagic!=0x02014b50)
613 err=UNZ_BADZIPFILE;
614
615 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
616 err=UNZ_ERRNO;
617
618 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
619 err=UNZ_ERRNO;
620
621 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
622 err=UNZ_ERRNO;
623
624 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
625 err=UNZ_ERRNO;
626
627 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
628 err=UNZ_ERRNO;
629
630 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
631
632 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
633 err=UNZ_ERRNO;
634
635 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
636 err=UNZ_ERRNO;
637
638 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
639 err=UNZ_ERRNO;
640
641 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
642 err=UNZ_ERRNO;
643
644 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
645 err=UNZ_ERRNO;
646
647 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
648 err=UNZ_ERRNO;
649
650 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
651 err=UNZ_ERRNO;
652
653 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
654 err=UNZ_ERRNO;
655
656 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
657 err=UNZ_ERRNO;
658
659 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
660 err=UNZ_ERRNO;
661
662 lSeek+=file_info.size_filename;
663 if ((err==UNZ_OK) && (szFileName!=NULL))
664 {
665 uLong uSizeRead ;
666 if (file_info.size_filename<fileNameBufferSize)
667 {
668 *(szFileName+file_info.size_filename)='\0';
669 uSizeRead = file_info.size_filename;
670 }
671 else
672 uSizeRead = fileNameBufferSize;
673
674 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
675 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
676 err=UNZ_ERRNO;
677 lSeek -= uSizeRead;
678 }
679
680
681 if ((err==UNZ_OK) && (extraField!=NULL))
682 {
683 uLong uSizeRead ;
684 if (file_info.size_file_extra<extraFieldBufferSize)
685 uSizeRead = file_info.size_file_extra;
686 else
687 uSizeRead = extraFieldBufferSize;
688
689 if (lSeek!=0)
690 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
691 lSeek=0;
692 else
693 err=UNZ_ERRNO;
694 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
695 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
696 err=UNZ_ERRNO;
697 lSeek += file_info.size_file_extra - uSizeRead;
698 }
699 else
700 lSeek+=file_info.size_file_extra;
701
702
703 if ((err==UNZ_OK) && (szComment!=NULL))
704 {
705 uLong uSizeRead ;
706 if (file_info.size_file_comment<commentBufferSize)
707 {
708 *(szComment+file_info.size_file_comment)='\0';
709 uSizeRead = file_info.size_file_comment;
710 }
711 else
712 uSizeRead = commentBufferSize;
713
714 if (lSeek!=0)
715 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
716 lSeek=0;
717 else
718 err=UNZ_ERRNO;
719 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
720 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
721 err=UNZ_ERRNO;
722 lSeek+=file_info.size_file_comment - uSizeRead;
723 }
724 else
725 lSeek+=file_info.size_file_comment;
726
727 if ((err==UNZ_OK) && (pfile_info!=NULL))
728 *pfile_info=file_info;
729
730 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
731 *pfile_info_internal=file_info_internal;
732
733 return err;
734 }
735
736
737
738 /*
739 Write info about the ZipFile in the *pglobal_info structure.
740 No preparation of the structure is needed
741 return UNZ_OK if there is no problem.
742 */
743 extern int ZEXPORT unzGetCurrentFileInfo (file,
744 pfile_info,
745 szFileName, fileNameBufferSize,
746 extraField, extraFieldBufferSize,
747 szComment, commentBufferSize)
748 unzFile file;
749 unz_file_info *pfile_info;
750 char *szFileName;
751 uLong fileNameBufferSize;
752 void *extraField;
753 uLong extraFieldBufferSize;
754 char *szComment;
755 uLong commentBufferSize;
756 {
757 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
758 szFileName,fileNameBufferSize,
759 extraField,extraFieldBufferSize,
760 szComment,commentBufferSize);
761 }
762
763 /*
764 Set the current file of the zipfile to the first file.
765 return UNZ_OK if there is no problem
766 */
767 extern int ZEXPORT unzGoToFirstFile (file)
768 unzFile file;
769 {
770 int err=UNZ_OK;
771 unz_s* s;
772 if (file==NULL)
773 return UNZ_PARAMERROR;
774 s=(unz_s*)file;
775 s->pos_in_central_dir=s->offset_central_dir;
776 s->num_file=0;
777 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
778 &s->cur_file_info_internal,
779 NULL,0,NULL,0,NULL,0);
780 s->current_file_ok = (err == UNZ_OK);
781 return err;
782 }
783
784 /*
785 Set the current file of the zipfile to the next file.
786 return UNZ_OK if there is no problem
787 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
788 */
789 extern int ZEXPORT unzGoToNextFile (file)
790 unzFile file;
791 {
792 unz_s* s;
793 int err;
794
795 if (file==NULL)
796 return UNZ_PARAMERROR;
797 s=(unz_s*)file;
798 if (!s->current_file_ok)
799 return UNZ_END_OF_LIST_OF_FILE;
800 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
801 if (s->num_file+1==s->gi.number_entry)
802 return UNZ_END_OF_LIST_OF_FILE;
803
804 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
805 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
806 s->num_file++;
807 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
808 &s->cur_file_info_internal,
809 NULL,0,NULL,0,NULL,0);
810 s->current_file_ok = (err == UNZ_OK);
811 return err;
812 }
813
814
815 /*
816 Try locate the file szFileName in the zipfile.
817 For the iCaseSensitivity signification, see unzipStringFileNameCompare
818
819 return value :
820 UNZ_OK if the file is found. It becomes the current file.
821 UNZ_END_OF_LIST_OF_FILE if the file is not found
822 */
823 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
824 unzFile file;
825 const char *szFileName;
826 int iCaseSensitivity;
827 {
828 unz_s* s;
829 int err;
830
831 /* We remember the 'current' position in the file so that we can jump
832 * back there if we fail.
833 */
834 unz_file_info cur_file_infoSaved;
835 unz_file_info_internal cur_file_info_internalSaved;
836 uLong num_fileSaved;
837 uLong pos_in_central_dirSaved;
838
839
840 if (file==NULL)
841 return UNZ_PARAMERROR;
842
843 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
844 return UNZ_PARAMERROR;
845
846 s=(unz_s*)file;
847 if (!s->current_file_ok)
848 return UNZ_END_OF_LIST_OF_FILE;
849
850 /* Save the current state */
851 num_fileSaved = s->num_file;
852 pos_in_central_dirSaved = s->pos_in_central_dir;
853 cur_file_infoSaved = s->cur_file_info;
854 cur_file_info_internalSaved = s->cur_file_info_internal;
855
856 err = unzGoToFirstFile(file);
857
858 while (err == UNZ_OK)
859 {
860 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
861 err = unzGetCurrentFileInfo(file,NULL,
862 szCurrentFileName,sizeof(szCurrentFileName)-1,
863 NULL,0,NULL,0);
864 if (err == UNZ_OK)
865 {
866 if (unzStringFileNameCompare(szCurrentFileName,
867 szFileName,iCaseSensitivity)==0)
868 return UNZ_OK;
869 err = unzGoToNextFile(file);
870 }
871 }
872
873 /* We failed, so restore the state of the 'current file' to where we
874 * were.
875 */
876 s->num_file = num_fileSaved ;
877 s->pos_in_central_dir = pos_in_central_dirSaved ;
878 s->cur_file_info = cur_file_infoSaved;
879 s->cur_file_info_internal = cur_file_info_internalSaved;
880 return err;
881 }
882
883
884 /*
885 ///////////////////////////////////////////
886 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
887 // I need random access
888 //
889 // Further optimization could be realized by adding an ability
890 // to cache the directory in memory. The goal being a single
891 // comprehensive file read to put the file I need in a memory.
892 */
893
894 /*
895 typedef struct unz_file_pos_s
896 {
897 uLong pos_in_zip_directory; // offset in file
898 uLong num_of_file; // # of file
899 } unz_file_pos;
900 */
901
902 extern int ZEXPORT unzGetFilePos(file, file_pos)
903 unzFile file;
904 unz_file_pos* file_pos;
905 {
906 unz_s* s;
907
908 if (file==NULL || file_pos==NULL)
909 return UNZ_PARAMERROR;
910 s=(unz_s*)file;
911 if (!s->current_file_ok)
912 return UNZ_END_OF_LIST_OF_FILE;
913
914 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
915 file_pos->num_of_file = s->num_file;
916
917 return UNZ_OK;
918 }
919
920 extern int ZEXPORT unzGoToFilePos(file, file_pos)
921 unzFile file;
922 unz_file_pos* file_pos;
923 {
924 unz_s* s;
925 int err;
926
927 if (file==NULL || file_pos==NULL)
928 return UNZ_PARAMERROR;
929 s=(unz_s*)file;
930
931 /* jump to the right spot */
932 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
933 s->num_file = file_pos->num_of_file;
934
935 /* set the current file */
936 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
937 &s->cur_file_info_internal,
938 NULL,0,NULL,0,NULL,0);
939 /* return results */
940 s->current_file_ok = (err == UNZ_OK);
941 return err;
942 }
943
944 /*
945 // Unzip Helper Functions - should be here?
946 ///////////////////////////////////////////
947 */
948
949 /*
950 Read the local header of the current zipfile
951 Check the coherency of the local header and info in the end of central
952 directory about this file
953 store in *piSizeVar the size of extra info in local header
954 (filename and size of extra field data)
955 */
956 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
957 poffset_local_extrafield,
958 psize_local_extrafield)
959 unz_s* s;
960 uInt* piSizeVar;
961 uLong *poffset_local_extrafield;
962 uInt *psize_local_extrafield;
963 {
964 uLong uMagic,uData,uFlags;
965 uLong size_filename;
966 uLong size_extra_field;
967 int err=UNZ_OK;
968
969 *piSizeVar = 0;
970 *poffset_local_extrafield = 0;
971 *psize_local_extrafield = 0;
972
973 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
974 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
975 return UNZ_ERRNO;
976
977
978 if (err==UNZ_OK)
979 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
980 err=UNZ_ERRNO;
981 else if (uMagic!=0x04034b50)
982 err=UNZ_BADZIPFILE;
983
984 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
985 err=UNZ_ERRNO;
986 /*
987 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
988 err=UNZ_BADZIPFILE;
989 */
990 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
991 err=UNZ_ERRNO;
992
993 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
994 err=UNZ_ERRNO;
995 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
996 err=UNZ_BADZIPFILE;
997
998 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
999 (s->cur_file_info.compression_method!=Z_DEFLATED))
1000 err=UNZ_BADZIPFILE;
1001
1002 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1003 err=UNZ_ERRNO;
1004
1005 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1006 err=UNZ_ERRNO;
1007 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1008 ((uFlags & 8)==0))
1009 err=UNZ_BADZIPFILE;
1010
1011 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1012 err=UNZ_ERRNO;
1013 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1014 ((uFlags & 8)==0))
1015 err=UNZ_BADZIPFILE;
1016
1017 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1018 err=UNZ_ERRNO;
1019 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1020 ((uFlags & 8)==0))
1021 err=UNZ_BADZIPFILE;
1022
1023
1024 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1025 err=UNZ_ERRNO;
1026 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1027 err=UNZ_BADZIPFILE;
1028
1029 *piSizeVar += (uInt)size_filename;
1030
1031 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1032 err=UNZ_ERRNO;
1033 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1034 SIZEZIPLOCALHEADER + size_filename;
1035 *psize_local_extrafield = (uInt)size_extra_field;
1036
1037 *piSizeVar += (uInt)size_extra_field;
1038
1039 return err;
1040 }
1041
1042 /*
1043 Open for reading data the current file in the zipfile.
1044 If there is no error and the file is opened, the return value is UNZ_OK.
1045 */
1046 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1047 unzFile file;
1048 int* method;
1049 int* level;
1050 int raw;
1051 const char* password;
1052 {
1053 int err=UNZ_OK;
1054 uInt iSizeVar;
1055 unz_s* s;
1056 file_in_zip_read_info_s* pfile_in_zip_read_info;
1057 uLong offset_local_extrafield; /* offset of the local extra field */
1058 uInt size_local_extrafield; /* size of the local extra field */
1059 # ifndef NOUNCRYPT
1060 char source[12];
1061 # else
1062 if (password != NULL)
1063 return UNZ_PARAMERROR;
1064 # endif
1065
1066 if (file==NULL)
1067 return UNZ_PARAMERROR;
1068 s=(unz_s*)file;
1069 if (!s->current_file_ok)
1070 return UNZ_PARAMERROR;
1071
1072 if (s->pfile_in_zip_read != NULL)
1073 unzCloseCurrentFile(file);
1074
1075 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1076 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1077 return UNZ_BADZIPFILE;
1078
1079 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1080 ALLOC(sizeof(file_in_zip_read_info_s));
1081 if (pfile_in_zip_read_info==NULL)
1082 return UNZ_INTERNALERROR;
1083
1084 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1085 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1086 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1087 pfile_in_zip_read_info->pos_local_extrafield=0;
1088 pfile_in_zip_read_info->raw=raw;
1089
1090 if (pfile_in_zip_read_info->read_buffer==NULL)
1091 {
1092 TRYFREE(pfile_in_zip_read_info);
1093 return UNZ_INTERNALERROR;
1094 }
1095
1096 pfile_in_zip_read_info->stream_initialised=0;
1097
1098 if (method!=NULL)
1099 *method = (int)s->cur_file_info.compression_method;
1100
1101 if (level!=NULL)
1102 {
1103 *level = 6;
1104 switch (s->cur_file_info.flag & 0x06)
1105 {
1106 case 6 : *level = 1; break;
1107 case 4 : *level = 2; break;
1108 case 2 : *level = 9; break;
1109 }
1110 }
1111
1112 if ((s->cur_file_info.compression_method!=0) &&
1113 (s->cur_file_info.compression_method!=Z_DEFLATED))
1114 err=UNZ_BADZIPFILE;
1115
1116 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1117 pfile_in_zip_read_info->crc32=0;
1118 pfile_in_zip_read_info->compression_method =
1119 s->cur_file_info.compression_method;
1120 pfile_in_zip_read_info->filestream=s->filestream;
1121 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1122 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1123
1124 pfile_in_zip_read_info->stream.total_out = 0;
1125
1126 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1127 (!raw))
1128 {
1129 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1130 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1131 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1132 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1133 pfile_in_zip_read_info->stream.avail_in = 0;
1134
1135 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1136 if (err == Z_OK)
1137 pfile_in_zip_read_info->stream_initialised=1;
1138 else
1139 return err;
1140 /* windowBits is passed < 0 to tell that there is no zlib header.
1141 * Note that in this case inflate *requires* an extra "dummy" byte
1142 * after the compressed stream in order to complete decompression and
1143 * return Z_STREAM_END.
1144 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1145 * size of both compressed and uncompressed data
1146 */
1147 }
1148 pfile_in_zip_read_info->rest_read_compressed =
1149 s->cur_file_info.compressed_size ;
1150 pfile_in_zip_read_info->rest_read_uncompressed =
1151 s->cur_file_info.uncompressed_size ;
1152
1153
1154 pfile_in_zip_read_info->pos_in_zipfile =
1155 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1156 iSizeVar;
1157
1158 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1159
1160 s->pfile_in_zip_read = pfile_in_zip_read_info;
1161
1162 # ifndef NOUNCRYPT
1163 if (password != NULL)
1164 {
1165 int i;
1166 s->pcrc_32_tab = get_crc_table();
1167 init_keys(password,s->keys,s->pcrc_32_tab);
1168 if (ZSEEK(s->z_filefunc, s->filestream,
1169 s->pfile_in_zip_read->pos_in_zipfile +
1170 s->pfile_in_zip_read->byte_before_the_zipfile,
1171 SEEK_SET)!=0)
1172 return UNZ_INTERNALERROR;
1173 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1174 return UNZ_INTERNALERROR;
1175
1176 for (i = 0; i<12; i++)
1177 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1178
1179 s->pfile_in_zip_read->pos_in_zipfile+=12;
1180 s->encrypted=1;
1181 }
1182 # endif
1183
1184
1185 return UNZ_OK;
1186 }
1187
1188 extern int ZEXPORT unzOpenCurrentFile (file)
1189 unzFile file;
1190 {
1191 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1192 }
1193
1194 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1195 unzFile file;
1196 const char* password;
1197 {
1198 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1199 }
1200
1201 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1202 unzFile file;
1203 int* method;
1204 int* level;
1205 int raw;
1206 {
1207 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1208 }
1209
1210 /*
1211 Read bytes from the current file.
1212 buf contain buffer where data must be copied
1213 len the size of buf.
1214
1215 return the number of byte copied if somes bytes are copied
1216 return 0 if the end of file was reached
1217 return <0 with error code if there is an error
1218 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1219 */
1220 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1221 unzFile file;
1222 voidp buf;
1223 unsigned len;
1224 {
1225 int err=UNZ_OK;
1226 uInt iRead = 0;
1227 unz_s* s;
1228 file_in_zip_read_info_s* pfile_in_zip_read_info;
1229 if (file==NULL)
1230 return UNZ_PARAMERROR;
1231 s=(unz_s*)file;
1232 pfile_in_zip_read_info=s->pfile_in_zip_read;
1233
1234 if (pfile_in_zip_read_info==NULL)
1235 return UNZ_PARAMERROR;
1236
1237
1238 if ((pfile_in_zip_read_info->read_buffer == NULL))
1239 return UNZ_END_OF_LIST_OF_FILE;
1240 if (len==0)
1241 return 0;
1242
1243 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1244
1245 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1246
1247 if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1248 (!(pfile_in_zip_read_info->raw)))
1249 pfile_in_zip_read_info->stream.avail_out =
1250 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1251
1252 if ((len>pfile_in_zip_read_info->rest_read_compressed+
1253 pfile_in_zip_read_info->stream.avail_in) &&
1254 (pfile_in_zip_read_info->raw))
1255 pfile_in_zip_read_info->stream.avail_out =
1256 (uInt)pfile_in_zip_read_info->rest_read_compressed+
1257 pfile_in_zip_read_info->stream.avail_in;
1258
1259 while (pfile_in_zip_read_info->stream.avail_out>0)
1260 {
1261 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1262 (pfile_in_zip_read_info->rest_read_compressed>0))
1263 {
1264 uInt uReadThis = UNZ_BUFSIZE;
1265 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1266 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1267 if (uReadThis == 0)
1268 return UNZ_EOF;
1269 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1270 pfile_in_zip_read_info->filestream,
1271 pfile_in_zip_read_info->pos_in_zipfile +
1272 pfile_in_zip_read_info->byte_before_the_zipfile,
1273 ZLIB_FILEFUNC_SEEK_SET)!=0)
1274 return UNZ_ERRNO;
1275 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1276 pfile_in_zip_read_info->filestream,
1277 pfile_in_zip_read_info->read_buffer,
1278 uReadThis)!=uReadThis)
1279 return UNZ_ERRNO;
1280
1281
1282 # ifndef NOUNCRYPT
1283 if(s->encrypted)
1284 {
1285 uInt i;
1286 for(i=0;i<uReadThis;i++)
1287 pfile_in_zip_read_info->read_buffer[i] =
1288 zdecode(s->keys,s->pcrc_32_tab,
1289 pfile_in_zip_read_info->read_buffer[i]);
1290 }
1291 # endif
1292
1293
1294 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1295
1296 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1297
1298 pfile_in_zip_read_info->stream.next_in =
1299 (Bytef*)pfile_in_zip_read_info->read_buffer;
1300 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1301 }
1302
1303 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1304 {
1305 uInt uDoCopy,i ;
1306
1307 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1308 (pfile_in_zip_read_info->rest_read_compressed == 0))
1309 return (iRead==0) ? UNZ_EOF : iRead;
1310
1311 if (pfile_in_zip_read_info->stream.avail_out <
1312 pfile_in_zip_read_info->stream.avail_in)
1313 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1314 else
1315 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1316
1317 for (i=0;i<uDoCopy;i++)
1318 *(pfile_in_zip_read_info->stream.next_out+i) =
1319 *(pfile_in_zip_read_info->stream.next_in+i);
1320
1321 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1322 pfile_in_zip_read_info->stream.next_out,
1323 uDoCopy);
1324 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1325 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1326 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1327 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1328 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1329 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1330 iRead += uDoCopy;
1331 }
1332 else
1333 {
1334 uLong uTotalOutBefore,uTotalOutAfter;
1335 const Bytef *bufBefore;
1336 uLong uOutThis;
1337 int flush=Z_SYNC_FLUSH;
1338
1339 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1340 bufBefore = pfile_in_zip_read_info->stream.next_out;
1341
1342 /*
1343 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1344 pfile_in_zip_read_info->stream.avail_out) &&
1345 (pfile_in_zip_read_info->rest_read_compressed == 0))
1346 flush = Z_FINISH;
1347 */
1348 err=inflate(&pfile_in_zip_read_info->stream,flush);
1349
1350 if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1351 err = Z_DATA_ERROR;
1352
1353 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1354 uOutThis = uTotalOutAfter-uTotalOutBefore;
1355
1356 pfile_in_zip_read_info->crc32 =
1357 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1358 (uInt)(uOutThis));
1359
1360 pfile_in_zip_read_info->rest_read_uncompressed -=
1361 uOutThis;
1362
1363 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1364
1365 if (err==Z_STREAM_END)
1366 return (iRead==0) ? UNZ_EOF : iRead;
1367 if (err!=Z_OK)
1368 break;
1369 }
1370 }
1371
1372 if (err==Z_OK)
1373 return iRead;
1374 return err;
1375 }
1376
1377
1378 /*
1379 Give the current position in uncompressed data
1380 */
1381 extern z_off_t ZEXPORT unztell (file)
1382 unzFile file;
1383 {
1384 unz_s* s;
1385 file_in_zip_read_info_s* pfile_in_zip_read_info;
1386 if (file==NULL)
1387 return UNZ_PARAMERROR;
1388 s=(unz_s*)file;
1389 pfile_in_zip_read_info=s->pfile_in_zip_read;
1390
1391 if (pfile_in_zip_read_info==NULL)
1392 return UNZ_PARAMERROR;
1393
1394 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1395 }
1396
1397
1398 /*
1399 return 1 if the end of file was reached, 0 elsewhere
1400 */
1401 extern int ZEXPORT unzeof (file)
1402 unzFile file;
1403 {
1404 unz_s* s;
1405 file_in_zip_read_info_s* pfile_in_zip_read_info;
1406 if (file==NULL)
1407 return UNZ_PARAMERROR;
1408 s=(unz_s*)file;
1409 pfile_in_zip_read_info=s->pfile_in_zip_read;
1410
1411 if (pfile_in_zip_read_info==NULL)
1412 return UNZ_PARAMERROR;
1413
1414 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1415 return 1;
1416 else
1417 return 0;
1418 }
1419
1420
1421
1422 /*
1423 Read extra field from the current file (opened by unzOpenCurrentFile)
1424 This is the local-header version of the extra field (sometimes, there is
1425 more info in the local-header version than in the central-header)
1426
1427 if buf==NULL, it return the size of the local extra field that can be read
1428
1429 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1430 buf.
1431 the return value is the number of bytes copied in buf, or (if <0)
1432 the error code
1433 */
1434 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1435 unzFile file;
1436 voidp buf;
1437 unsigned len;
1438 {
1439 unz_s* s;
1440 file_in_zip_read_info_s* pfile_in_zip_read_info;
1441 uInt read_now;
1442 uLong size_to_read;
1443
1444 if (file==NULL)
1445 return UNZ_PARAMERROR;
1446 s=(unz_s*)file;
1447 pfile_in_zip_read_info=s->pfile_in_zip_read;
1448
1449 if (pfile_in_zip_read_info==NULL)
1450 return UNZ_PARAMERROR;
1451
1452 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1453 pfile_in_zip_read_info->pos_local_extrafield);
1454
1455 if (buf==NULL)
1456 return (int)size_to_read;
1457
1458 if (len>size_to_read)
1459 read_now = (uInt)size_to_read;
1460 else
1461 read_now = (uInt)len ;
1462
1463 if (read_now==0)
1464 return 0;
1465
1466 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1467 pfile_in_zip_read_info->filestream,
1468 pfile_in_zip_read_info->offset_local_extrafield +
1469 pfile_in_zip_read_info->pos_local_extrafield,
1470 ZLIB_FILEFUNC_SEEK_SET)!=0)
1471 return UNZ_ERRNO;
1472
1473 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1474 pfile_in_zip_read_info->filestream,
1475 buf,read_now)!=read_now)
1476 return UNZ_ERRNO;
1477
1478 return (int)read_now;
1479 }
1480
1481 /*
1482 Close the file in zip opened with unzipOpenCurrentFile
1483 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1484 */
1485 extern int ZEXPORT unzCloseCurrentFile (file)
1486 unzFile file;
1487 {
1488 int err=UNZ_OK;
1489
1490 unz_s* s;
1491 file_in_zip_read_info_s* pfile_in_zip_read_info;
1492 if (file==NULL)
1493 return UNZ_PARAMERROR;
1494 s=(unz_s*)file;
1495 pfile_in_zip_read_info=s->pfile_in_zip_read;
1496
1497 if (pfile_in_zip_read_info==NULL)
1498 return UNZ_PARAMERROR;
1499
1500
1501 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1502 (!pfile_in_zip_read_info->raw))
1503 {
1504 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1505 err=UNZ_CRCERROR;
1506 }
1507
1508
1509 TRYFREE(pfile_in_zip_read_info->read_buffer);
1510 pfile_in_zip_read_info->read_buffer = NULL;
1511 if (pfile_in_zip_read_info->stream_initialised)
1512 inflateEnd(&pfile_in_zip_read_info->stream);
1513
1514 pfile_in_zip_read_info->stream_initialised = 0;
1515 TRYFREE(pfile_in_zip_read_info);
1516
1517 s->pfile_in_zip_read=NULL;
1518
1519 return err;
1520 }
1521
1522
1523 /*
1524 Get the global comment string of the ZipFile, in the szComment buffer.
1525 uSizeBuf is the size of the szComment buffer.
1526 return the number of byte copied or an error code <0
1527 */
1528 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1529 unzFile file;
1530 char *szComment;
1531 uLong uSizeBuf;
1532 {
1533 int err=UNZ_OK;
1534 unz_s* s;
1535 uLong uReadThis ;
1536 if (file==NULL)
1537 return UNZ_PARAMERROR;
1538 s=(unz_s*)file;
1539
1540 uReadThis = uSizeBuf;
1541 if (uReadThis>s->gi.size_comment)
1542 uReadThis = s->gi.size_comment;
1543
1544 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1545 return UNZ_ERRNO;
1546
1547 if (uReadThis>0)
1548 {
1549 *szComment='\0';
1550 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1551 return UNZ_ERRNO;
1552 }
1553
1554 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1555 *(szComment+s->gi.size_comment)='\0';
1556 return (int)uReadThis;
1557 }
1558
1559 /* Additions by RX '2004 */
1560 extern uLong ZEXPORT unzGetOffset (file)
1561 unzFile file;
1562 {
1563 unz_s* s;
1564
1565 if (file==NULL)
1566 return UNZ_PARAMERROR;
1567 s=(unz_s*)file;
1568 if (!s->current_file_ok)
1569 return 0;
1570 if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
1571 if (s->num_file==s->gi.number_entry)
1572 return 0;
1573 return s->pos_in_central_dir;
1574 }
1575
1576 extern int ZEXPORT unzSetOffset (file, pos)
1577 unzFile file;
1578 uLong pos;
1579 {
1580 unz_s* s;
1581 int err;
1582
1583 if (file==NULL)
1584 return UNZ_PARAMERROR;
1585 s=(unz_s*)file;
1586
1587 s->pos_in_central_dir = pos;
1588 s->num_file = s->gi.number_entry; /* hack */
1589 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1590 &s->cur_file_info_internal,
1591 NULL,0,NULL,0,NULL,0);
1592 s->current_file_ok = (err == UNZ_OK);
1593 return err;
1594 }
0 /* unzip.h -- IO for uncompress .zip files using zlib
1 Version 1.01, May 8th, 2004
2
3 Copyright (C) 1998-2004 Gilles Vollant
4
5 This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
6 WinZip, InfoZip tools and compatible.
7 Encryption and multi volume ZipFile (span) are not supported.
8 Old compressions used by old PKZip 1.x are not supported
9
10
11 I WAIT FEEDBACK at mail info@winimage.com
12 Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
13
14 Condition of use and distribution are the same than zlib :
15
16 This software is provided 'as-is', without any express or implied
17 warranty. In no event will the authors be held liable for any damages
18 arising from the use of this software.
19
20 Permission is granted to anyone to use this software for any purpose,
21 including commercial applications, and to alter it and redistribute it
22 freely, subject to the following restrictions:
23
24 1. The origin of this software must not be misrepresented; you must not
25 claim that you wrote the original software. If you use this software
26 in a product, an acknowledgment in the product documentation would be
27 appreciated but is not required.
28 2. Altered source versions must be plainly marked as such, and must not be
29 misrepresented as being the original software.
30 3. This notice may not be removed or altered from any source distribution.
31
32
33 */
34
35 /* for more info about .ZIP format, see
36 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
37 http://www.info-zip.org/pub/infozip/doc/
38 PkWare has also a specification at :
39 ftp://ftp.pkware.com/probdesc.zip
40 */
41
42 #ifndef _unz_H
43 #define _unz_H
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 #ifndef _ZLIB_H
50 #include "zlib.h"
51 #endif
52
53 #ifndef _ZLIBIOAPI_H
54 #include "ioapi.h"
55 #endif
56
57 #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
58 /* like the STRICT of WIN32, we define a pointer that cannot be converted
59 from (void*) without cast */
60 typedef struct TagunzFile__ { int unused; } unzFile__;
61 typedef unzFile__ *unzFile;
62 #else
63 typedef voidp unzFile;
64 #endif
65
66
67 #define UNZ_OK (0)
68 #define UNZ_END_OF_LIST_OF_FILE (-100)
69 #define UNZ_ERRNO (Z_ERRNO)
70 #define UNZ_EOF (0)
71 #define UNZ_PARAMERROR (-102)
72 #define UNZ_BADZIPFILE (-103)
73 #define UNZ_INTERNALERROR (-104)
74 #define UNZ_CRCERROR (-105)
75
76 /* tm_unz contain date/time info */
77 typedef struct tm_unz_s
78 {
79 uInt tm_sec; /* seconds after the minute - [0,59] */
80 uInt tm_min; /* minutes after the hour - [0,59] */
81 uInt tm_hour; /* hours since midnight - [0,23] */
82 uInt tm_mday; /* day of the month - [1,31] */
83 uInt tm_mon; /* months since January - [0,11] */
84 uInt tm_year; /* years - [1980..2044] */
85 } tm_unz;
86
87 /* unz_global_info structure contain global data about the ZIPfile
88 These data comes from the end of central dir */
89 typedef struct unz_global_info_s
90 {
91 uLong number_entry; /* total number of entries in
92 the central dir on this disk */
93 uLong size_comment; /* size of the global comment of the zipfile */
94 } unz_global_info;
95
96
97 /* unz_file_info contain information about a file in the zipfile */
98 typedef struct unz_file_info_s
99 {
100 uLong version; /* version made by 2 bytes */
101 uLong version_needed; /* version needed to extract 2 bytes */
102 uLong flag; /* general purpose bit flag 2 bytes */
103 uLong compression_method; /* compression method 2 bytes */
104 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
105 uLong crc; /* crc-32 4 bytes */
106 uLong compressed_size; /* compressed size 4 bytes */
107 uLong uncompressed_size; /* uncompressed size 4 bytes */
108 uLong size_filename; /* filename length 2 bytes */
109 uLong size_file_extra; /* extra field length 2 bytes */
110 uLong size_file_comment; /* file comment length 2 bytes */
111
112 uLong disk_num_start; /* disk number start 2 bytes */
113 uLong internal_fa; /* internal file attributes 2 bytes */
114 uLong external_fa; /* external file attributes 4 bytes */
115
116 tm_unz tmu_date;
117 } unz_file_info;
118
119 extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
120 const char* fileName2,
121 int iCaseSensitivity));
122 /*
123 Compare two filename (fileName1,fileName2).
124 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
125 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
126 or strcasecmp)
127 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
128 (like 1 on Unix, 2 on Windows)
129 */
130
131
132 extern unzFile ZEXPORT unzOpen OF((const char *path));
133 /*
134 Open a Zip file. path contain the full pathname (by example,
135 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
136 "zlib/zlib113.zip".
137 If the zipfile cannot be opened (file don't exist or in not valid), the
138 return value is NULL.
139 Else, the return value is a unzFile Handle, usable with other function
140 of this unzip package.
141 */
142
143 extern unzFile ZEXPORT unzOpen2 OF((const char *path,
144 zlib_filefunc_def* pzlib_filefunc_def));
145 /*
146 Open a Zip file, like unzOpen, but provide a set of file low level API
147 for read/write the zip file (see ioapi.h)
148 */
149
150 extern int ZEXPORT unzClose OF((unzFile file));
151 /*
152 Close a ZipFile opened with unzipOpen.
153 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
154 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
155 return UNZ_OK if there is no problem. */
156
157 extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
158 unz_global_info *pglobal_info));
159 /*
160 Write info about the ZipFile in the *pglobal_info structure.
161 No preparation of the structure is needed
162 return UNZ_OK if there is no problem. */
163
164
165 extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
166 char *szComment,
167 uLong uSizeBuf));
168 /*
169 Get the global comment string of the ZipFile, in the szComment buffer.
170 uSizeBuf is the size of the szComment buffer.
171 return the number of byte copied or an error code <0
172 */
173
174
175 /***************************************************************************/
176 /* Unzip package allow you browse the directory of the zipfile */
177
178 extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
179 /*
180 Set the current file of the zipfile to the first file.
181 return UNZ_OK if there is no problem
182 */
183
184 extern int ZEXPORT unzGoToNextFile OF((unzFile file));
185 /*
186 Set the current file of the zipfile to the next file.
187 return UNZ_OK if there is no problem
188 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
189 */
190
191 extern int ZEXPORT unzLocateFile OF((unzFile file,
192 const char *szFileName,
193 int iCaseSensitivity));
194 /*
195 Try locate the file szFileName in the zipfile.
196 For the iCaseSensitivity signification, see unzStringFileNameCompare
197
198 return value :
199 UNZ_OK if the file is found. It becomes the current file.
200 UNZ_END_OF_LIST_OF_FILE if the file is not found
201 */
202
203
204 /* ****************************************** */
205 /* Ryan supplied functions */
206 /* unz_file_info contain information about a file in the zipfile */
207 typedef struct unz_file_pos_s
208 {
209 uLong pos_in_zip_directory; /* offset in zip file directory */
210 uLong num_of_file; /* # of file */
211 } unz_file_pos;
212
213 extern int ZEXPORT unzGetFilePos(
214 unzFile file,
215 unz_file_pos* file_pos);
216
217 extern int ZEXPORT unzGoToFilePos(
218 unzFile file,
219 unz_file_pos* file_pos);
220
221 /* ****************************************** */
222
223 extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
224 unz_file_info *pfile_info,
225 char *szFileName,
226 uLong fileNameBufferSize,
227 void *extraField,
228 uLong extraFieldBufferSize,
229 char *szComment,
230 uLong commentBufferSize));
231 /*
232 Get Info about the current file
233 if pfile_info!=NULL, the *pfile_info structure will contain somes info about
234 the current file
235 if szFileName!=NULL, the filemane string will be copied in szFileName
236 (fileNameBufferSize is the size of the buffer)
237 if extraField!=NULL, the extra field information will be copied in extraField
238 (extraFieldBufferSize is the size of the buffer).
239 This is the Central-header version of the extra field
240 if szComment!=NULL, the comment string of the file will be copied in szComment
241 (commentBufferSize is the size of the buffer)
242 */
243
244 /***************************************************************************/
245 /* for reading the content of the current zipfile, you can open it, read data
246 from it, and close it (you can close it before reading all the file)
247 */
248
249 extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
250 /*
251 Open for reading data the current file in the zipfile.
252 If there is no error, the return value is UNZ_OK.
253 */
254
255 extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
256 const char* password));
257 /*
258 Open for reading data the current file in the zipfile.
259 password is a crypting password
260 If there is no error, the return value is UNZ_OK.
261 */
262
263 extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
264 int* method,
265 int* level,
266 int raw));
267 /*
268 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
269 if raw==1
270 *method will receive method of compression, *level will receive level of
271 compression
272 note : you can set level parameter as NULL (if you did not want known level,
273 but you CANNOT set method parameter as NULL
274 */
275
276 extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
277 int* method,
278 int* level,
279 int raw,
280 const char* password));
281 /*
282 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
283 if raw==1
284 *method will receive method of compression, *level will receive level of
285 compression
286 note : you can set level parameter as NULL (if you did not want known level,
287 but you CANNOT set method parameter as NULL
288 */
289
290
291 extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
292 /*
293 Close the file in zip opened with unzOpenCurrentFile
294 Return UNZ_CRCERROR if all the file was read but the CRC is not good
295 */
296
297 extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
298 voidp buf,
299 unsigned len));
300 /*
301 Read bytes from the current file (opened by unzOpenCurrentFile)
302 buf contain buffer where data must be copied
303 len the size of buf.
304
305 return the number of byte copied if somes bytes are copied
306 return 0 if the end of file was reached
307 return <0 with error code if there is an error
308 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
309 */
310
311 extern z_off_t ZEXPORT unztell OF((unzFile file));
312 /*
313 Give the current position in uncompressed data
314 */
315
316 extern int ZEXPORT unzeof OF((unzFile file));
317 /*
318 return 1 if the end of file was reached, 0 elsewhere
319 */
320
321 extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
322 voidp buf,
323 unsigned len));
324 /*
325 Read extra field from the current file (opened by unzOpenCurrentFile)
326 This is the local-header version of the extra field (sometimes, there is
327 more info in the local-header version than in the central-header)
328
329 if buf==NULL, it return the size of the local extra field
330
331 if buf!=NULL, len is the size of the buffer, the extra header is copied in
332 buf.
333 the return value is the number of bytes copied in buf, or (if <0)
334 the error code
335 */
336
337 /***************************************************************************/
338
339 /* Get the current file offset */
340 extern uLong ZEXPORT unzGetOffset (unzFile file);
341
342 /* Set the current file offset */
343 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
344
345
346
347 #ifdef __cplusplus
348 }
349 #endif
350
351 #endif /* _unz_H */
0 /* zip.c -- IO on .zip files using zlib
1 Version 1.01, May 8th, 2004
2
3 Copyright (C) 1998-2004 Gilles Vollant
4
5 Read zip.h for more info
6 */
7
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13 #include "zlib.h"
14 #include "zip.h"
15
16 #ifdef STDC
17 # include <stddef.h>
18 # include <string.h>
19 # include <stdlib.h>
20 #endif
21 #ifdef NO_ERRNO_H
22 extern int errno;
23 #else
24 # include <errno.h>
25 #endif
26
27
28 #ifndef local
29 # define local static
30 #endif
31 /* compile with -Dlocal if your debugger can't find static symbols */
32
33 #ifndef VERSIONMADEBY
34 # define VERSIONMADEBY (0x0) /* platform depedent */
35 #endif
36
37 #ifndef Z_BUFSIZE
38 #define Z_BUFSIZE (16384)
39 #endif
40
41 #ifndef Z_MAXFILENAMEINZIP
42 #define Z_MAXFILENAMEINZIP (256)
43 #endif
44
45 #ifndef ALLOC
46 # define ALLOC(size) (malloc(size))
47 #endif
48 #ifndef TRYFREE
49 # define TRYFREE(p) {if (p) free(p);}
50 #endif
51
52 /*
53 #define SIZECENTRALDIRITEM (0x2e)
54 #define SIZEZIPLOCALHEADER (0x1e)
55 */
56
57 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
58
59 #ifndef SEEK_CUR
60 #define SEEK_CUR 1
61 #endif
62
63 #ifndef SEEK_END
64 #define SEEK_END 2
65 #endif
66
67 #ifndef SEEK_SET
68 #define SEEK_SET 0
69 #endif
70
71 #ifndef DEF_MEM_LEVEL
72 #if MAX_MEM_LEVEL >= 8
73 # define DEF_MEM_LEVEL 8
74 #else
75 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
76 #endif
77 #endif
78 const char zip_copyright[] =
79 " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
80
81
82 #define SIZEDATA_INDATABLOCK (4096-(4*4))
83
84 #define LOCALHEADERMAGIC (0x04034b50)
85 #define CENTRALHEADERMAGIC (0x02014b50)
86 #define ENDHEADERMAGIC (0x06054b50)
87
88 #define FLAG_LOCALHEADER_OFFSET (0x06)
89 #define CRC_LOCALHEADER_OFFSET (0x0e)
90
91 #define SIZECENTRALHEADER (0x2e) /* 46 */
92
93 typedef struct linkedlist_datablock_internal_s
94 {
95 struct linkedlist_datablock_internal_s* next_datablock;
96 uLong avail_in_this_block;
97 uLong filled_in_this_block;
98 uLong unused; /* for future use and alignement */
99 unsigned char data[SIZEDATA_INDATABLOCK];
100 } linkedlist_datablock_internal;
101
102 typedef struct linkedlist_data_s
103 {
104 linkedlist_datablock_internal* first_block;
105 linkedlist_datablock_internal* last_block;
106 } linkedlist_data;
107
108
109 typedef struct
110 {
111 z_stream stream; /* zLib stream structure for inflate */
112 int stream_initialised; /* 1 is stream is initialised */
113 uInt pos_in_buffered_data; /* last written byte in buffered_data */
114
115 uLong pos_local_header; /* offset of the local header of the file
116 currenty writing */
117 char* central_header; /* central header data for the current file */
118 uLong size_centralheader; /* size of the central header for cur file */
119 uLong flag; /* flag of the file currently writing */
120
121 int method; /* compression method of file currenty wr.*/
122 int raw; /* 1 for directly writing raw data */
123 Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
124 uLong dosDate;
125 uLong crc32;
126 int encrypt;
127 #ifndef NOCRYPT
128 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
129 const unsigned long* pcrc_32_tab;
130 int crypt_header_size;
131 #endif
132 } curfile_info;
133
134 typedef struct
135 {
136 zlib_filefunc_def z_filefunc;
137 voidpf filestream; /* io structore of the zipfile */
138 linkedlist_data central_dir;/* datablock with central dir in construction*/
139 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
140 curfile_info ci; /* info on the file curretly writing */
141
142 uLong begin_pos; /* position of the beginning of the zipfile */
143 uLong add_position_when_writting_offset;
144 uLong number_entry;
145 } zip_internal;
146
147
148
149 #ifndef NOCRYPT
150 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
151 #include "crypt.h"
152 #endif
153
154 local linkedlist_datablock_internal* allocate_new_datablock()
155 {
156 linkedlist_datablock_internal* ldi;
157 ldi = (linkedlist_datablock_internal*)
158 ALLOC(sizeof(linkedlist_datablock_internal));
159 if (ldi!=NULL)
160 {
161 ldi->next_datablock = NULL ;
162 ldi->filled_in_this_block = 0 ;
163 ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
164 }
165 return ldi;
166 }
167
168 local void free_datablock(ldi)
169 linkedlist_datablock_internal* ldi;
170 {
171 while (ldi!=NULL)
172 {
173 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
174 TRYFREE(ldi);
175 ldi = ldinext;
176 }
177 }
178
179 local void init_linkedlist(ll)
180 linkedlist_data* ll;
181 {
182 ll->first_block = ll->last_block = NULL;
183 }
184
185 local void free_linkedlist(ll)
186 linkedlist_data* ll;
187 {
188 free_datablock(ll->first_block);
189 ll->first_block = ll->last_block = NULL;
190 }
191
192
193 local int add_data_in_datablock(ll,buf,len)
194 linkedlist_data* ll;
195 const void* buf;
196 uLong len;
197 {
198 linkedlist_datablock_internal* ldi;
199 const unsigned char* from_copy;
200
201 if (ll==NULL)
202 return ZIP_INTERNALERROR;
203
204 if (ll->last_block == NULL)
205 {
206 ll->first_block = ll->last_block = allocate_new_datablock();
207 if (ll->first_block == NULL)
208 return ZIP_INTERNALERROR;
209 }
210
211 ldi = ll->last_block;
212 from_copy = (unsigned char*)buf;
213
214 while (len>0)
215 {
216 uInt copy_this;
217 uInt i;
218 unsigned char* to_copy;
219
220 if (ldi->avail_in_this_block==0)
221 {
222 ldi->next_datablock = allocate_new_datablock();
223 if (ldi->next_datablock == NULL)
224 return ZIP_INTERNALERROR;
225 ldi = ldi->next_datablock ;
226 ll->last_block = ldi;
227 }
228
229 if (ldi->avail_in_this_block < len)
230 copy_this = (uInt)ldi->avail_in_this_block;
231 else
232 copy_this = (uInt)len;
233
234 to_copy = &(ldi->data[ldi->filled_in_this_block]);
235
236 for (i=0;i<copy_this;i++)
237 *(to_copy+i)=*(from_copy+i);
238
239 ldi->filled_in_this_block += copy_this;
240 ldi->avail_in_this_block -= copy_this;
241 from_copy += copy_this ;
242 len -= copy_this;
243 }
244 return ZIP_OK;
245 }
246
247
248
249 /****************************************************************************/
250
251 #ifndef NO_ADDFILEINEXISTINGZIP
252 /* ===========================================================================
253 Inputs a long in LSB order to the given file
254 nbByte == 1, 2 or 4 (byte, short or long)
255 */
256
257 local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
258 voidpf filestream, uLong x, int nbByte));
259 local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
260 const zlib_filefunc_def* pzlib_filefunc_def;
261 voidpf filestream;
262 uLong x;
263 int nbByte;
264 {
265 unsigned char buf[4];
266 int n;
267 for (n = 0; n < nbByte; n++)
268 {
269 buf[n] = (unsigned char)(x & 0xff);
270 x >>= 8;
271 }
272 if (x != 0)
273 { /* data overflow - hack for ZIP64 (X Roche) */
274 for (n = 0; n < nbByte; n++)
275 {
276 buf[n] = 0xff;
277 }
278 }
279
280 if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
281 return ZIP_ERRNO;
282 else
283 return ZIP_OK;
284 }
285
286 local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
287 local void ziplocal_putValue_inmemory (dest, x, nbByte)
288 void* dest;
289 uLong x;
290 int nbByte;
291 {
292 unsigned char* buf=(unsigned char*)dest;
293 int n;
294 for (n = 0; n < nbByte; n++) {
295 buf[n] = (unsigned char)(x & 0xff);
296 x >>= 8;
297 }
298
299 if (x != 0)
300 { /* data overflow - hack for ZIP64 */
301 for (n = 0; n < nbByte; n++)
302 {
303 buf[n] = 0xff;
304 }
305 }
306 }
307
308 /****************************************************************************/
309
310
311 local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
312 const tm_zip* ptm;
313 uLong dosDate;
314 {
315 uLong year = (uLong)ptm->tm_year;
316 if (year>1980)
317 year-=1980;
318 else if (year>80)
319 year-=80;
320 return
321 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
322 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
323 }
324
325
326 /****************************************************************************/
327
328 local int ziplocal_getByte OF((
329 const zlib_filefunc_def* pzlib_filefunc_def,
330 voidpf filestream,
331 int *pi));
332
333 local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
334 const zlib_filefunc_def* pzlib_filefunc_def;
335 voidpf filestream;
336 int *pi;
337 {
338 unsigned char c;
339 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
340 if (err==1)
341 {
342 *pi = (int)c;
343 return ZIP_OK;
344 }
345 else
346 {
347 if (ZERROR(*pzlib_filefunc_def,filestream))
348 return ZIP_ERRNO;
349 else
350 return ZIP_EOF;
351 }
352 }
353
354
355 /* ===========================================================================
356 Reads a long in LSB order from the given gz_stream. Sets
357 */
358 local int ziplocal_getShort OF((
359 const zlib_filefunc_def* pzlib_filefunc_def,
360 voidpf filestream,
361 uLong *pX));
362
363 local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
364 const zlib_filefunc_def* pzlib_filefunc_def;
365 voidpf filestream;
366 uLong *pX;
367 {
368 uLong x ;
369 int i;
370 int err;
371
372 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
373 x = (uLong)i;
374
375 if (err==ZIP_OK)
376 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
377 x += ((uLong)i)<<8;
378
379 if (err==ZIP_OK)
380 *pX = x;
381 else
382 *pX = 0;
383 return err;
384 }
385
386 local int ziplocal_getLong OF((
387 const zlib_filefunc_def* pzlib_filefunc_def,
388 voidpf filestream,
389 uLong *pX));
390
391 local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
392 const zlib_filefunc_def* pzlib_filefunc_def;
393 voidpf filestream;
394 uLong *pX;
395 {
396 uLong x ;
397 int i;
398 int err;
399
400 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
401 x = (uLong)i;
402
403 if (err==ZIP_OK)
404 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
405 x += ((uLong)i)<<8;
406
407 if (err==ZIP_OK)
408 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
409 x += ((uLong)i)<<16;
410
411 if (err==ZIP_OK)
412 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
413 x += ((uLong)i)<<24;
414
415 if (err==ZIP_OK)
416 *pX = x;
417 else
418 *pX = 0;
419 return err;
420 }
421
422 #ifndef BUFREADCOMMENT
423 #define BUFREADCOMMENT (0x400)
424 #endif
425 /*
426 Locate the Central directory of a zipfile (at the end, just before
427 the global comment)
428 */
429 local uLong ziplocal_SearchCentralDir OF((
430 const zlib_filefunc_def* pzlib_filefunc_def,
431 voidpf filestream));
432
433 local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
434 const zlib_filefunc_def* pzlib_filefunc_def;
435 voidpf filestream;
436 {
437 unsigned char* buf;
438 uLong uSizeFile;
439 uLong uBackRead;
440 uLong uMaxBack=0xffff; /* maximum size of global comment */
441 uLong uPosFound=0;
442
443 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
444 return 0;
445
446
447 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
448
449 if (uMaxBack>uSizeFile)
450 uMaxBack = uSizeFile;
451
452 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
453 if (buf==NULL)
454 return 0;
455
456 uBackRead = 4;
457 while (uBackRead<uMaxBack)
458 {
459 uLong uReadSize,uReadPos ;
460 int i;
461 if (uBackRead+BUFREADCOMMENT>uMaxBack)
462 uBackRead = uMaxBack;
463 else
464 uBackRead+=BUFREADCOMMENT;
465 uReadPos = uSizeFile-uBackRead ;
466
467 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
468 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
469 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
470 break;
471
472 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
473 break;
474
475 for (i=(int)uReadSize-3; (i--)>0;)
476 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
477 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
478 {
479 uPosFound = uReadPos+i;
480 break;
481 }
482
483 if (uPosFound!=0)
484 break;
485 }
486 TRYFREE(buf);
487 return uPosFound;
488 }
489 #endif /* !NO_ADDFILEINEXISTINGZIP*/
490
491 /************************************************************/
492 extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
493 const char *pathname;
494 int append;
495 zipcharpc* globalcomment;
496 zlib_filefunc_def* pzlib_filefunc_def;
497 {
498 zip_internal ziinit;
499 zip_internal* zi;
500 int err=ZIP_OK;
501
502
503 if (pzlib_filefunc_def==NULL)
504 fill_fopen_filefunc(&ziinit.z_filefunc);
505 else
506 ziinit.z_filefunc = *pzlib_filefunc_def;
507
508 ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
509 (ziinit.z_filefunc.opaque,
510 pathname,
511 (append == APPEND_STATUS_CREATE) ?
512 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
513 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
514
515 if (ziinit.filestream == NULL)
516 return NULL;
517 ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
518 ziinit.in_opened_file_inzip = 0;
519 ziinit.ci.stream_initialised = 0;
520 ziinit.number_entry = 0;
521 ziinit.add_position_when_writting_offset = 0;
522 init_linkedlist(&(ziinit.central_dir));
523
524
525 zi = (zip_internal*)ALLOC(sizeof(zip_internal));
526 if (zi==NULL)
527 {
528 ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
529 return NULL;
530 }
531
532 /* now we add file in a zipfile */
533 # ifndef NO_ADDFILEINEXISTINGZIP
534 if (append == APPEND_STATUS_ADDINZIP)
535 {
536 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
537
538 uLong size_central_dir; /* size of the central directory */
539 uLong offset_central_dir; /* offset of start of central directory */
540 uLong central_pos,uL;
541
542 uLong number_disk; /* number of the current dist, used for
543 spaning ZIP, unsupported, always 0*/
544 uLong number_disk_with_CD; /* number the the disk with central dir, used
545 for spaning ZIP, unsupported, always 0*/
546 uLong number_entry;
547 uLong number_entry_CD; /* total number of entries in
548 the central dir
549 (same than number_entry on nospan) */
550 uLong size_comment;
551
552 central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
553 if (central_pos==0)
554 err=ZIP_ERRNO;
555
556 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
557 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
558 err=ZIP_ERRNO;
559
560 /* the signature, already checked */
561 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
562 err=ZIP_ERRNO;
563
564 /* number of this disk */
565 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
566 err=ZIP_ERRNO;
567
568 /* number of the disk with the start of the central directory */
569 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
570 err=ZIP_ERRNO;
571
572 /* total number of entries in the central dir on this disk */
573 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
574 err=ZIP_ERRNO;
575
576 /* total number of entries in the central dir */
577 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
578 err=ZIP_ERRNO;
579
580 if ((number_entry_CD!=number_entry) ||
581 (number_disk_with_CD!=0) ||
582 (number_disk!=0))
583 err=ZIP_BADZIPFILE;
584
585 /* size of the central directory */
586 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
587 err=ZIP_ERRNO;
588
589 /* offset of start of central directory with respect to the
590 starting disk number */
591 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
592 err=ZIP_ERRNO;
593
594 /* zipfile comment length */
595 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
596 err=ZIP_ERRNO;
597
598 if ((central_pos<offset_central_dir+size_central_dir) &&
599 (err==ZIP_OK))
600 err=ZIP_BADZIPFILE;
601
602 if (err!=ZIP_OK)
603 {
604 ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
605 return NULL;
606 }
607
608 byte_before_the_zipfile = central_pos -
609 (offset_central_dir+size_central_dir);
610 ziinit.add_position_when_writting_offset = byte_before_the_zipfile ;
611
612 {
613 uLong size_central_dir_to_read = size_central_dir;
614 size_t buf_size = SIZEDATA_INDATABLOCK;
615 void* buf_read = (void*)ALLOC(buf_size);
616 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
617 offset_central_dir + byte_before_the_zipfile,
618 ZLIB_FILEFUNC_SEEK_SET) != 0)
619 err=ZIP_ERRNO;
620
621 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
622 {
623 uLong read_this = SIZEDATA_INDATABLOCK;
624 if (read_this > size_central_dir_to_read)
625 read_this = size_central_dir_to_read;
626 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
627 err=ZIP_ERRNO;
628
629 if (err==ZIP_OK)
630 err = add_data_in_datablock(&ziinit.central_dir,buf_read,
631 (uLong)read_this);
632 size_central_dir_to_read-=read_this;
633 }
634 TRYFREE(buf_read);
635 }
636 ziinit.begin_pos = byte_before_the_zipfile;
637 ziinit.number_entry = number_entry_CD;
638
639 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
640 offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
641 err=ZIP_ERRNO;
642 }
643 # endif /* !NO_ADDFILEINEXISTINGZIP*/
644
645 if (err != ZIP_OK)
646 {
647 TRYFREE(zi);
648 return NULL;
649 }
650 else
651 {
652 *zi = ziinit;
653 return (zipFile)zi;
654 }
655 }
656
657 extern zipFile ZEXPORT zipOpen (pathname, append)
658 const char *pathname;
659 int append;
660 {
661 return zipOpen2(pathname,append,NULL,NULL);
662 }
663
664 extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
665 extrafield_local, size_extrafield_local,
666 extrafield_global, size_extrafield_global,
667 comment, method, level, raw,
668 windowBits, memLevel, strategy,
669 password, crcForCrypting)
670 zipFile file;
671 const char* filename;
672 const zip_fileinfo* zipfi;
673 const void* extrafield_local;
674 uInt size_extrafield_local;
675 const void* extrafield_global;
676 uInt size_extrafield_global;
677 const char* comment;
678 int method;
679 int level;
680 int raw;
681 int windowBits;
682 int memLevel;
683 int strategy;
684 const char* password;
685 uLong crcForCrypting;
686 {
687 zip_internal* zi;
688 uInt size_filename;
689 uInt size_comment;
690 uInt i;
691 int err = ZIP_OK;
692
693 # ifdef NOCRYPT
694 if (password != NULL)
695 return ZIP_PARAMERROR;
696 # endif
697
698 if (file == NULL)
699 return ZIP_PARAMERROR;
700 if ((method!=0) && (method!=Z_DEFLATED))
701 return ZIP_PARAMERROR;
702
703 zi = (zip_internal*)file;
704
705 if (zi->in_opened_file_inzip == 1)
706 {
707 err = zipCloseFileInZip (file);
708 if (err != ZIP_OK)
709 return err;
710 }
711
712
713 if (filename==NULL)
714 filename="-";
715
716 if (comment==NULL)
717 size_comment = 0;
718 else
719 size_comment = (uInt)strlen(comment);
720
721 size_filename = (uInt)strlen(filename);
722
723 if (zipfi == NULL)
724 zi->ci.dosDate = 0;
725 else
726 {
727 if (zipfi->dosDate != 0)
728 zi->ci.dosDate = zipfi->dosDate;
729 else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
730 }
731
732 zi->ci.flag = 0;
733 if ((level==8) || (level==9))
734 zi->ci.flag |= 2;
735 if ((level==2))
736 zi->ci.flag |= 4;
737 if ((level==1))
738 zi->ci.flag |= 6;
739 if (password != NULL)
740 zi->ci.flag |= 1;
741
742 zi->ci.crc32 = 0;
743 zi->ci.method = method;
744 zi->ci.encrypt = 0;
745 zi->ci.stream_initialised = 0;
746 zi->ci.pos_in_buffered_data = 0;
747 zi->ci.raw = raw;
748 zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
749 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
750 size_extrafield_global + size_comment;
751 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
752
753 ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
754 /* version info */
755 ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
756 ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
757 ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
758 ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
759 ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
760 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
761 ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
762 ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
763 ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
764 ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
765 ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
766 ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
767
768 if (zipfi==NULL)
769 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
770 else
771 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
772
773 if (zipfi==NULL)
774 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
775 else
776 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
777
778 ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
779
780 for (i=0;i<size_filename;i++)
781 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
782
783 for (i=0;i<size_extrafield_global;i++)
784 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
785 *(((const char*)extrafield_global)+i);
786
787 for (i=0;i<size_comment;i++)
788 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
789 size_extrafield_global+i) = *(comment+i);
790 if (zi->ci.central_header == NULL)
791 return ZIP_INTERNALERROR;
792
793 /* write the local header */
794 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
795
796 if (err==ZIP_OK)
797 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
798 if (err==ZIP_OK)
799 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
800
801 if (err==ZIP_OK)
802 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
803
804 if (err==ZIP_OK)
805 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
806
807 if (err==ZIP_OK)
808 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
809 if (err==ZIP_OK)
810 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
811 if (err==ZIP_OK)
812 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
813
814 if (err==ZIP_OK)
815 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
816
817 if (err==ZIP_OK)
818 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
819
820 if ((err==ZIP_OK) && (size_filename>0))
821 if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
822 err = ZIP_ERRNO;
823
824 if ((err==ZIP_OK) && (size_extrafield_local>0))
825 if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
826 !=size_extrafield_local)
827 err = ZIP_ERRNO;
828
829 zi->ci.stream.avail_in = (uInt)0;
830 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
831 zi->ci.stream.next_out = zi->ci.buffered_data;
832 zi->ci.stream.total_in = 0;
833 zi->ci.stream.total_out = 0;
834
835 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
836 {
837 zi->ci.stream.zalloc = (alloc_func)0;
838 zi->ci.stream.zfree = (free_func)0;
839 zi->ci.stream.opaque = (voidpf)0;
840
841 if (windowBits>0)
842 windowBits = -windowBits;
843
844 err = deflateInit2(&zi->ci.stream, level,
845 Z_DEFLATED, windowBits, memLevel, strategy);
846
847 if (err==Z_OK)
848 zi->ci.stream_initialised = 1;
849 }
850 # ifndef NOCRYPT
851 zi->ci.crypt_header_size = 0;
852 if ((err==Z_OK) && (password != NULL))
853 {
854 unsigned char bufHead[RAND_HEAD_LEN];
855 unsigned int sizeHead;
856 zi->ci.encrypt = 1;
857 zi->ci.pcrc_32_tab = get_crc_table();
858 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
859
860 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
861 zi->ci.crypt_header_size = sizeHead;
862
863 if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
864 err = ZIP_ERRNO;
865 }
866 # endif
867
868 if (err==Z_OK)
869 zi->in_opened_file_inzip = 1;
870 return err;
871 }
872
873 extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
874 extrafield_local, size_extrafield_local,
875 extrafield_global, size_extrafield_global,
876 comment, method, level, raw)
877 zipFile file;
878 const char* filename;
879 const zip_fileinfo* zipfi;
880 const void* extrafield_local;
881 uInt size_extrafield_local;
882 const void* extrafield_global;
883 uInt size_extrafield_global;
884 const char* comment;
885 int method;
886 int level;
887 int raw;
888 {
889 return zipOpenNewFileInZip3 (file, filename, zipfi,
890 extrafield_local, size_extrafield_local,
891 extrafield_global, size_extrafield_global,
892 comment, method, level, raw,
893 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
894 NULL, 0);
895 }
896
897 extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
898 extrafield_local, size_extrafield_local,
899 extrafield_global, size_extrafield_global,
900 comment, method, level)
901 zipFile file;
902 const char* filename;
903 const zip_fileinfo* zipfi;
904 const void* extrafield_local;
905 uInt size_extrafield_local;
906 const void* extrafield_global;
907 uInt size_extrafield_global;
908 const char* comment;
909 int method;
910 int level;
911 {
912 return zipOpenNewFileInZip2 (file, filename, zipfi,
913 extrafield_local, size_extrafield_local,
914 extrafield_global, size_extrafield_global,
915 comment, method, level, 0);
916 }
917
918 local int zipFlushWriteBuffer(zi)
919 zip_internal* zi;
920 {
921 int err=ZIP_OK;
922
923 if (zi->ci.encrypt != 0)
924 {
925 #ifndef NOCRYPT
926 uInt i;
927 int t;
928 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
929 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
930 zi->ci.buffered_data[i],t);
931 #endif
932 }
933 if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
934 !=zi->ci.pos_in_buffered_data)
935 err = ZIP_ERRNO;
936 zi->ci.pos_in_buffered_data = 0;
937 return err;
938 }
939
940 extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
941 zipFile file;
942 const void* buf;
943 unsigned len;
944 {
945 zip_internal* zi;
946 int err=ZIP_OK;
947
948 if (file == NULL)
949 return ZIP_PARAMERROR;
950 zi = (zip_internal*)file;
951
952 if (zi->in_opened_file_inzip == 0)
953 return ZIP_PARAMERROR;
954
955 zi->ci.stream.next_in = (void*)buf;
956 zi->ci.stream.avail_in = len;
957 zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
958
959 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
960 {
961 if (zi->ci.stream.avail_out == 0)
962 {
963 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
964 err = ZIP_ERRNO;
965 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
966 zi->ci.stream.next_out = zi->ci.buffered_data;
967 }
968
969
970 if(err != ZIP_OK)
971 break;
972
973 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
974 {
975 uLong uTotalOutBefore = zi->ci.stream.total_out;
976 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
977 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
978
979 }
980 else
981 {
982 uInt copy_this,i;
983 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
984 copy_this = zi->ci.stream.avail_in;
985 else
986 copy_this = zi->ci.stream.avail_out;
987 for (i=0;i<copy_this;i++)
988 *(((char*)zi->ci.stream.next_out)+i) =
989 *(((const char*)zi->ci.stream.next_in)+i);
990 {
991 zi->ci.stream.avail_in -= copy_this;
992 zi->ci.stream.avail_out-= copy_this;
993 zi->ci.stream.next_in+= copy_this;
994 zi->ci.stream.next_out+= copy_this;
995 zi->ci.stream.total_in+= copy_this;
996 zi->ci.stream.total_out+= copy_this;
997 zi->ci.pos_in_buffered_data += copy_this;
998 }
999 }
1000 }
1001
1002 return err;
1003 }
1004
1005 extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
1006 zipFile file;
1007 uLong uncompressed_size;
1008 uLong crc32;
1009 {
1010 zip_internal* zi;
1011 uLong compressed_size;
1012 int err=ZIP_OK;
1013
1014 if (file == NULL)
1015 return ZIP_PARAMERROR;
1016 zi = (zip_internal*)file;
1017
1018 if (zi->in_opened_file_inzip == 0)
1019 return ZIP_PARAMERROR;
1020 zi->ci.stream.avail_in = 0;
1021
1022 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1023 while (err==ZIP_OK)
1024 {
1025 uLong uTotalOutBefore;
1026 if (zi->ci.stream.avail_out == 0)
1027 {
1028 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1029 err = ZIP_ERRNO;
1030 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1031 zi->ci.stream.next_out = zi->ci.buffered_data;
1032 }
1033 uTotalOutBefore = zi->ci.stream.total_out;
1034 err=deflate(&zi->ci.stream, Z_FINISH);
1035 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1036 }
1037
1038 if (err==Z_STREAM_END)
1039 err=ZIP_OK; /* this is normal */
1040
1041 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1042 if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1043 err = ZIP_ERRNO;
1044
1045 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1046 {
1047 err=deflateEnd(&zi->ci.stream);
1048 zi->ci.stream_initialised = 0;
1049 }
1050
1051 if (!zi->ci.raw)
1052 {
1053 crc32 = (uLong)zi->ci.crc32;
1054 uncompressed_size = (uLong)zi->ci.stream.total_in;
1055 }
1056 compressed_size = (uLong)zi->ci.stream.total_out;
1057 # ifndef NOCRYPT
1058 compressed_size += zi->ci.crypt_header_size;
1059 # endif
1060
1061 ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1062 ziplocal_putValue_inmemory(zi->ci.central_header+20,
1063 compressed_size,4); /*compr size*/
1064 if (zi->ci.stream.data_type == Z_ASCII)
1065 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1066 ziplocal_putValue_inmemory(zi->ci.central_header+24,
1067 uncompressed_size,4); /*uncompr size*/
1068
1069 if (err==ZIP_OK)
1070 err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1071 (uLong)zi->ci.size_centralheader);
1072 free(zi->ci.central_header);
1073
1074 if (err==ZIP_OK)
1075 {
1076 long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1077 if (ZSEEK(zi->z_filefunc,zi->filestream,
1078 zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1079 err = ZIP_ERRNO;
1080
1081 if (err==ZIP_OK)
1082 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1083
1084 if (err==ZIP_OK) /* compressed size, unknown */
1085 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1086
1087 if (err==ZIP_OK) /* uncompressed size, unknown */
1088 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1089
1090 if (ZSEEK(zi->z_filefunc,zi->filestream,
1091 cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1092 err = ZIP_ERRNO;
1093 }
1094
1095 zi->number_entry ++;
1096 zi->in_opened_file_inzip = 0;
1097
1098 return err;
1099 }
1100
1101 extern int ZEXPORT zipCloseFileInZip (file)
1102 zipFile file;
1103 {
1104 return zipCloseFileInZipRaw (file,0,0);
1105 }
1106
1107 extern int ZEXPORT zipClose (file, global_comment)
1108 zipFile file;
1109 const char* global_comment;
1110 {
1111 zip_internal* zi;
1112 int err = 0;
1113 uLong size_centraldir = 0;
1114 uLong centraldir_pos_inzip ;
1115 uInt size_global_comment;
1116 if (file == NULL)
1117 return ZIP_PARAMERROR;
1118 zi = (zip_internal*)file;
1119
1120 if (zi->in_opened_file_inzip == 1)
1121 {
1122 err = zipCloseFileInZip (file);
1123 }
1124
1125 if (global_comment==NULL)
1126 size_global_comment = 0;
1127 else
1128 size_global_comment = (uInt)strlen(global_comment);
1129
1130
1131 centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1132 if (err==ZIP_OK)
1133 {
1134 linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1135 while (ldi!=NULL)
1136 {
1137 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1138 if (ZWRITE(zi->z_filefunc,zi->filestream,
1139 ldi->data,ldi->filled_in_this_block)
1140 !=ldi->filled_in_this_block )
1141 err = ZIP_ERRNO;
1142
1143 size_centraldir += ldi->filled_in_this_block;
1144 ldi = ldi->next_datablock;
1145 }
1146 }
1147 free_datablock(zi->central_dir.first_block);
1148
1149 if (err==ZIP_OK) /* Magic End */
1150 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1151
1152 if (err==ZIP_OK) /* number of this disk */
1153 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1154
1155 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1156 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1157
1158 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1159 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1160
1161 if (err==ZIP_OK) /* total number of entries in the central dir */
1162 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1163
1164 if (err==ZIP_OK) /* size of the central directory */
1165 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1166
1167 if (err==ZIP_OK) /* offset of start of central directory with respect to the
1168 starting disk number */
1169 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1170 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1171
1172 if (err==ZIP_OK) /* zipfile comment length */
1173 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1174
1175 if ((err==ZIP_OK) && (size_global_comment>0))
1176 if (ZWRITE(zi->z_filefunc,zi->filestream,
1177 global_comment,size_global_comment) != size_global_comment)
1178 err = ZIP_ERRNO;
1179
1180 if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1181 if (err == ZIP_OK)
1182 err = ZIP_ERRNO;
1183
1184 TRYFREE(zi);
1185
1186 return err;
1187 }
0 /* zip.h -- IO for compress .zip files using zlib
1 Version 1.01, May 8th, 2004
2
3 Copyright (C) 1998-2004 Gilles Vollant
4
5 This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
6 WinZip, InfoZip tools and compatible.
7 Encryption and multi volume ZipFile (span) are not supported.
8 Old compressions used by old PKZip 1.x are not supported
9
10 For uncompress .zip file, look at unzip.h
11
12
13 I WAIT FEEDBACK at mail info@winimage.com
14 Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
15
16 Condition of use and distribution are the same than zlib :
17
18 This software is provided 'as-is', without any express or implied
19 warranty. In no event will the authors be held liable for any damages
20 arising from the use of this software.
21
22 Permission is granted to anyone to use this software for any purpose,
23 including commercial applications, and to alter it and redistribute it
24 freely, subject to the following restrictions:
25
26 1. The origin of this software must not be misrepresented; you must not
27 claim that you wrote the original software. If you use this software
28 in a product, an acknowledgment in the product documentation would be
29 appreciated but is not required.
30 2. Altered source versions must be plainly marked as such, and must not be
31 misrepresented as being the original software.
32 3. This notice may not be removed or altered from any source distribution.
33
34
35 */
36
37 /* for more info about .ZIP format, see
38 http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
39 http://www.info-zip.org/pub/infozip/doc/
40 PkWare has also a specification at :
41 ftp://ftp.pkware.com/probdesc.zip
42 */
43
44 #ifndef _zip_H
45 #define _zip_H
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 #ifndef _ZLIB_H
52 #include "zlib.h"
53 #endif
54
55 #ifndef _ZLIBIOAPI_H
56 #include "ioapi.h"
57 #endif
58
59 #if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
60 /* like the STRICT of WIN32, we define a pointer that cannot be converted
61 from (void*) without cast */
62 typedef struct TagzipFile__ { int unused; } zipFile__;
63 typedef zipFile__ *zipFile;
64 #else
65 typedef voidp zipFile;
66 #endif
67
68 #define ZIP_OK (0)
69 #define ZIP_EOF (0)
70 #define ZIP_ERRNO (Z_ERRNO)
71 #define ZIP_PARAMERROR (-102)
72 #define ZIP_BADZIPFILE (-103)
73 #define ZIP_INTERNALERROR (-104)
74
75 #ifndef DEF_MEM_LEVEL
76 # if MAX_MEM_LEVEL >= 8
77 # define DEF_MEM_LEVEL 8
78 # else
79 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
80 # endif
81 #endif
82 /* default memLevel */
83
84 /* tm_zip contain date/time info */
85 typedef struct tm_zip_s
86 {
87 uInt tm_sec; /* seconds after the minute - [0,59] */
88 uInt tm_min; /* minutes after the hour - [0,59] */
89 uInt tm_hour; /* hours since midnight - [0,23] */
90 uInt tm_mday; /* day of the month - [1,31] */
91 uInt tm_mon; /* months since January - [0,11] */
92 uInt tm_year; /* years - [1980..2044] */
93 } tm_zip;
94
95 typedef struct
96 {
97 tm_zip tmz_date; /* date in understandable format */
98 uLong dosDate; /* if dos_date == 0, tmu_date is used */
99 /* uLong flag; */ /* general purpose bit flag 2 bytes */
100
101 uLong internal_fa; /* internal file attributes 2 bytes */
102 uLong external_fa; /* external file attributes 4 bytes */
103 } zip_fileinfo;
104
105 typedef const char* zipcharpc;
106
107
108 #define APPEND_STATUS_CREATE (0)
109 #define APPEND_STATUS_CREATEAFTER (1)
110 #define APPEND_STATUS_ADDINZIP (2)
111
112 extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
113 /*
114 Create a zipfile.
115 pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
116 an Unix computer "zlib/zlib113.zip".
117 if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
118 will be created at the end of the file.
119 (useful if the file contain a self extractor code)
120 if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
121 add files in existing zip (be sure you don't add file that doesn't exist)
122 If the zipfile cannot be opened, the return value is NULL.
123 Else, the return value is a zipFile Handle, usable with other function
124 of this zip package.
125 */
126
127 /* Note : there is no delete function into a zipfile.
128 If you want delete file into a zipfile, you must open a zipfile, and create another
129 Of couse, you can use RAW reading and writing to copy the file you did not want delte
130 */
131
132 extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
133 int append,
134 zipcharpc* globalcomment,
135 zlib_filefunc_def* pzlib_filefunc_def));
136
137 extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
138 const char* filename,
139 const zip_fileinfo* zipfi,
140 const void* extrafield_local,
141 uInt size_extrafield_local,
142 const void* extrafield_global,
143 uInt size_extrafield_global,
144 const char* comment,
145 int method,
146 int level));
147 /*
148 Open a file in the ZIP for writing.
149 filename : the filename in zip (if NULL, '-' without quote will be used
150 *zipfi contain supplemental information
151 if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
152 contains the extrafield data the the local header
153 if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
154 contains the extrafield data the the local header
155 if comment != NULL, comment contain the comment string
156 method contain the compression method (0 for store, Z_DEFLATED for deflate)
157 level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
158 */
159
160
161 extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
162 const char* filename,
163 const zip_fileinfo* zipfi,
164 const void* extrafield_local,
165 uInt size_extrafield_local,
166 const void* extrafield_global,
167 uInt size_extrafield_global,
168 const char* comment,
169 int method,
170 int level,
171 int raw));
172
173 /*
174 Same than zipOpenNewFileInZip, except if raw=1, we write raw file
175 */
176
177 extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
178 const char* filename,
179 const zip_fileinfo* zipfi,
180 const void* extrafield_local,
181 uInt size_extrafield_local,
182 const void* extrafield_global,
183 uInt size_extrafield_global,
184 const char* comment,
185 int method,
186 int level,
187 int raw,
188 int windowBits,
189 int memLevel,
190 int strategy,
191 const char* password,
192 uLong crcForCtypting));
193
194 /*
195 Same than zipOpenNewFileInZip2, except
196 windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
197 password : crypting password (NULL for no crypting)
198 crcForCtypting : crc of file to compress (needed for crypting)
199 */
200
201
202 extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
203 const void* buf,
204 unsigned len));
205 /*
206 Write data in the zipfile
207 */
208
209 extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
210 /*
211 Close the current file in the zipfile
212 */
213
214 extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
215 uLong uncompressed_size,
216 uLong crc32));
217 /*
218 Close the current file in the zipfile, for fiel opened with
219 parameter raw=1 in zipOpenNewFileInZip2
220 uncompressed_size and crc32 are value for the uncompressed size
221 */
222
223 extern int ZEXPORT zipClose OF((zipFile file,
224 const char* global_comment));
225 /*
226 Close the zipfile
227 */
228
229 #ifdef __cplusplus
230 }
231 #endif
232
233 #endif /* _zip_H */
0 (* example.c -- usage example of the zlib compression library
1 * Copyright (C) 1995-2003 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 *
4 * Pascal translation
5 * Copyright (C) 1998 by Jacques Nomssi Nzali.
6 * For conditions of distribution and use, see copyright notice in readme.txt
7 *
8 * Adaptation to the zlibpas interface
9 * Copyright (C) 2003 by Cosmin Truta.
10 * For conditions of distribution and use, see copyright notice in readme.txt
11 *)
12
13 program example;
14
15 {$DEFINE TEST_COMPRESS}
16 {DO NOT $DEFINE TEST_GZIO}
17 {$DEFINE TEST_DEFLATE}
18 {$DEFINE TEST_INFLATE}
19 {$DEFINE TEST_FLUSH}
20 {$DEFINE TEST_SYNC}
21 {$DEFINE TEST_DICT}
22
23 uses SysUtils, zlibpas;
24
25 const TESTFILE = 'foo.gz';
26
27 (* "hello world" would be more standard, but the repeated "hello"
28 * stresses the compression code better, sorry...
29 *)
30 const hello: PChar = 'hello, hello!';
31
32 const dictionary: PChar = 'hello';
33
34 var dictId: LongInt; (* Adler32 value of the dictionary *)
35
36 procedure CHECK_ERR(err: Integer; msg: String);
37 begin
38 if err <> Z_OK then
39 begin
40 WriteLn(msg, ' error: ', err);
41 Halt(1);
42 end;
43 end;
44
45 procedure EXIT_ERR(const msg: String);
46 begin
47 WriteLn('Error: ', msg);
48 Halt(1);
49 end;
50
51 (* ===========================================================================
52 * Test compress and uncompress
53 *)
54 {$IFDEF TEST_COMPRESS}
55 procedure test_compress(compr: Pointer; comprLen: LongInt;
56 uncompr: Pointer; uncomprLen: LongInt);
57 var err: Integer;
58 len: LongInt;
59 begin
60 len := StrLen(hello)+1;
61
62 err := compress(compr, comprLen, hello, len);
63 CHECK_ERR(err, 'compress');
64
65 StrCopy(PChar(uncompr), 'garbage');
66
67 err := uncompress(uncompr, uncomprLen, compr, comprLen);
68 CHECK_ERR(err, 'uncompress');
69
70 if StrComp(PChar(uncompr), hello) <> 0 then
71 EXIT_ERR('bad uncompress')
72 else
73 WriteLn('uncompress(): ', PChar(uncompr));
74 end;
75 {$ENDIF}
76
77 (* ===========================================================================
78 * Test read/write of .gz files
79 *)
80 {$IFDEF TEST_GZIO}
81 procedure test_gzio(const fname: PChar; (* compressed file name *)
82 uncompr: Pointer;
83 uncomprLen: LongInt);
84 var err: Integer;
85 len: Integer;
86 zfile: gzFile;
87 pos: LongInt;
88 begin
89 len := StrLen(hello)+1;
90
91 zfile := gzopen(fname, 'wb');
92 if zfile = NIL then
93 begin
94 WriteLn('gzopen error');
95 Halt(1);
96 end;
97 gzputc(zfile, 'h');
98 if gzputs(zfile, 'ello') <> 4 then
99 begin
100 WriteLn('gzputs err: ', gzerror(zfile, err));
101 Halt(1);
102 end;
103 {$IFDEF GZ_FORMAT_STRING}
104 if gzprintf(zfile, ', %s!', 'hello') <> 8 then
105 begin
106 WriteLn('gzprintf err: ', gzerror(zfile, err));
107 Halt(1);
108 end;
109 {$ELSE}
110 if gzputs(zfile, ', hello!') <> 8 then
111 begin
112 WriteLn('gzputs err: ', gzerror(zfile, err));
113 Halt(1);
114 end;
115 {$ENDIF}
116 gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
117 gzclose(zfile);
118
119 zfile := gzopen(fname, 'rb');
120 if zfile = NIL then
121 begin
122 WriteLn('gzopen error');
123 Halt(1);
124 end;
125
126 StrCopy(PChar(uncompr), 'garbage');
127
128 if gzread(zfile, uncompr, uncomprLen) <> len then
129 begin
130 WriteLn('gzread err: ', gzerror(zfile, err));
131 Halt(1);
132 end;
133 if StrComp(PChar(uncompr), hello) <> 0 then
134 begin
135 WriteLn('bad gzread: ', PChar(uncompr));
136 Halt(1);
137 end
138 else
139 WriteLn('gzread(): ', PChar(uncompr));
140
141 pos := gzseek(zfile, -8, SEEK_CUR);
142 if (pos <> 6) or (gztell(zfile) <> pos) then
143 begin
144 WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
145 Halt(1);
146 end;
147
148 if gzgetc(zfile) <> ' ' then
149 begin
150 WriteLn('gzgetc error');
151 Halt(1);
152 end;
153
154 if gzungetc(' ', zfile) <> ' ' then
155 begin
156 WriteLn('gzungetc error');
157 Halt(1);
158 end;
159
160 gzgets(zfile, PChar(uncompr), uncomprLen);
161 uncomprLen := StrLen(PChar(uncompr));
162 if uncomprLen <> 7 then (* " hello!" *)
163 begin
164 WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
165 Halt(1);
166 end;
167 if StrComp(PChar(uncompr), hello + 6) <> 0 then
168 begin
169 WriteLn('bad gzgets after gzseek');
170 Halt(1);
171 end
172 else
173 WriteLn('gzgets() after gzseek: ', PChar(uncompr));
174
175 gzclose(zfile);
176 end;
177 {$ENDIF}
178
179 (* ===========================================================================
180 * Test deflate with small buffers
181 *)
182 {$IFDEF TEST_DEFLATE}
183 procedure test_deflate(compr: Pointer; comprLen: LongInt);
184 var c_stream: z_stream; (* compression stream *)
185 err: Integer;
186 len: LongInt;
187 begin
188 len := StrLen(hello)+1;
189
190 c_stream.zalloc := NIL;
191 c_stream.zfree := NIL;
192 c_stream.opaque := NIL;
193
194 err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
195 CHECK_ERR(err, 'deflateInit');
196
197 c_stream.next_in := hello;
198 c_stream.next_out := compr;
199
200 while (c_stream.total_in <> len) and
201 (c_stream.total_out < comprLen) do
202 begin
203 c_stream.avail_out := 1; { force small buffers }
204 c_stream.avail_in := 1;
205 err := deflate(c_stream, Z_NO_FLUSH);
206 CHECK_ERR(err, 'deflate');
207 end;
208
209 (* Finish the stream, still forcing small buffers: *)
210 while TRUE do
211 begin
212 c_stream.avail_out := 1;
213 err := deflate(c_stream, Z_FINISH);
214 if err = Z_STREAM_END then
215 break;
216 CHECK_ERR(err, 'deflate');
217 end;
218
219 err := deflateEnd(c_stream);
220 CHECK_ERR(err, 'deflateEnd');
221 end;
222 {$ENDIF}
223
224 (* ===========================================================================
225 * Test inflate with small buffers
226 *)
227 {$IFDEF TEST_INFLATE}
228 procedure test_inflate(compr: Pointer; comprLen : LongInt;
229 uncompr: Pointer; uncomprLen : LongInt);
230 var err: Integer;
231 d_stream: z_stream; (* decompression stream *)
232 begin
233 StrCopy(PChar(uncompr), 'garbage');
234
235 d_stream.zalloc := NIL;
236 d_stream.zfree := NIL;
237 d_stream.opaque := NIL;
238
239 d_stream.next_in := compr;
240 d_stream.avail_in := 0;
241 d_stream.next_out := uncompr;
242
243 err := inflateInit(d_stream);
244 CHECK_ERR(err, 'inflateInit');
245
246 while (d_stream.total_out < uncomprLen) and
247 (d_stream.total_in < comprLen) do
248 begin
249 d_stream.avail_out := 1; (* force small buffers *)
250 d_stream.avail_in := 1;
251 err := inflate(d_stream, Z_NO_FLUSH);
252 if err = Z_STREAM_END then
253 break;
254 CHECK_ERR(err, 'inflate');
255 end;
256
257 err := inflateEnd(d_stream);
258 CHECK_ERR(err, 'inflateEnd');
259
260 if StrComp(PChar(uncompr), hello) <> 0 then
261 EXIT_ERR('bad inflate')
262 else
263 WriteLn('inflate(): ', PChar(uncompr));
264 end;
265 {$ENDIF}
266
267 (* ===========================================================================
268 * Test deflate with large buffers and dynamic change of compression level
269 *)
270 {$IFDEF TEST_DEFLATE}
271 procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
272 uncompr: Pointer; uncomprLen: LongInt);
273 var c_stream: z_stream; (* compression stream *)
274 err: Integer;
275 begin
276 c_stream.zalloc := NIL;
277 c_stream.zfree := NIL;
278 c_stream.opaque := NIL;
279
280 err := deflateInit(c_stream, Z_BEST_SPEED);
281 CHECK_ERR(err, 'deflateInit');
282
283 c_stream.next_out := compr;
284 c_stream.avail_out := Integer(comprLen);
285
286 (* At this point, uncompr is still mostly zeroes, so it should compress
287 * very well:
288 *)
289 c_stream.next_in := uncompr;
290 c_stream.avail_in := Integer(uncomprLen);
291 err := deflate(c_stream, Z_NO_FLUSH);
292 CHECK_ERR(err, 'deflate');
293 if c_stream.avail_in <> 0 then
294 EXIT_ERR('deflate not greedy');
295
296 (* Feed in already compressed data and switch to no compression: *)
297 deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
298 c_stream.next_in := compr;
299 c_stream.avail_in := Integer(comprLen div 2);
300 err := deflate(c_stream, Z_NO_FLUSH);
301 CHECK_ERR(err, 'deflate');
302
303 (* Switch back to compressing mode: *)
304 deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
305 c_stream.next_in := uncompr;
306 c_stream.avail_in := Integer(uncomprLen);
307 err := deflate(c_stream, Z_NO_FLUSH);
308 CHECK_ERR(err, 'deflate');
309
310 err := deflate(c_stream, Z_FINISH);
311 if err <> Z_STREAM_END then
312 EXIT_ERR('deflate should report Z_STREAM_END');
313
314 err := deflateEnd(c_stream);
315 CHECK_ERR(err, 'deflateEnd');
316 end;
317 {$ENDIF}
318
319 (* ===========================================================================
320 * Test inflate with large buffers
321 *)
322 {$IFDEF TEST_INFLATE}
323 procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
324 uncompr: Pointer; uncomprLen: LongInt);
325 var err: Integer;
326 d_stream: z_stream; (* decompression stream *)
327 begin
328 StrCopy(PChar(uncompr), 'garbage');
329
330 d_stream.zalloc := NIL;
331 d_stream.zfree := NIL;
332 d_stream.opaque := NIL;
333
334 d_stream.next_in := compr;
335 d_stream.avail_in := Integer(comprLen);
336
337 err := inflateInit(d_stream);
338 CHECK_ERR(err, 'inflateInit');
339
340 while TRUE do
341 begin
342 d_stream.next_out := uncompr; (* discard the output *)
343 d_stream.avail_out := Integer(uncomprLen);
344 err := inflate(d_stream, Z_NO_FLUSH);
345 if err = Z_STREAM_END then
346 break;
347 CHECK_ERR(err, 'large inflate');
348 end;
349
350 err := inflateEnd(d_stream);
351 CHECK_ERR(err, 'inflateEnd');
352
353 if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
354 begin
355 WriteLn('bad large inflate: ', d_stream.total_out);
356 Halt(1);
357 end
358 else
359 WriteLn('large_inflate(): OK');
360 end;
361 {$ENDIF}
362
363 (* ===========================================================================
364 * Test deflate with full flush
365 *)
366 {$IFDEF TEST_FLUSH}
367 procedure test_flush(compr: Pointer; var comprLen : LongInt);
368 var c_stream: z_stream; (* compression stream *)
369 err: Integer;
370 len: Integer;
371 begin
372 len := StrLen(hello)+1;
373
374 c_stream.zalloc := NIL;
375 c_stream.zfree := NIL;
376 c_stream.opaque := NIL;
377
378 err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
379 CHECK_ERR(err, 'deflateInit');
380
381 c_stream.next_in := hello;
382 c_stream.next_out := compr;
383 c_stream.avail_in := 3;
384 c_stream.avail_out := Integer(comprLen);
385 err := deflate(c_stream, Z_FULL_FLUSH);
386 CHECK_ERR(err, 'deflate');
387
388 Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
389 c_stream.avail_in := len - 3;
390
391 err := deflate(c_stream, Z_FINISH);
392 if err <> Z_STREAM_END then
393 CHECK_ERR(err, 'deflate');
394
395 err := deflateEnd(c_stream);
396 CHECK_ERR(err, 'deflateEnd');
397
398 comprLen := c_stream.total_out;
399 end;
400 {$ENDIF}
401
402 (* ===========================================================================
403 * Test inflateSync()
404 *)
405 {$IFDEF TEST_SYNC}
406 procedure test_sync(compr: Pointer; comprLen: LongInt;
407 uncompr: Pointer; uncomprLen : LongInt);
408 var err: Integer;
409 d_stream: z_stream; (* decompression stream *)
410 begin
411 StrCopy(PChar(uncompr), 'garbage');
412
413 d_stream.zalloc := NIL;
414 d_stream.zfree := NIL;
415 d_stream.opaque := NIL;
416
417 d_stream.next_in := compr;
418 d_stream.avail_in := 2; (* just read the zlib header *)
419
420 err := inflateInit(d_stream);
421 CHECK_ERR(err, 'inflateInit');
422
423 d_stream.next_out := uncompr;
424 d_stream.avail_out := Integer(uncomprLen);
425
426 inflate(d_stream, Z_NO_FLUSH);
427 CHECK_ERR(err, 'inflate');
428
429 d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *)
430 err := inflateSync(d_stream); (* but skip the damaged part *)
431 CHECK_ERR(err, 'inflateSync');
432
433 err := inflate(d_stream, Z_FINISH);
434 if err <> Z_DATA_ERROR then
435 EXIT_ERR('inflate should report DATA_ERROR');
436 (* Because of incorrect adler32 *)
437
438 err := inflateEnd(d_stream);
439 CHECK_ERR(err, 'inflateEnd');
440
441 WriteLn('after inflateSync(): hel', PChar(uncompr));
442 end;
443 {$ENDIF}
444
445 (* ===========================================================================
446 * Test deflate with preset dictionary
447 *)
448 {$IFDEF TEST_DICT}
449 procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
450 var c_stream: z_stream; (* compression stream *)
451 err: Integer;
452 begin
453 c_stream.zalloc := NIL;
454 c_stream.zfree := NIL;
455 c_stream.opaque := NIL;
456
457 err := deflateInit(c_stream, Z_BEST_COMPRESSION);
458 CHECK_ERR(err, 'deflateInit');
459
460 err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
461 CHECK_ERR(err, 'deflateSetDictionary');
462
463 dictId := c_stream.adler;
464 c_stream.next_out := compr;
465 c_stream.avail_out := Integer(comprLen);
466
467 c_stream.next_in := hello;
468 c_stream.avail_in := StrLen(hello)+1;
469
470 err := deflate(c_stream, Z_FINISH);
471 if err <> Z_STREAM_END then
472 EXIT_ERR('deflate should report Z_STREAM_END');
473
474 err := deflateEnd(c_stream);
475 CHECK_ERR(err, 'deflateEnd');
476 end;
477 {$ENDIF}
478
479 (* ===========================================================================
480 * Test inflate with a preset dictionary
481 *)
482 {$IFDEF TEST_DICT}
483 procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
484 uncompr: Pointer; uncomprLen: LongInt);
485 var err: Integer;
486 d_stream: z_stream; (* decompression stream *)
487 begin
488 StrCopy(PChar(uncompr), 'garbage');
489
490 d_stream.zalloc := NIL;
491 d_stream.zfree := NIL;
492 d_stream.opaque := NIL;
493
494 d_stream.next_in := compr;
495 d_stream.avail_in := Integer(comprLen);
496
497 err := inflateInit(d_stream);
498 CHECK_ERR(err, 'inflateInit');
499
500 d_stream.next_out := uncompr;
501 d_stream.avail_out := Integer(uncomprLen);
502
503 while TRUE do
504 begin
505 err := inflate(d_stream, Z_NO_FLUSH);
506 if err = Z_STREAM_END then
507 break;
508 if err = Z_NEED_DICT then
509 begin
510 if d_stream.adler <> dictId then
511 EXIT_ERR('unexpected dictionary');
512 err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
513 end;
514 CHECK_ERR(err, 'inflate with dict');
515 end;
516
517 err := inflateEnd(d_stream);
518 CHECK_ERR(err, 'inflateEnd');
519
520 if StrComp(PChar(uncompr), hello) <> 0 then
521 EXIT_ERR('bad inflate with dict')
522 else
523 WriteLn('inflate with dictionary: ', PChar(uncompr));
524 end;
525 {$ENDIF}
526
527 var compr, uncompr: Pointer;
528 comprLen, uncomprLen: LongInt;
529
530 begin
531 if zlibVersion^ <> ZLIB_VERSION[1] then
532 EXIT_ERR('Incompatible zlib version');
533
534 WriteLn('zlib version: ', zlibVersion);
535 WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
536
537 comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
538 uncomprLen := comprLen;
539 GetMem(compr, comprLen);
540 GetMem(uncompr, uncomprLen);
541 if (compr = NIL) or (uncompr = NIL) then
542 EXIT_ERR('Out of memory');
543 (* compr and uncompr are cleared to avoid reading uninitialized
544 * data and to ensure that uncompr compresses well.
545 *)
546 FillChar(compr^, comprLen, 0);
547 FillChar(uncompr^, uncomprLen, 0);
548
549 {$IFDEF TEST_COMPRESS}
550 WriteLn('** Testing compress');
551 test_compress(compr, comprLen, uncompr, uncomprLen);
552 {$ENDIF}
553
554 {$IFDEF TEST_GZIO}
555 WriteLn('** Testing gzio');
556 if ParamCount >= 1 then
557 test_gzio(ParamStr(1), uncompr, uncomprLen)
558 else
559 test_gzio(TESTFILE, uncompr, uncomprLen);
560 {$ENDIF}
561
562 {$IFDEF TEST_DEFLATE}
563 WriteLn('** Testing deflate with small buffers');
564 test_deflate(compr, comprLen);
565 {$ENDIF}
566 {$IFDEF TEST_INFLATE}
567 WriteLn('** Testing inflate with small buffers');
568 test_inflate(compr, comprLen, uncompr, uncomprLen);
569 {$ENDIF}
570
571 {$IFDEF TEST_DEFLATE}
572 WriteLn('** Testing deflate with large buffers');
573 test_large_deflate(compr, comprLen, uncompr, uncomprLen);
574 {$ENDIF}
575 {$IFDEF TEST_INFLATE}
576 WriteLn('** Testing inflate with large buffers');
577 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
578 {$ENDIF}
579
580 {$IFDEF TEST_FLUSH}
581 WriteLn('** Testing deflate with full flush');
582 test_flush(compr, comprLen);
583 {$ENDIF}
584 {$IFDEF TEST_SYNC}
585 WriteLn('** Testing inflateSync');
586 test_sync(compr, comprLen, uncompr, uncomprLen);
587 {$ENDIF}
588 comprLen := uncomprLen;
589
590 {$IFDEF TEST_DICT}
591 WriteLn('** Testing deflate and inflate with preset dictionary');
592 test_dict_deflate(compr, comprLen);
593 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
594 {$ENDIF}
595
596 FreeMem(compr, comprLen);
597 FreeMem(uncompr, uncomprLen);
598 end.
0
1 This directory contains a Pascal (Delphi, Kylix) interface to the
2 zlib data compression library.
3
4
5 Directory listing
6 =================
7
8 zlibd32.mak makefile for Borland C++
9 example.pas usage example of zlib
10 zlibpas.pas the Pascal interface to zlib
11 readme.txt this file
12
13
14 Compatibility notes
15 ===================
16
17 - Although the name "zlib" would have been more normal for the
18 zlibpas unit, this name is already taken by Borland's ZLib unit.
19 This is somehow unfortunate, because that unit is not a genuine
20 interface to the full-fledged zlib functionality, but a suite of
21 class wrappers around zlib streams. Other essential features,
22 such as checksums, are missing.
23 It would have been more appropriate for that unit to have a name
24 like "ZStreams", or something similar.
25
26 - The C and zlib-supplied types int, uInt, long, uLong, etc. are
27 translated directly into Pascal types of similar sizes (Integer,
28 LongInt, etc.), to avoid namespace pollution. In particular,
29 there is no conversion of unsigned int into a Pascal unsigned
30 integer. The Word type is non-portable and has the same size
31 (16 bits) both in a 16-bit and in a 32-bit environment, unlike
32 Integer. Even if there is a 32-bit Cardinal type, there is no
33 real need for unsigned int in zlib under a 32-bit environment.
34
35 - Except for the callbacks, the zlib function interfaces are
36 assuming the calling convention normally used in Pascal
37 (__pascal for DOS and Windows16, __fastcall for Windows32).
38 Since the cdecl keyword is used, the old Turbo Pascal does
39 not work with this interface.
40
41 - The gz* function interfaces are not translated, to avoid
42 interfacing problems with the C runtime library. Besides,
43 gzprintf(gzFile file, const char *format, ...)
44 cannot be translated into Pascal.
45
46
47 Legal issues
48 ============
49
50 The zlibpas interface is:
51 Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.
52 Copyright (C) 1998 by Bob Dellaca.
53 Copyright (C) 2003 by Cosmin Truta.
54
55 The example program is:
56 Copyright (C) 1995-2003 by Jean-loup Gailly.
57 Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.
58 Copyright (C) 2003 by Cosmin Truta.
59
60 This software is provided 'as-is', without any express or implied
61 warranty. In no event will the author be held liable for any damages
62 arising from the use of this software.
63
64 Permission is granted to anyone to use this software for any purpose,
65 including commercial applications, and to alter it and redistribute it
66 freely, subject to the following restrictions:
67
68 1. The origin of this software must not be misrepresented; you must not
69 claim that you wrote the original software. If you use this software
70 in a product, an acknowledgment in the product documentation would be
71 appreciated but is not required.
72 2. Altered source versions must be plainly marked as such, and must not be
73 misrepresented as being the original software.
74 3. This notice may not be removed or altered from any source distribution.
75
0 # Makefile for zlib
1 # For use with Delphi and C++ Builder under Win32
2 # Updated for zlib 1.2.x by Cosmin Truta
3
4 # ------------ Borland C++ ------------
5
6 # This project uses the Delphi (fastcall/register) calling convention:
7 LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
8
9 CC = bcc32
10 LD = bcc32
11 AR = tlib
12 # do not use "-pr" in CFLAGS
13 CFLAGS = -a -d -k- -O2 $(LOC)
14 LDFLAGS =
15
16
17 # variables
18 ZLIB_LIB = zlib.lib
19
20 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
21 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
22 OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
23 OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
24
25
26 # targets
27 all: $(ZLIB_LIB) example.exe minigzip.exe
28
29 .c.obj:
30 $(CC) -c $(CFLAGS) $*.c
31
32 adler32.obj: adler32.c zlib.h zconf.h
33
34 compress.obj: compress.c zlib.h zconf.h
35
36 crc32.obj: crc32.c zlib.h zconf.h crc32.h
37
38 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
39
40 gzio.obj: gzio.c zutil.h zlib.h zconf.h
41
42 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
43 inffast.h inffixed.h
44
45 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
46 inffast.h
47
48 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
49 inffast.h inffixed.h
50
51 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
52
53 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
54
55 uncompr.obj: uncompr.c zlib.h zconf.h
56
57 zutil.obj: zutil.c zutil.h zlib.h zconf.h
58
59 example.obj: example.c zlib.h zconf.h
60
61 minigzip.obj: minigzip.c zlib.h zconf.h
62
63
64 # For the sake of the old Borland make,
65 # the command line is cut to fit in the MS-DOS 128 byte limit:
66 $(ZLIB_LIB): $(OBJ1) $(OBJ2)
67 -del $(ZLIB_LIB)
68 $(AR) $(ZLIB_LIB) $(OBJP1)
69 $(AR) $(ZLIB_LIB) $(OBJP2)
70
71
72 # testing
73 test: example.exe minigzip.exe
74 example
75 echo hello world | minigzip | minigzip -d
76
77 example.exe: example.obj $(ZLIB_LIB)
78 $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
79
80 minigzip.exe: minigzip.obj $(ZLIB_LIB)
81 $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
82
83
84 # cleanup
85 clean:
86 -del *.obj
87 -del *.exe
88 -del *.lib
89 -del *.tds
90 -del zlib.bak
91 -del foo.gz
92
0 (* zlibpas -- Pascal interface to the zlib data compression library
1 *
2 * Copyright (C) 2003 Cosmin Truta.
3 * Derived from original sources by Bob Dellaca.
4 * For conditions of distribution and use, see copyright notice in readme.txt
5 *)
6
7 unit zlibpas;
8
9 interface
10
11 const
12 ZLIB_VERSION = '1.2.2';
13
14 type
15 alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
16 cdecl;
17 free_func = procedure(opaque, address: Pointer);
18 cdecl;
19
20 in_func = function(opaque: Pointer; var buf: PByte): Integer;
21 cdecl;
22 out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer;
23 cdecl;
24
25 z_streamp = ^z_stream;
26 z_stream = packed record
27 next_in: PChar; (* next input byte *)
28 avail_in: Integer; (* number of bytes available at next_in *)
29 total_in: LongInt; (* total nb of input bytes read so far *)
30
31 next_out: PChar; (* next output byte should be put there *)
32 avail_out: Integer; (* remaining free space at next_out *)
33 total_out: LongInt; (* total nb of bytes output so far *)
34
35 msg: PChar; (* last error message, NULL if no error *)
36 state: Pointer; (* not visible by applications *)
37
38 zalloc: alloc_func; (* used to allocate the internal state *)
39 zfree: free_func; (* used to free the internal state *)
40 opaque: Pointer; (* private data object passed to zalloc and zfree *)
41
42 data_type: Integer; (* best guess about the data type: ascii or binary *)
43 adler: LongInt; (* adler32 value of the uncompressed data *)
44 reserved: LongInt; (* reserved for future use *)
45 end;
46
47 (* constants *)
48 const
49 Z_NO_FLUSH = 0;
50 Z_PARTIAL_FLUSH = 1;
51 Z_SYNC_FLUSH = 2;
52 Z_FULL_FLUSH = 3;
53 Z_FINISH = 4;
54
55 Z_OK = 0;
56 Z_STREAM_END = 1;
57 Z_NEED_DICT = 2;
58 Z_ERRNO = -1;
59 Z_STREAM_ERROR = -2;
60 Z_DATA_ERROR = -3;
61 Z_MEM_ERROR = -4;
62 Z_BUF_ERROR = -5;
63 Z_VERSION_ERROR = -6;
64
65 Z_NO_COMPRESSION = 0;
66 Z_BEST_SPEED = 1;
67 Z_BEST_COMPRESSION = 9;
68 Z_DEFAULT_COMPRESSION = -1;
69
70 Z_FILTERED = 1;
71 Z_HUFFMAN_ONLY = 2;
72 Z_RLE = 3;
73 Z_DEFAULT_STRATEGY = 0;
74
75 Z_BINARY = 0;
76 Z_ASCII = 1;
77 Z_UNKNOWN = 2;
78
79 Z_DEFLATED = 8;
80
81 (* basic functions *)
82 function zlibVersion: PChar;
83 function deflateInit(var strm: z_stream; level: Integer): Integer;
84 function deflate(var strm: z_stream; flush: Integer): Integer;
85 function deflateEnd(var strm: z_stream): Integer;
86 function inflateInit(var strm: z_stream): Integer;
87 function inflate(var strm: z_stream; flush: Integer): Integer;
88 function inflateEnd(var strm: z_stream): Integer;
89
90 (* advanced functions *)
91 function deflateInit2(var strm: z_stream; level, method, windowBits,
92 memLevel, strategy: Integer): Integer;
93 function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
94 dictLength: Integer): Integer;
95 function deflateCopy(var dest, source: z_stream): Integer;
96 function deflateReset(var strm: z_stream): Integer;
97 function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
98 function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
99 function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
100 function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
101 function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
102 dictLength: Integer): Integer;
103 function inflateSync(var strm: z_stream): Integer;
104 function inflateCopy(var dest, source: z_stream): Integer;
105 function inflateReset(var strm: z_stream): Integer;
106 function inflateBackInit(var strm: z_stream;
107 windowBits: Integer; window: PChar): Integer;
108 function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
109 out_fn: out_func; out_desc: Pointer): Integer;
110 function inflateBackEnd(var strm: z_stream): Integer;
111 function zlibCompileFlags: LongInt;
112
113 (* utility functions *)
114 function compress(dest: PChar; var destLen: LongInt;
115 const source: PChar; sourceLen: LongInt): Integer;
116 function compress2(dest: PChar; var destLen: LongInt;
117 const source: PChar; sourceLen: LongInt;
118 level: Integer): Integer;
119 function compressBound(sourceLen: LongInt): LongInt;
120 function uncompress(dest: PChar; var destLen: LongInt;
121 const source: PChar; sourceLen: LongInt): Integer;
122
123 (* checksum functions *)
124 function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
125 function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
126
127 (* various hacks, don't look :) *)
128 function deflateInit_(var strm: z_stream; level: Integer;
129 const version: PChar; stream_size: Integer): Integer;
130 function inflateInit_(var strm: z_stream; const version: PChar;
131 stream_size: Integer): Integer;
132 function deflateInit2_(var strm: z_stream;
133 level, method, windowBits, memLevel, strategy: Integer;
134 const version: PChar; stream_size: Integer): Integer;
135 function inflateInit2_(var strm: z_stream; windowBits: Integer;
136 const version: PChar; stream_size: Integer): Integer;
137 function inflateBackInit_(var strm: z_stream;
138 windowBits: Integer; window: PChar;
139 const version: PChar; stream_size: Integer): Integer;
140
141
142 implementation
143
144 {$L adler32.obj}
145 {$L compress.obj}
146 {$L crc32.obj}
147 {$L deflate.obj}
148 {$L infback.obj}
149 {$L inffast.obj}
150 {$L inflate.obj}
151 {$L inftrees.obj}
152 {$L trees.obj}
153 {$L uncompr.obj}
154 {$L zutil.obj}
155
156 function adler32; external;
157 function compress; external;
158 function compress2; external;
159 function compressBound; external;
160 function crc32; external;
161 function deflate; external;
162 function deflateBound; external;
163 function deflateCopy; external;
164 function deflateEnd; external;
165 function deflateInit_; external;
166 function deflateInit2_; external;
167 function deflateParams; external;
168 function deflatePrime; external;
169 function deflateReset; external;
170 function deflateSetDictionary; external;
171 function inflate; external;
172 function inflateBack; external;
173 function inflateBackEnd; external;
174 function inflateBackInit_; external;
175 function inflateCopy; external;
176 function inflateEnd; external;
177 function inflateInit_; external;
178 function inflateInit2_; external;
179 function inflateReset; external;
180 function inflateSetDictionary; external;
181 function inflateSync; external;
182 function uncompress; external;
183 function zlibCompileFlags; external;
184 function zlibVersion; external;
185
186 function deflateInit(var strm: z_stream; level: Integer): Integer;
187 begin
188 Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
189 end;
190
191 function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,
192 strategy: Integer): Integer;
193 begin
194 Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
195 ZLIB_VERSION, sizeof(z_stream));
196 end;
197
198 function inflateInit(var strm: z_stream): Integer;
199 begin
200 Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
201 end;
202
203 function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
204 begin
205 Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));
206 end;
207
208 function inflateBackInit(var strm: z_stream;
209 windowBits: Integer; window: PChar): Integer;
210 begin
211 Result := inflateBackInit_(strm, windowBits, window,
212 ZLIB_VERSION, sizeof(z_stream));
213 end;
214
215 function _malloc(Size: Integer): Pointer; cdecl;
216 begin
217 GetMem(Result, Size);
218 end;
219
220 procedure _free(Block: Pointer); cdecl;
221 begin
222 FreeMem(Block);
223 end;
224
225 procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
226 begin
227 FillChar(P^, count, B);
228 end;
229
230 procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
231 begin
232 Move(source^, dest^, count);
233 end;
234
235 end.
0 puff: puff.c puff.h
1 cc -DTEST -o puff puff.c
2
3 test: puff
4 puff zeros.raw
5
6 clean:
7 rm -f puff puff.o
0 Puff -- A Simple Inflate
1 3 Mar 2003
2 Mark Adler
3 madler@alumni.caltech.edu
4
5 What this is --
6
7 puff.c provides the routine puff() to decompress the deflate data format. It
8 does so more slowly than zlib, but the code is about one-fifth the size of the
9 inflate code in zlib, and written to be very easy to read.
10
11 Why I wrote this --
12
13 puff.c was written to document the deflate format unambiguously, by virtue of
14 being working C code. It is meant to supplement RFC 1951, which formally
15 describes the deflate format. I have received many questions on details of the
16 deflate format, and I hope that reading this code will answer those questions.
17 puff.c is heavily commented with details of the deflate format, especially
18 those little nooks and cranies of the format that might not be obvious from a
19 specification.
20
21 puff.c may also be useful in applications where code size or memory usage is a
22 very limited resource, and speed is not as important.
23
24 How to use it --
25
26 Well, most likely you should just be reading puff.c and using zlib for actual
27 applications, but if you must ...
28
29 Include puff.h in your code, which provides this prototype:
30
31 int puff(unsigned char *dest, /* pointer to destination pointer */
32 unsigned long *destlen, /* amount of output space */
33 unsigned char *source, /* pointer to source data pointer */
34 unsigned long *sourcelen); /* amount of input available */
35
36 Then you can call puff() to decompress a deflate stream that is in memory in
37 its entirety at source, to a sufficiently sized block of memory for the
38 decompressed data at dest. puff() is the only external symbol in puff.c The
39 only C library functions that puff.c needs are setjmp() and longjmp(), which
40 are used to simplify error checking in the code to improve readabilty. puff.c
41 does no memory allocation, and uses less than 2K bytes off of the stack.
42
43 If destlen is not enough space for the uncompressed data, then inflate will
44 return an error without writing more than destlen bytes. Note that this means
45 that in order to decompress the deflate data successfully, you need to know
46 the size of the uncompressed data ahead of time.
47
48 If needed, puff() can determine the size of the uncompressed data with no
49 output space. This is done by passing dest equal to (unsigned char *)0. Then
50 the initial value of *destlen is ignored and *destlen is set to the length of
51 the uncompressed data. So if the size of the uncompressed data is not known,
52 then two passes of puff() can be used--first to determine the size, and second
53 to do the actual inflation after allocating the appropriate memory. Not
54 pretty, but it works. (This is one of the reasons you should be using zlib.)
55
56 The deflate format is self-terminating. If the deflate stream does not end
57 in *sourcelen bytes, puff() will return an error without reading at or past
58 endsource.
59
60 On return, *sourcelen is updated to the amount of input data consumed, and
61 *destlen is updated to the size of the uncompressed data. See the comments
62 in puff.c for the possible return codes for puff().
0 /*
1 * puff.c
2 * Copyright (C) 2002-2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in puff.h
4 * version 1.8, 9 Jan 2004
5 *
6 * puff.c is a simple inflate written to be an unambiguous way to specify the
7 * deflate format. It is not written for speed but rather simplicity. As a
8 * side benefit, this code might actually be useful when small code is more
9 * important than speed, such as bootstrap applications. For typical deflate
10 * data, zlib's inflate() is about four times as fast as puff(). zlib's
11 * inflate compiles to around 20K on my machine, whereas puff.c compiles to
12 * around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
13 * function here is used, then puff() is only twice as slow as zlib's
14 * inflate().
15 *
16 * All dynamically allocated memory comes from the stack. The stack required
17 * is less than 2K bytes. This code is compatible with 16-bit int's and
18 * assumes that long's are at least 32 bits. puff.c uses the short data type,
19 * assumed to be 16 bits, for arrays in order to to conserve memory. The code
20 * works whether integers are stored big endian or little endian.
21 *
22 * In the comments below are "Format notes" that describe the inflate process
23 * and document some of the less obvious aspects of the format. This source
24 * code is meant to supplement RFC 1951, which formally describes the deflate
25 * format:
26 *
27 * http://www.zlib.org/rfc-deflate.html
28 */
29
30 /*
31 * Change history:
32 *
33 * 1.0 10 Feb 2002 - First version
34 * 1.1 17 Feb 2002 - Clarifications of some comments and notes
35 * - Update puff() dest and source pointers on negative
36 * errors to facilitate debugging deflators
37 * - Remove longest from struct huffman -- not needed
38 * - Simplify offs[] index in construct()
39 * - Add input size and checking, using longjmp() to
40 * maintain easy readability
41 * - Use short data type for large arrays
42 * - Use pointers instead of long to specify source and
43 * destination sizes to avoid arbitrary 4 GB limits
44 * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
45 * but leave simple version for readabilty
46 * - Make sure invalid distances detected if pointers
47 * are 16 bits
48 * - Fix fixed codes table error
49 * - Provide a scanning mode for determining size of
50 * uncompressed data
51 * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup]
52 * - Add a puff.h file for the interface
53 * - Add braces in puff() for else do [Jean-loup]
54 * - Use indexes instead of pointers for readability
55 * 1.4 31 Mar 2002 - Simplify construct() code set check
56 * - Fix some comments
57 * - Add FIXLCODES #define
58 * 1.5 6 Apr 2002 - Minor comment fixes
59 * 1.6 7 Aug 2002 - Minor format changes
60 * 1.7 3 Mar 2003 - Added test code for distribution
61 * - Added zlib-like license
62 * 1.8 9 Jan 2004 - Added some comments on no distance codes case
63 */
64
65 #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
66 #include "puff.h" /* prototype for puff() */
67
68 #define local static /* for local function definitions */
69 #define NIL ((unsigned char *)0) /* for no output option */
70
71 /*
72 * Maximums for allocations and loops. It is not useful to change these --
73 * they are fixed by the deflate format.
74 */
75 #define MAXBITS 15 /* maximum bits in a code */
76 #define MAXLCODES 286 /* maximum number of literal/length codes */
77 #define MAXDCODES 30 /* maximum number of distance codes */
78 #define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
79 #define FIXLCODES 288 /* number of fixed literal/length codes */
80
81 /* input and output state */
82 struct state {
83 /* output state */
84 unsigned char *out; /* output buffer */
85 unsigned long outlen; /* available space at out */
86 unsigned long outcnt; /* bytes written to out so far */
87
88 /* input state */
89 unsigned char *in; /* input buffer */
90 unsigned long inlen; /* available input at in */
91 unsigned long incnt; /* bytes read so far */
92 int bitbuf; /* bit buffer */
93 int bitcnt; /* number of bits in bit buffer */
94
95 /* input limit error return state for bits() and decode() */
96 jmp_buf env;
97 };
98
99 /*
100 * Return need bits from the input stream. This always leaves less than
101 * eight bits in the buffer. bits() works properly for need == 0.
102 *
103 * Format notes:
104 *
105 * - Bits are stored in bytes from the least significant bit to the most
106 * significant bit. Therefore bits are dropped from the bottom of the bit
107 * buffer, using shift right, and new bytes are appended to the top of the
108 * bit buffer, using shift left.
109 */
110 local int bits(struct state *s, int need)
111 {
112 long val; /* bit accumulator (can use up to 20 bits) */
113
114 /* load at least need bits into val */
115 val = s->bitbuf;
116 while (s->bitcnt < need) {
117 if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
118 val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
119 s->bitcnt += 8;
120 }
121
122 /* drop need bits and update buffer, always zero to seven bits left */
123 s->bitbuf = (int)(val >> need);
124 s->bitcnt -= need;
125
126 /* return need bits, zeroing the bits above that */
127 return (int)(val & ((1L << need) - 1));
128 }
129
130 /*
131 * Process a stored block.
132 *
133 * Format notes:
134 *
135 * - After the two-bit stored block type (00), the stored block length and
136 * stored bytes are byte-aligned for fast copying. Therefore any leftover
137 * bits in the byte that has the last bit of the type, as many as seven, are
138 * discarded. The value of the discarded bits are not defined and should not
139 * be checked against any expectation.
140 *
141 * - The second inverted copy of the stored block length does not have to be
142 * checked, but it's probably a good idea to do so anyway.
143 *
144 * - A stored block can have zero length. This is sometimes used to byte-align
145 * subsets of the compressed data for random access or partial recovery.
146 */
147 local int stored(struct state *s)
148 {
149 unsigned len; /* length of stored block */
150
151 /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
152 s->bitbuf = 0;
153 s->bitcnt = 0;
154
155 /* get length and check against its one's complement */
156 if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
157 len = s->in[s->incnt++];
158 len |= s->in[s->incnt++] << 8;
159 if (s->in[s->incnt++] != (~len & 0xff) ||
160 s->in[s->incnt++] != ((~len >> 8) & 0xff))
161 return -2; /* didn't match complement! */
162
163 /* copy len bytes from in to out */
164 if (s->incnt + len > s->inlen) return 2; /* not enough input */
165 if (s->out != NIL) {
166 if (s->outcnt + len > s->outlen)
167 return 1; /* not enough output space */
168 while (len--)
169 s->out[s->outcnt++] = s->in[s->incnt++];
170 }
171 else { /* just scanning */
172 s->outcnt += len;
173 s->incnt += len;
174 }
175
176 /* done with a valid stored block */
177 return 0;
178 }
179
180 /*
181 * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
182 * each length, which for a canonical code are stepped through in order.
183 * symbol[] are the symbol values in canonical order, where the number of
184 * entries is the sum of the counts in count[]. The decoding process can be
185 * seen in the function decode() below.
186 */
187 struct huffman {
188 short *count; /* number of symbols of each length */
189 short *symbol; /* canonically ordered symbols */
190 };
191
192 /*
193 * Decode a code from the stream s using huffman table h. Return the symbol or
194 * a negative value if there is an error. If all of the lengths are zero, i.e.
195 * an empty code, or if the code is incomplete and an invalid code is received,
196 * then -9 is returned after reading MAXBITS bits.
197 *
198 * Format notes:
199 *
200 * - The codes as stored in the compressed data are bit-reversed relative to
201 * a simple integer ordering of codes of the same lengths. Hence below the
202 * bits are pulled from the compressed data one at a time and used to
203 * build the code value reversed from what is in the stream in order to
204 * permit simple integer comparisons for decoding. A table-based decoding
205 * scheme (as used in zlib) does not need to do this reversal.
206 *
207 * - The first code for the shortest length is all zeros. Subsequent codes of
208 * the same length are simply integer increments of the previous code. When
209 * moving up a length, a zero bit is appended to the code. For a complete
210 * code, the last code of the longest length will be all ones.
211 *
212 * - Incomplete codes are handled by this decoder, since they are permitted
213 * in the deflate format. See the format notes for fixed() and dynamic().
214 */
215 #ifdef SLOW
216 local int decode(struct state *s, struct huffman *h)
217 {
218 int len; /* current number of bits in code */
219 int code; /* len bits being decoded */
220 int first; /* first code of length len */
221 int count; /* number of codes of length len */
222 int index; /* index of first code of length len in symbol table */
223
224 code = first = index = 0;
225 for (len = 1; len <= MAXBITS; len++) {
226 code |= bits(s, 1); /* get next bit */
227 count = h->count[len];
228 if (code < first + count) /* if length len, return symbol */
229 return h->symbol[index + (code - first)];
230 index += count; /* else update for next length */
231 first += count;
232 first <<= 1;
233 code <<= 1;
234 }
235 return -9; /* ran out of codes */
236 }
237
238 /*
239 * A faster version of decode() for real applications of this code. It's not
240 * as readable, but it makes puff() twice as fast. And it only makes the code
241 * a few percent larger.
242 */
243 #else /* !SLOW */
244 local int decode(struct state *s, struct huffman *h)
245 {
246 int len; /* current number of bits in code */
247 int code; /* len bits being decoded */
248 int first; /* first code of length len */
249 int count; /* number of codes of length len */
250 int index; /* index of first code of length len in symbol table */
251 int bitbuf; /* bits from stream */
252 int left; /* bits left in next or left to process */
253 short *next; /* next number of codes */
254
255 bitbuf = s->bitbuf;
256 left = s->bitcnt;
257 code = first = index = 0;
258 len = 1;
259 next = h->count + 1;
260 while (1) {
261 while (left--) {
262 code |= bitbuf & 1;
263 bitbuf >>= 1;
264 count = *next++;
265 if (code < first + count) { /* if length len, return symbol */
266 s->bitbuf = bitbuf;
267 s->bitcnt = (s->bitcnt - len) & 7;
268 return h->symbol[index + (code - first)];
269 }
270 index += count; /* else update for next length */
271 first += count;
272 first <<= 1;
273 code <<= 1;
274 len++;
275 }
276 left = (MAXBITS+1) - len;
277 if (left == 0) break;
278 if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
279 bitbuf = s->in[s->incnt++];
280 if (left > 8) left = 8;
281 }
282 return -9; /* ran out of codes */
283 }
284 #endif /* SLOW */
285
286 /*
287 * Given the list of code lengths length[0..n-1] representing a canonical
288 * Huffman code for n symbols, construct the tables required to decode those
289 * codes. Those tables are the number of codes of each length, and the symbols
290 * sorted by length, retaining their original order within each length. The
291 * return value is zero for a complete code set, negative for an over-
292 * subscribed code set, and positive for an incomplete code set. The tables
293 * can be used if the return value is zero or positive, but they cannot be used
294 * if the return value is negative. If the return value is zero, it is not
295 * possible for decode() using that table to return an error--any stream of
296 * enough bits will resolve to a symbol. If the return value is positive, then
297 * it is possible for decode() using that table to return an error for received
298 * codes past the end of the incomplete lengths.
299 *
300 * Not used by decode(), but used for error checking, h->count[0] is the number
301 * of the n symbols not in the code. So n - h->count[0] is the number of
302 * codes. This is useful for checking for incomplete codes that have more than
303 * one symbol, which is an error in a dynamic block.
304 *
305 * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
306 * This is assured by the construction of the length arrays in dynamic() and
307 * fixed() and is not verified by construct().
308 *
309 * Format notes:
310 *
311 * - Permitted and expected examples of incomplete codes are one of the fixed
312 * codes and any code with a single symbol which in deflate is coded as one
313 * bit instead of zero bits. See the format notes for fixed() and dynamic().
314 *
315 * - Within a given code length, the symbols are kept in ascending order for
316 * the code bits definition.
317 */
318 local int construct(struct huffman *h, short *length, int n)
319 {
320 int symbol; /* current symbol when stepping through length[] */
321 int len; /* current length when stepping through h->count[] */
322 int left; /* number of possible codes left of current length */
323 short offs[MAXBITS+1]; /* offsets in symbol table for each length */
324
325 /* count number of codes of each length */
326 for (len = 0; len <= MAXBITS; len++)
327 h->count[len] = 0;
328 for (symbol = 0; symbol < n; symbol++)
329 (h->count[length[symbol]])++; /* assumes lengths are within bounds */
330 if (h->count[0] == n) /* no codes! */
331 return 0; /* complete, but decode() will fail */
332
333 /* check for an over-subscribed or incomplete set of lengths */
334 left = 1; /* one possible code of zero length */
335 for (len = 1; len <= MAXBITS; len++) {
336 left <<= 1; /* one more bit, double codes left */
337 left -= h->count[len]; /* deduct count from possible codes */
338 if (left < 0) return left; /* over-subscribed--return negative */
339 } /* left > 0 means incomplete */
340
341 /* generate offsets into symbol table for each length for sorting */
342 offs[1] = 0;
343 for (len = 1; len < MAXBITS; len++)
344 offs[len + 1] = offs[len] + h->count[len];
345
346 /*
347 * put symbols in table sorted by length, by symbol order within each
348 * length
349 */
350 for (symbol = 0; symbol < n; symbol++)
351 if (length[symbol] != 0)
352 h->symbol[offs[length[symbol]]++] = symbol;
353
354 /* return zero for complete set, positive for incomplete set */
355 return left;
356 }
357
358 /*
359 * Decode literal/length and distance codes until an end-of-block code.
360 *
361 * Format notes:
362 *
363 * - Compressed data that is after the block type if fixed or after the code
364 * description if dynamic is a combination of literals and length/distance
365 * pairs terminated by and end-of-block code. Literals are simply Huffman
366 * coded bytes. A length/distance pair is a coded length followed by a
367 * coded distance to represent a string that occurs earlier in the
368 * uncompressed data that occurs again at the current location.
369 *
370 * - Literals, lengths, and the end-of-block code are combined into a single
371 * code of up to 286 symbols. They are 256 literals (0..255), 29 length
372 * symbols (257..285), and the end-of-block symbol (256).
373 *
374 * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
375 * to represent all of those. Lengths 3..10 and 258 are in fact represented
376 * by just a length symbol. Lengths 11..257 are represented as a symbol and
377 * some number of extra bits that are added as an integer to the base length
378 * of the length symbol. The number of extra bits is determined by the base
379 * length symbol. These are in the static arrays below, lens[] for the base
380 * lengths and lext[] for the corresponding number of extra bits.
381 *
382 * - The reason that 258 gets its own symbol is that the longest length is used
383 * often in highly redundant files. Note that 258 can also be coded as the
384 * base value 227 plus the maximum extra value of 31. While a good deflate
385 * should never do this, it is not an error, and should be decoded properly.
386 *
387 * - If a length is decoded, including its extra bits if any, then it is
388 * followed a distance code. There are up to 30 distance symbols. Again
389 * there are many more possible distances (1..32768), so extra bits are added
390 * to a base value represented by the symbol. The distances 1..4 get their
391 * own symbol, but the rest require extra bits. The base distances and
392 * corresponding number of extra bits are below in the static arrays dist[]
393 * and dext[].
394 *
395 * - Literal bytes are simply written to the output. A length/distance pair is
396 * an instruction to copy previously uncompressed bytes to the output. The
397 * copy is from distance bytes back in the output stream, copying for length
398 * bytes.
399 *
400 * - Distances pointing before the beginning of the output data are not
401 * permitted.
402 *
403 * - Overlapped copies, where the length is greater than the distance, are
404 * allowed and common. For example, a distance of one and a length of 258
405 * simply copies the last byte 258 times. A distance of four and a length of
406 * twelve copies the last four bytes three times. A simple forward copy
407 * ignoring whether the length is greater than the distance or not implements
408 * this correctly. You should not use memcpy() since its behavior is not
409 * defined for overlapped arrays. You should not use memmove() or bcopy()
410 * since though their behavior -is- defined for overlapping arrays, it is
411 * defined to do the wrong thing in this case.
412 */
413 local int codes(struct state *s,
414 struct huffman *lencode,
415 struct huffman *distcode)
416 {
417 int symbol; /* decoded symbol */
418 int len; /* length for copy */
419 unsigned dist; /* distance for copy */
420 static const short lens[29] = { /* Size base for length codes 257..285 */
421 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
422 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
423 static const short lext[29] = { /* Extra bits for length codes 257..285 */
424 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
425 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
426 static const short dists[30] = { /* Offset base for distance codes 0..29 */
427 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
428 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
429 8193, 12289, 16385, 24577};
430 static const short dext[30] = { /* Extra bits for distance codes 0..29 */
431 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
432 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
433 12, 12, 13, 13};
434
435 /* decode literals and length/distance pairs */
436 do {
437 symbol = decode(s, lencode);
438 if (symbol < 0) return symbol; /* invalid symbol */
439 if (symbol < 256) { /* literal: symbol is the byte */
440 /* write out the literal */
441 if (s->out != NIL) {
442 if (s->outcnt == s->outlen) return 1;
443 s->out[s->outcnt] = symbol;
444 }
445 s->outcnt++;
446 }
447 else if (symbol > 256) { /* length */
448 /* get and compute length */
449 symbol -= 257;
450 if (symbol >= 29) return -9; /* invalid fixed code */
451 len = lens[symbol] + bits(s, lext[symbol]);
452
453 /* get and check distance */
454 symbol = decode(s, distcode);
455 if (symbol < 0) return symbol; /* invalid symbol */
456 dist = dists[symbol] + bits(s, dext[symbol]);
457 if (dist > s->outcnt)
458 return -10; /* distance too far back */
459
460 /* copy length bytes from distance bytes back */
461 if (s->out != NIL) {
462 if (s->outcnt + len > s->outlen) return 1;
463 while (len--) {
464 s->out[s->outcnt] = s->out[s->outcnt - dist];
465 s->outcnt++;
466 }
467 }
468 else
469 s->outcnt += len;
470 }
471 } while (symbol != 256); /* end of block symbol */
472
473 /* done with a valid fixed or dynamic block */
474 return 0;
475 }
476
477 /*
478 * Process a fixed codes block.
479 *
480 * Format notes:
481 *
482 * - This block type can be useful for compressing small amounts of data for
483 * which the size of the code descriptions in a dynamic block exceeds the
484 * benefit of custom codes for that block. For fixed codes, no bits are
485 * spent on code descriptions. Instead the code lengths for literal/length
486 * codes and distance codes are fixed. The specific lengths for each symbol
487 * can be seen in the "for" loops below.
488 *
489 * - The literal/length code is complete, but has two symbols that are invalid
490 * and should result in an error if received. This cannot be implemented
491 * simply as an incomplete code since those two symbols are in the "middle"
492 * of the code. They are eight bits long and the longest literal/length\
493 * code is nine bits. Therefore the code must be constructed with those
494 * symbols, and the invalid symbols must be detected after decoding.
495 *
496 * - The fixed distance codes also have two invalid symbols that should result
497 * in an error if received. Since all of the distance codes are the same
498 * length, this can be implemented as an incomplete code. Then the invalid
499 * codes are detected while decoding.
500 */
501 local int fixed(struct state *s)
502 {
503 static int virgin = 1;
504 static short lencnt[MAXBITS+1], lensym[FIXLCODES];
505 static short distcnt[MAXBITS+1], distsym[MAXDCODES];
506 static struct huffman lencode = {lencnt, lensym};
507 static struct huffman distcode = {distcnt, distsym};
508
509 /* build fixed huffman tables if first call (may not be thread safe) */
510 if (virgin) {
511 int symbol;
512 short lengths[FIXLCODES];
513
514 /* literal/length table */
515 for (symbol = 0; symbol < 144; symbol++)
516 lengths[symbol] = 8;
517 for (; symbol < 256; symbol++)
518 lengths[symbol] = 9;
519 for (; symbol < 280; symbol++)
520 lengths[symbol] = 7;
521 for (; symbol < FIXLCODES; symbol++)
522 lengths[symbol] = 8;
523 construct(&lencode, lengths, FIXLCODES);
524
525 /* distance table */
526 for (symbol = 0; symbol < MAXDCODES; symbol++)
527 lengths[symbol] = 5;
528 construct(&distcode, lengths, MAXDCODES);
529
530 /* do this just once */
531 virgin = 0;
532 }
533
534 /* decode data until end-of-block code */
535 return codes(s, &lencode, &distcode);
536 }
537
538 /*
539 * Process a dynamic codes block.
540 *
541 * Format notes:
542 *
543 * - A dynamic block starts with a description of the literal/length and
544 * distance codes for that block. New dynamic blocks allow the compressor to
545 * rapidly adapt to changing data with new codes optimized for that data.
546 *
547 * - The codes used by the deflate format are "canonical", which means that
548 * the actual bits of the codes are generated in an unambiguous way simply
549 * from the number of bits in each code. Therefore the code descriptions
550 * are simply a list of code lengths for each symbol.
551 *
552 * - The code lengths are stored in order for the symbols, so lengths are
553 * provided for each of the literal/length symbols, and for each of the
554 * distance symbols.
555 *
556 * - If a symbol is not used in the block, this is represented by a zero as
557 * as the code length. This does not mean a zero-length code, but rather
558 * that no code should be created for this symbol. There is no way in the
559 * deflate format to represent a zero-length code.
560 *
561 * - The maximum number of bits in a code is 15, so the possible lengths for
562 * any code are 1..15.
563 *
564 * - The fact that a length of zero is not permitted for a code has an
565 * interesting consequence. Normally if only one symbol is used for a given
566 * code, then in fact that code could be represented with zero bits. However
567 * in deflate, that code has to be at least one bit. So for example, if
568 * only a single distance base symbol appears in a block, then it will be
569 * represented by a single code of length one, in particular one 0 bit. This
570 * is an incomplete code, since if a 1 bit is received, it has no meaning,
571 * and should result in an error. So incomplete distance codes of one symbol
572 * should be permitted, and the receipt of invalid codes should be handled.
573 *
574 * - It is also possible to have a single literal/length code, but that code
575 * must be the end-of-block code, since every dynamic block has one. This
576 * is not the most efficient way to create an empty block (an empty fixed
577 * block is fewer bits), but it is allowed by the format. So incomplete
578 * literal/length codes of one symbol should also be permitted.
579 *
580 * - If there are only literal codes and no lengths, then there are no distance
581 * codes. This is represented by one distance code with zero bits.
582 *
583 * - The list of up to 286 length/literal lengths and up to 30 distance lengths
584 * are themselves compressed using Huffman codes and run-length encoding. In
585 * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
586 * that length, and the symbols 16, 17, and 18 are run-length instructions.
587 * Each of 16, 17, and 18 are follwed by extra bits to define the length of
588 * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
589 * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
590 * are common, hence the special coding for zero lengths.
591 *
592 * - The symbols for 0..18 are Huffman coded, and so that code must be
593 * described first. This is simply a sequence of up to 19 three-bit values
594 * representing no code (0) or the code length for that symbol (1..7).
595 *
596 * - A dynamic block starts with three fixed-size counts from which is computed
597 * the number of literal/length code lengths, the number of distance code
598 * lengths, and the number of code length code lengths (ok, you come up with
599 * a better name!) in the code descriptions. For the literal/length and
600 * distance codes, lengths after those provided are considered zero, i.e. no
601 * code. The code length code lengths are received in a permuted order (see
602 * the order[] array below) to make a short code length code length list more
603 * likely. As it turns out, very short and very long codes are less likely
604 * to be seen in a dynamic code description, hence what may appear initially
605 * to be a peculiar ordering.
606 *
607 * - Given the number of literal/length code lengths (nlen) and distance code
608 * lengths (ndist), then they are treated as one long list of nlen + ndist
609 * code lengths. Therefore run-length coding can and often does cross the
610 * boundary between the two sets of lengths.
611 *
612 * - So to summarize, the code description at the start of a dynamic block is
613 * three counts for the number of code lengths for the literal/length codes,
614 * the distance codes, and the code length codes. This is followed by the
615 * code length code lengths, three bits each. This is used to construct the
616 * code length code which is used to read the remainder of the lengths. Then
617 * the literal/length code lengths and distance lengths are read as a single
618 * set of lengths using the code length codes. Codes are constructed from
619 * the resulting two sets of lengths, and then finally you can start
620 * decoding actual compressed data in the block.
621 *
622 * - For reference, a "typical" size for the code description in a dynamic
623 * block is around 80 bytes.
624 */
625 local int dynamic(struct state *s)
626 {
627 int nlen, ndist, ncode; /* number of lengths in descriptor */
628 int index; /* index of lengths[] */
629 int err; /* construct() return value */
630 short lengths[MAXCODES]; /* descriptor code lengths */
631 short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
632 short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
633 struct huffman lencode = {lencnt, lensym}; /* length code */
634 struct huffman distcode = {distcnt, distsym}; /* distance code */
635 static const short order[19] = /* permutation of code length codes */
636 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
637
638 /* get number of lengths in each table, check lengths */
639 nlen = bits(s, 5) + 257;
640 ndist = bits(s, 5) + 1;
641 ncode = bits(s, 4) + 4;
642 if (nlen > MAXLCODES || ndist > MAXDCODES)
643 return -3; /* bad counts */
644
645 /* read code length code lengths (really), missing lengths are zero */
646 for (index = 0; index < ncode; index++)
647 lengths[order[index]] = bits(s, 3);
648 for (; index < 19; index++)
649 lengths[order[index]] = 0;
650
651 /* build huffman table for code lengths codes (use lencode temporarily) */
652 err = construct(&lencode, lengths, 19);
653 if (err != 0) return -4; /* require complete code set here */
654
655 /* read length/literal and distance code length tables */
656 index = 0;
657 while (index < nlen + ndist) {
658 int symbol; /* decoded value */
659 int len; /* last length to repeat */
660
661 symbol = decode(s, &lencode);
662 if (symbol < 16) /* length in 0..15 */
663 lengths[index++] = symbol;
664 else { /* repeat instruction */
665 len = 0; /* assume repeating zeros */
666 if (symbol == 16) { /* repeat last length 3..6 times */
667 if (index == 0) return -5; /* no last length! */
668 len = lengths[index - 1]; /* last length */
669 symbol = 3 + bits(s, 2);
670 }
671 else if (symbol == 17) /* repeat zero 3..10 times */
672 symbol = 3 + bits(s, 3);
673 else /* == 18, repeat zero 11..138 times */
674 symbol = 11 + bits(s, 7);
675 if (index + symbol > nlen + ndist)
676 return -6; /* too many lengths! */
677 while (symbol--) /* repeat last or zero symbol times */
678 lengths[index++] = len;
679 }
680 }
681
682 /* build huffman table for literal/length codes */
683 err = construct(&lencode, lengths, nlen);
684 if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
685 return -7; /* only allow incomplete codes if just one code */
686
687 /* build huffman table for distance codes */
688 err = construct(&distcode, lengths + nlen, ndist);
689 if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
690 return -8; /* only allow incomplete codes if just one code */
691
692 /* decode data until end-of-block code */
693 return codes(s, &lencode, &distcode);
694 }
695
696 /*
697 * Inflate source to dest. On return, destlen and sourcelen are updated to the
698 * size of the uncompressed data and the size of the deflate data respectively.
699 * On success, the return value of puff() is zero. If there is an error in the
700 * source data, i.e. it is not in the deflate format, then a negative value is
701 * returned. If there is not enough input available or there is not enough
702 * output space, then a positive error is returned. In that case, destlen and
703 * sourcelen are not updated to facilitate retrying from the beginning with the
704 * provision of more input data or more output space. In the case of invalid
705 * inflate data (a negative error), the dest and source pointers are updated to
706 * facilitate the debugging of deflators.
707 *
708 * puff() also has a mode to determine the size of the uncompressed output with
709 * no output written. For this dest must be (unsigned char *)0. In this case,
710 * the input value of *destlen is ignored, and on return *destlen is set to the
711 * size of the uncompressed output.
712 *
713 * The return codes are:
714 *
715 * 2: available inflate data did not terminate
716 * 1: output space exhausted before completing inflate
717 * 0: successful inflate
718 * -1: invalid block type (type == 3)
719 * -2: stored block length did not match one's complement
720 * -3: dynamic block code description: too many length or distance codes
721 * -4: dynamic block code description: code lengths codes incomplete
722 * -5: dynamic block code description: repeat lengths with no first length
723 * -6: dynamic block code description: repeat more than specified lengths
724 * -7: dynamic block code description: invalid literal/length code lengths
725 * -8: dynamic block code description: invalid distance code lengths
726 * -9: invalid literal/length or distance code in fixed or dynamic block
727 * -10: distance is too far back in fixed or dynamic block
728 *
729 * Format notes:
730 *
731 * - Three bits are read for each block to determine the kind of block and
732 * whether or not it is the last block. Then the block is decoded and the
733 * process repeated if it was not the last block.
734 *
735 * - The leftover bits in the last byte of the deflate data after the last
736 * block (if it was a fixed or dynamic block) are undefined and have no
737 * expected values to check.
738 */
739 int puff(unsigned char *dest, /* pointer to destination pointer */
740 unsigned long *destlen, /* amount of output space */
741 unsigned char *source, /* pointer to source data pointer */
742 unsigned long *sourcelen) /* amount of input available */
743 {
744 struct state s; /* input/output state */
745 int last, type; /* block information */
746 int err; /* return value */
747
748 /* initialize output state */
749 s.out = dest;
750 s.outlen = *destlen; /* ignored if dest is NIL */
751 s.outcnt = 0;
752
753 /* initialize input state */
754 s.in = source;
755 s.inlen = *sourcelen;
756 s.incnt = 0;
757 s.bitbuf = 0;
758 s.bitcnt = 0;
759
760 /* return if bits() or decode() tries to read past available input */
761 if (setjmp(s.env) != 0) /* if came back here via longjmp() */
762 err = 2; /* then skip do-loop, return error */
763 else {
764 /* process blocks until last block or error */
765 do {
766 last = bits(&s, 1); /* one if last block */
767 type = bits(&s, 2); /* block type 0..3 */
768 err = type == 0 ? stored(&s) :
769 (type == 1 ? fixed(&s) :
770 (type == 2 ? dynamic(&s) :
771 -1)); /* type == 3, invalid */
772 if (err != 0) break; /* return with error */
773 } while (!last);
774 }
775
776 /* update the lengths and return */
777 if (err <= 0) {
778 *destlen = s.outcnt;
779 *sourcelen = s.incnt;
780 }
781 return err;
782 }
783
784 #ifdef TEST
785 /* Example of how to use puff() */
786 #include <stdio.h>
787 #include <stdlib.h>
788 #include <sys/types.h>
789 #include <sys/stat.h>
790
791 local unsigned char *yank(char *name, unsigned long *len)
792 {
793 unsigned long size;
794 unsigned char *buf;
795 FILE *in;
796 struct stat s;
797
798 *len = 0;
799 if (stat(name, &s)) return NULL;
800 if ((s.st_mode & S_IFMT) != S_IFREG) return NULL;
801 size = (unsigned long)(s.st_size);
802 if (size == 0 || (off_t)size != s.st_size) return NULL;
803 in = fopen(name, "r");
804 if (in == NULL) return NULL;
805 buf = malloc(size);
806 if (buf != NULL && fread(buf, 1, size, in) != size) {
807 free(buf);
808 buf = NULL;
809 }
810 fclose(in);
811 *len = size;
812 return buf;
813 }
814
815 int main(int argc, char **argv)
816 {
817 int ret;
818 unsigned char *source;
819 unsigned long len, sourcelen, destlen;
820
821 if (argc < 2) return 2;
822 source = yank(argv[1], &len);
823 if (source == NULL) return 2;
824 sourcelen = len;
825 ret = puff(NIL, &destlen, source, &sourcelen);
826 if (ret)
827 printf("puff() failed with return code %d\n", ret);
828 else {
829 printf("puff() succeeded uncompressing %lu bytes\n", destlen);
830 if (sourcelen < len) printf("%lu compressed bytes unused\n",
831 len - sourcelen);
832 }
833 free(source);
834 return ret;
835 }
836 #endif
0 /* puff.h
1 Copyright (C) 2002, 2003 Mark Adler, all rights reserved
2 version 1.7, 3 Mar 2002
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the author be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Mark Adler madler@alumni.caltech.edu
21 */
22
23
24 /*
25 * See puff.c for purpose and usage.
26 */
27 int puff(unsigned char *dest, /* pointer to destination pointer */
28 unsigned long *destlen, /* amount of output space */
29 unsigned char *source, /* pointer to source data pointer */
30 unsigned long *sourcelen); /* amount of input available */
0
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <windows.h>
4 #include "zlib.h"
5
6 int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
7 {
8 FILE* stream;
9 void* ptr;
10 int retVal=1;
11 stream=fopen(filename, "rb");
12 if (stream==NULL)
13 return 0;
14
15 fseek(stream,0,SEEK_END);
16
17 *plFileSize=ftell(stream);
18 fseek(stream,0,SEEK_SET);
19 ptr=malloc((*plFileSize)+1);
20 if (ptr==NULL)
21 retVal=0;
22 else
23 {
24 if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
25 retVal=0;
26 }
27 fclose(stream);
28 *pFilePtr=ptr;
29 return retVal;
30 }
31
32 int main(int argc, char *argv[])
33 {
34 int BlockSizeCompress=0x8000;
35 int BlockSizeUncompress=0x8000;
36 int cprLevel=Z_DEFAULT_COMPRESSION ;
37 long lFileSize;
38 unsigned char* FilePtr;
39 long lBufferSizeCpr;
40 long lBufferSizeUncpr;
41 long lCompressedSize=0;
42 unsigned char* CprPtr;
43 unsigned char* UncprPtr;
44 long lSizeCpr,lSizeUncpr;
45 DWORD dwGetTick;
46
47 if (argc<=1)
48 {
49 printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
50 return 0;
51 }
52
53 if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
54 {
55 printf("error reading %s\n",argv[1]);
56 return 1;
57 }
58 else printf("file %s read, %u bytes\n",argv[1],lFileSize);
59
60 if (argc>=3)
61 BlockSizeCompress=atol(argv[2]);
62
63 if (argc>=4)
64 BlockSizeUncompress=atol(argv[3]);
65
66 if (argc>=5)
67 cprLevel=(int)atol(argv[4]);
68
69 lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
70 lBufferSizeUncpr = lBufferSizeCpr;
71
72 CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
73 UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
74
75 dwGetTick=GetTickCount();
76 {
77 z_stream zcpr;
78 int ret=Z_OK;
79 long lOrigToDo = lFileSize;
80 long lOrigDone = 0;
81 int step=0;
82 memset(&zcpr,0,sizeof(z_stream));
83 deflateInit(&zcpr,cprLevel);
84
85 zcpr.next_in = FilePtr;
86 zcpr.next_out = CprPtr;
87
88
89 do
90 {
91 long all_read_before = zcpr.total_in;
92 zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
93 zcpr.avail_out = BlockSizeCompress;
94 ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
95 lOrigDone += (zcpr.total_in-all_read_before);
96 lOrigToDo -= (zcpr.total_in-all_read_before);
97 step++;
98 } while (ret==Z_OK);
99
100 lSizeCpr=zcpr.total_out;
101 deflateEnd(&zcpr);
102 dwGetTick=GetTickCount()-dwGetTick;
103 printf("total compress size = %u, in %u step\n",lSizeCpr,step);
104 printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
105 }
106
107 dwGetTick=GetTickCount();
108 {
109 z_stream zcpr;
110 int ret=Z_OK;
111 long lOrigToDo = lSizeCpr;
112 long lOrigDone = 0;
113 int step=0;
114 memset(&zcpr,0,sizeof(z_stream));
115 inflateInit(&zcpr);
116
117 zcpr.next_in = CprPtr;
118 zcpr.next_out = UncprPtr;
119
120
121 do
122 {
123 long all_read_before = zcpr.total_in;
124 zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
125 zcpr.avail_out = BlockSizeUncompress;
126 ret=inflate(&zcpr,Z_SYNC_FLUSH);
127 lOrigDone += (zcpr.total_in-all_read_before);
128 lOrigToDo -= (zcpr.total_in-all_read_before);
129 step++;
130 } while (ret==Z_OK);
131
132 lSizeUncpr=zcpr.total_out;
133 inflateEnd(&zcpr);
134 dwGetTick=GetTickCount()-dwGetTick;
135 printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
136 printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
137 }
138
139 if (lSizeUncpr==lFileSize)
140 {
141 if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
142 printf("compare ok\n");
143
144 }
145
146 return 0;
147
148 }
0 Microsoft Visual Studio Solution File, Format Version 7.00
1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
2 EndProject
3 Global
4 GlobalSection(SolutionConfiguration) = preSolution
5 ConfigName.0 = Debug
6 ConfigName.1 = Release
7 EndGlobalSection
8 GlobalSection(ProjectDependencies) = postSolution
9 EndGlobalSection
10 GlobalSection(ProjectConfiguration) = postSolution
11 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug.ActiveCfg = Debug|Win32
12 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug.Build.0 = Debug|Win32
13 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release.ActiveCfg = Release|Win32
14 {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release.Build.0 = Release|Win32
15 EndGlobalSection
16 GlobalSection(ExtensibilityGlobals) = postSolution
17 EndGlobalSection
18 GlobalSection(ExtensibilityAddIns) = postSolution
19 EndGlobalSection
20 EndGlobal
0 <?xml version="1.0" encoding = "Windows-1252"?>
1 <VisualStudioProject
2 ProjectType="Visual C++"
3 Version="7.00"
4 Name="testzlib"
5 ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
6 Keyword="Win32Proj">
7 <Platforms>
8 <Platform
9 Name="Win32"/>
10 </Platforms>
11 <Configurations>
12 <Configuration
13 Name="Debug|Win32"
14 OutputDirectory="Debug"
15 IntermediateDirectory="Debug"
16 ConfigurationType="1"
17 CharacterSet="2">
18 <Tool
19 Name="VCCLCompilerTool"
20 Optimization="0"
21 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
22 MinimalRebuild="TRUE"
23 BasicRuntimeChecks="3"
24 RuntimeLibrary="5"
25 UsePrecompiledHeader="0"
26 WarningLevel="3"
27 Detect64BitPortabilityProblems="TRUE"
28 DebugInformationFormat="4"/>
29 <Tool
30 Name="VCCustomBuildTool"/>
31 <Tool
32 Name="VCLinkerTool"
33 OutputFile="$(OutDir)/testzlib.exe"
34 LinkIncremental="2"
35 GenerateDebugInformation="TRUE"
36 ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
37 SubSystem="1"
38 TargetMachine="1"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCWebDeploymentTool"/>
53 </Configuration>
54 <Configuration
55 Name="Release|Win32"
56 OutputDirectory="Release"
57 IntermediateDirectory="Release"
58 ConfigurationType="1"
59 CharacterSet="2">
60 <Tool
61 Name="VCCLCompilerTool"
62 Optimization="2"
63 InlineFunctionExpansion="1"
64 OmitFramePointers="TRUE"
65 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
66 StringPooling="TRUE"
67 RuntimeLibrary="4"
68 EnableFunctionLevelLinking="TRUE"
69 UsePrecompiledHeader="0"
70 WarningLevel="3"
71 Detect64BitPortabilityProblems="TRUE"
72 DebugInformationFormat="3"/>
73 <Tool
74 Name="VCCustomBuildTool"/>
75 <Tool
76 Name="VCLinkerTool"
77 OutputFile="$(OutDir)/testzlib.exe"
78 LinkIncremental="1"
79 GenerateDebugInformation="TRUE"
80 SubSystem="1"
81 OptimizeReferences="2"
82 EnableCOMDATFolding="2"
83 OptimizeForWindows98="1"
84 TargetMachine="1"/>
85 <Tool
86 Name="VCMIDLTool"/>
87 <Tool
88 Name="VCPostBuildEventTool"/>
89 <Tool
90 Name="VCPreBuildEventTool"/>
91 <Tool
92 Name="VCPreLinkEventTool"/>
93 <Tool
94 Name="VCResourceCompilerTool"/>
95 <Tool
96 Name="VCWebServiceProxyGeneratorTool"/>
97 <Tool
98 Name="VCWebDeploymentTool"/>
99 </Configuration>
100 </Configurations>
101 <Files>
102 <Filter
103 Name="Source Files"
104 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
105 <File
106 RelativePath="testzlib.c">
107 </File>
108 </Filter>
109 <Filter
110 Name="Header Files"
111 Filter="h;hpp;hxx;hm;inl;inc">
112 </Filter>
113 <Filter
114 Name="Resource Files"
115 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
116 </Filter>
117 <File
118 RelativePath="zlibwapi.lib">
119 </File>
120 </Files>
121 <Globals>
122 </Globals>
123 </VisualStudioProject>
0 CC=cc
1 CFLAGS=-g
2
3 untgz: untgz.o ../../libz.a
4 $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz
5
6 untgz.o: untgz.c ../../zlib.h
7 $(CC) $(CFLAGS) -c -I../.. untgz.c
8
9 ../../libz.a:
10 cd ../..; ./configure; make
11
12 clean:
13 rm -f untgz untgz.o *~
0 CC=cl
1 CFLAGS=-MD
2
3 untgz.exe: untgz.obj ..\..\zlib.lib
4 $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib
5
6 untgz.obj: untgz.c ..\..\zlib.h
7 $(CC) $(CFLAGS) -c -I..\.. untgz.c
8
9 ..\..\zlib.lib:
10 cd ..\..
11 $(MAKE) -f win32\makefile.msc
12 cd contrib\untgz
13
14 clean:
15 -del untgz.obj
16 -del untgz.exe
0 /*
1 * untgz.c -- Display contents and extract files from a gzip'd TAR file
2 *
3 * written by Pedro A. Aranda Gutierrez <paag@tid.es>
4 * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
5 * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <errno.h>
13
14 #include "zlib.h"
15
16 #ifdef unix
17 # include <unistd.h>
18 #else
19 # include <direct.h>
20 # include <io.h>
21 #endif
22
23 #ifdef WIN32
24 #include <windows.h>
25 # ifndef F_OK
26 # define F_OK 0
27 # endif
28 # define mkdir(dirname,mode) _mkdir(dirname)
29 # ifdef _MSC_VER
30 # define access(path,mode) _access(path,mode)
31 # define chmod(path,mode) _chmod(path,mode)
32 # define strdup(str) _strdup(str)
33 # endif
34 #else
35 # include <utime.h>
36 #endif
37
38
39 /* values used in typeflag field */
40
41 #define REGTYPE '0' /* regular file */
42 #define AREGTYPE '\0' /* regular file */
43 #define LNKTYPE '1' /* link */
44 #define SYMTYPE '2' /* reserved */
45 #define CHRTYPE '3' /* character special */
46 #define BLKTYPE '4' /* block special */
47 #define DIRTYPE '5' /* directory */
48 #define FIFOTYPE '6' /* FIFO special */
49 #define CONTTYPE '7' /* reserved */
50
51 /* GNU tar extensions */
52
53 #define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
54 #define GNUTYPE_LONGLINK 'K' /* long link name */
55 #define GNUTYPE_LONGNAME 'L' /* long file name */
56 #define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
57 #define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
58 #define GNUTYPE_SPARSE 'S' /* sparse file */
59 #define GNUTYPE_VOLHDR 'V' /* tape/volume header */
60
61
62 /* tar header */
63
64 #define BLOCKSIZE 512
65 #define SHORTNAMESIZE 100
66
67 struct tar_header
68 { /* byte offset */
69 char name[100]; /* 0 */
70 char mode[8]; /* 100 */
71 char uid[8]; /* 108 */
72 char gid[8]; /* 116 */
73 char size[12]; /* 124 */
74 char mtime[12]; /* 136 */
75 char chksum[8]; /* 148 */
76 char typeflag; /* 156 */
77 char linkname[100]; /* 157 */
78 char magic[6]; /* 257 */
79 char version[2]; /* 263 */
80 char uname[32]; /* 265 */
81 char gname[32]; /* 297 */
82 char devmajor[8]; /* 329 */
83 char devminor[8]; /* 337 */
84 char prefix[155]; /* 345 */
85 /* 500 */
86 };
87
88 union tar_buffer
89 {
90 char buffer[BLOCKSIZE];
91 struct tar_header header;
92 };
93
94 struct attr_item
95 {
96 struct attr_item *next;
97 char *fname;
98 int mode;
99 time_t time;
100 };
101
102 enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
103
104 char *TGZfname OF((const char *));
105 void TGZnotfound OF((const char *));
106
107 int getoct OF((char *, int));
108 char *strtime OF((time_t *));
109 int setfiletime OF((char *, time_t));
110 void push_attr OF((struct attr_item **, char *, int, time_t));
111 void restore_attr OF((struct attr_item **));
112
113 int ExprMatch OF((char *, char *));
114
115 int makedir OF((char *));
116 int matchname OF((int, int, char **, char *));
117
118 void error OF((const char *));
119 int tar OF((gzFile, int, int, int, char **));
120
121 void help OF((int));
122 int main OF((int, char **));
123
124 char *prog;
125
126 const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
127
128 /* return the file name of the TGZ archive */
129 /* or NULL if it does not exist */
130
131 char *TGZfname (const char *arcname)
132 {
133 static char buffer[1024];
134 int origlen,i;
135
136 strcpy(buffer,arcname);
137 origlen = strlen(buffer);
138
139 for (i=0; TGZsuffix[i]; i++)
140 {
141 strcpy(buffer+origlen,TGZsuffix[i]);
142 if (access(buffer,F_OK) == 0)
143 return buffer;
144 }
145 return NULL;
146 }
147
148
149 /* error message for the filename */
150
151 void TGZnotfound (const char *arcname)
152 {
153 int i;
154
155 fprintf(stderr,"%s: Couldn't find ",prog);
156 for (i=0;TGZsuffix[i];i++)
157 fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
158 arcname,
159 TGZsuffix[i]);
160 exit(1);
161 }
162
163
164 /* convert octal digits to int */
165 /* on error return -1 */
166
167 int getoct (char *p,int width)
168 {
169 int result = 0;
170 char c;
171
172 while (width--)
173 {
174 c = *p++;
175 if (c == 0)
176 break;
177 if (c == ' ')
178 continue;
179 if (c < '0' || c > '7')
180 return -1;
181 result = result * 8 + (c - '0');
182 }
183 return result;
184 }
185
186
187 /* convert time_t to string */
188 /* use the "YYYY/MM/DD hh:mm:ss" format */
189
190 char *strtime (time_t *t)
191 {
192 struct tm *local;
193 static char result[32];
194
195 local = localtime(t);
196 sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
197 local->tm_year+1900, local->tm_mon+1, local->tm_mday,
198 local->tm_hour, local->tm_min, local->tm_sec);
199 return result;
200 }
201
202
203 /* set file time */
204
205 int setfiletime (char *fname,time_t ftime)
206 {
207 #ifdef WIN32
208 static int isWinNT = -1;
209 SYSTEMTIME st;
210 FILETIME locft, modft;
211 struct tm *loctm;
212 HANDLE hFile;
213 int result;
214
215 loctm = localtime(&ftime);
216 if (loctm == NULL)
217 return -1;
218
219 st.wYear = (WORD)loctm->tm_year + 1900;
220 st.wMonth = (WORD)loctm->tm_mon + 1;
221 st.wDayOfWeek = (WORD)loctm->tm_wday;
222 st.wDay = (WORD)loctm->tm_mday;
223 st.wHour = (WORD)loctm->tm_hour;
224 st.wMinute = (WORD)loctm->tm_min;
225 st.wSecond = (WORD)loctm->tm_sec;
226 st.wMilliseconds = 0;
227 if (!SystemTimeToFileTime(&st, &locft) ||
228 !LocalFileTimeToFileTime(&locft, &modft))
229 return -1;
230
231 if (isWinNT < 0)
232 isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
233 hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
234 (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
235 NULL);
236 if (hFile == INVALID_HANDLE_VALUE)
237 return -1;
238 result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
239 CloseHandle(hFile);
240 return result;
241 #else
242 struct utimbuf settime;
243
244 settime.actime = settime.modtime = ftime;
245 return utime(fname,&settime);
246 #endif
247 }
248
249
250 /* push file attributes */
251
252 void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
253 {
254 struct attr_item *item;
255
256 item = (struct attr_item *)malloc(sizeof(struct attr_item));
257 if (item == NULL)
258 error("Out of memory");
259 item->fname = strdup(fname);
260 item->mode = mode;
261 item->time = time;
262 item->next = *list;
263 *list = item;
264 }
265
266
267 /* restore file attributes */
268
269 void restore_attr(struct attr_item **list)
270 {
271 struct attr_item *item, *prev;
272
273 for (item = *list; item != NULL; )
274 {
275 setfiletime(item->fname,item->time);
276 chmod(item->fname,item->mode);
277 prev = item;
278 item = item->next;
279 free(prev);
280 }
281 *list = NULL;
282 }
283
284
285 /* match regular expression */
286
287 #define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
288
289 int ExprMatch (char *string,char *expr)
290 {
291 while (1)
292 {
293 if (ISSPECIAL(*expr))
294 {
295 if (*expr == '/')
296 {
297 if (*string != '\\' && *string != '/')
298 return 0;
299 string ++; expr++;
300 }
301 else if (*expr == '*')
302 {
303 if (*expr ++ == 0)
304 return 1;
305 while (*++string != *expr)
306 if (*string == 0)
307 return 0;
308 }
309 }
310 else
311 {
312 if (*string != *expr)
313 return 0;
314 if (*expr++ == 0)
315 return 1;
316 string++;
317 }
318 }
319 }
320
321
322 /* recursive mkdir */
323 /* abort on ENOENT; ignore other errors like "directory already exists" */
324 /* return 1 if OK */
325 /* 0 on error */
326
327 int makedir (char *newdir)
328 {
329 char *buffer = strdup(newdir);
330 char *p;
331 int len = strlen(buffer);
332
333 if (len <= 0) {
334 free(buffer);
335 return 0;
336 }
337 if (buffer[len-1] == '/') {
338 buffer[len-1] = '\0';
339 }
340 if (mkdir(buffer, 0755) == 0)
341 {
342 free(buffer);
343 return 1;
344 }
345
346 p = buffer+1;
347 while (1)
348 {
349 char hold;
350
351 while(*p && *p != '\\' && *p != '/')
352 p++;
353 hold = *p;
354 *p = 0;
355 if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
356 {
357 fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
358 free(buffer);
359 return 0;
360 }
361 if (hold == 0)
362 break;
363 *p++ = hold;
364 }
365 free(buffer);
366 return 1;
367 }
368
369
370 int matchname (int arg,int argc,char **argv,char *fname)
371 {
372 if (arg == argc) /* no arguments given (untgz tgzarchive) */
373 return 1;
374
375 while (arg < argc)
376 if (ExprMatch(fname,argv[arg++]))
377 return 1;
378
379 return 0; /* ignore this for the moment being */
380 }
381
382
383 /* tar file list or extract */
384
385 int tar (gzFile in,int action,int arg,int argc,char **argv)
386 {
387 union tar_buffer buffer;
388 int len;
389 int err;
390 int getheader = 1;
391 int remaining = 0;
392 FILE *outfile = NULL;
393 char fname[BLOCKSIZE];
394 int tarmode;
395 time_t tartime;
396 struct attr_item *attributes = NULL;
397
398 if (action == TGZ_LIST)
399 printf(" date time size file\n"
400 " ---------- -------- --------- -------------------------------------\n");
401 while (1)
402 {
403 len = gzread(in, &buffer, BLOCKSIZE);
404 if (len < 0)
405 error(gzerror(in, &err));
406 /*
407 * Always expect complete blocks to process
408 * the tar information.
409 */
410 if (len != BLOCKSIZE)
411 {
412 action = TGZ_INVALID; /* force error exit */
413 remaining = 0; /* force I/O cleanup */
414 }
415
416 /*
417 * If we have to get a tar header
418 */
419 if (getheader >= 1)
420 {
421 /*
422 * if we met the end of the tar
423 * or the end-of-tar block,
424 * we are done
425 */
426 if (len == 0 || buffer.header.name[0] == 0)
427 break;
428
429 tarmode = getoct(buffer.header.mode,8);
430 tartime = (time_t)getoct(buffer.header.mtime,12);
431 if (tarmode == -1 || tartime == (time_t)-1)
432 {
433 buffer.header.name[0] = 0;
434 action = TGZ_INVALID;
435 }
436
437 if (getheader == 1)
438 {
439 strncpy(fname,buffer.header.name,SHORTNAMESIZE);
440 if (fname[SHORTNAMESIZE-1] != 0)
441 fname[SHORTNAMESIZE] = 0;
442 }
443 else
444 {
445 /*
446 * The file name is longer than SHORTNAMESIZE
447 */
448 if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
449 error("bad long name");
450 getheader = 1;
451 }
452
453 /*
454 * Act according to the type flag
455 */
456 switch (buffer.header.typeflag)
457 {
458 case DIRTYPE:
459 if (action == TGZ_LIST)
460 printf(" %s <dir> %s\n",strtime(&tartime),fname);
461 if (action == TGZ_EXTRACT)
462 {
463 makedir(fname);
464 push_attr(&attributes,fname,tarmode,tartime);
465 }
466 break;
467 case REGTYPE:
468 case AREGTYPE:
469 remaining = getoct(buffer.header.size,12);
470 if (remaining == -1)
471 {
472 action = TGZ_INVALID;
473 break;
474 }
475 if (action == TGZ_LIST)
476 printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
477 else if (action == TGZ_EXTRACT)
478 {
479 if (matchname(arg,argc,argv,fname))
480 {
481 outfile = fopen(fname,"wb");
482 if (outfile == NULL) {
483 /* try creating directory */
484 char *p = strrchr(fname, '/');
485 if (p != NULL) {
486 *p = '\0';
487 makedir(fname);
488 *p = '/';
489 outfile = fopen(fname,"wb");
490 }
491 }
492 if (outfile != NULL)
493 printf("Extracting %s\n",fname);
494 else
495 fprintf(stderr, "%s: Couldn't create %s",prog,fname);
496 }
497 else
498 outfile = NULL;
499 }
500 getheader = 0;
501 break;
502 case GNUTYPE_LONGLINK:
503 case GNUTYPE_LONGNAME:
504 remaining = getoct(buffer.header.size,12);
505 if (remaining < 0 || remaining >= BLOCKSIZE)
506 {
507 action = TGZ_INVALID;
508 break;
509 }
510 len = gzread(in, fname, BLOCKSIZE);
511 if (len < 0)
512 error(gzerror(in, &err));
513 if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
514 {
515 action = TGZ_INVALID;
516 break;
517 }
518 getheader = 2;
519 break;
520 default:
521 if (action == TGZ_LIST)
522 printf(" %s <---> %s\n",strtime(&tartime),fname);
523 break;
524 }
525 }
526 else
527 {
528 unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
529
530 if (outfile != NULL)
531 {
532 if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
533 {
534 fprintf(stderr,
535 "%s: Error writing %s -- skipping\n",prog,fname);
536 fclose(outfile);
537 outfile = NULL;
538 remove(fname);
539 }
540 }
541 remaining -= bytes;
542 }
543
544 if (remaining == 0)
545 {
546 getheader = 1;
547 if (outfile != NULL)
548 {
549 fclose(outfile);
550 outfile = NULL;
551 if (action != TGZ_INVALID)
552 push_attr(&attributes,fname,tarmode,tartime);
553 }
554 }
555
556 /*
557 * Abandon if errors are found
558 */
559 if (action == TGZ_INVALID)
560 {
561 error("broken archive");
562 break;
563 }
564 }
565
566 /*
567 * Restore file modes and time stamps
568 */
569 restore_attr(&attributes);
570
571 if (gzclose(in) != Z_OK)
572 error("failed gzclose");
573
574 return 0;
575 }
576
577
578 /* ============================================================ */
579
580 void help(int exitval)
581 {
582 printf("untgz version 0.2.1\n"
583 " using zlib version %s\n\n",
584 zlibVersion());
585 printf("Usage: untgz file.tgz extract all files\n"
586 " untgz file.tgz fname ... extract selected files\n"
587 " untgz -l file.tgz list archive contents\n"
588 " untgz -h display this help\n");
589 exit(exitval);
590 }
591
592 void error(const char *msg)
593 {
594 fprintf(stderr, "%s: %s\n", prog, msg);
595 exit(1);
596 }
597
598
599 /* ============================================================ */
600
601 #if defined(WIN32) && defined(__GNUC__)
602 int _CRT_glob = 0; /* disable argument globbing in MinGW */
603 #endif
604
605 int main(int argc,char **argv)
606 {
607 int action = TGZ_EXTRACT;
608 int arg = 1;
609 char *TGZfile;
610 gzFile *f;
611
612 prog = strrchr(argv[0],'\\');
613 if (prog == NULL)
614 {
615 prog = strrchr(argv[0],'/');
616 if (prog == NULL)
617 {
618 prog = strrchr(argv[0],':');
619 if (prog == NULL)
620 prog = argv[0];
621 else
622 prog++;
623 }
624 else
625 prog++;
626 }
627 else
628 prog++;
629
630 if (argc == 1)
631 help(0);
632
633 if (strcmp(argv[arg],"-l") == 0)
634 {
635 action = TGZ_LIST;
636 if (argc == ++arg)
637 help(0);
638 }
639 else if (strcmp(argv[arg],"-h") == 0)
640 {
641 help(0);
642 }
643
644 if ((TGZfile = TGZfname(argv[arg])) == NULL)
645 TGZnotfound(argv[arg]);
646
647 ++arg;
648 if ((action == TGZ_LIST) && (arg != argc))
649 help(1);
650
651 /*
652 * Process the TGZ file
653 */
654 switch(action)
655 {
656 case TGZ_LIST:
657 case TGZ_EXTRACT:
658 f = gzopen(TGZfile,"rb");
659 if (f == NULL)
660 {
661 fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
662 return 1;
663 }
664 exit(tar(f, action, arg, argc, argv));
665 break;
666
667 default:
668 error("Unknown option");
669 exit(1);
670 }
671
672 return 0;
673 }
0 Building instructions for the DLL versions of Zlib 1.2.x
1 =======================================================
2
3 This directory contains projects that build zlib and minizip using
4 Microsoft Visual C++ 7.0/7.1.
5
6 You don't need to build these projects yourself. You can download the
7 binaries from:
8 http://www.winimage.com/zLibDll
9
10 More information can be found at this site.
11
12
13 Build instructions
14 ------------------
15 - Unzip zlib*.zip and copy the files from contrib\vstudio\vc7,
16 from contrib\vstudio\masmx86 and from contrib\minizip into the same
17 directory.
18 - Download the crtdll library from
19 http://www.winimage.com/zLibDll/crtdll.zip
20 Unzip crtdll.zip to extract crtdll.lib.
21 - If you are using x86, use the Release target.
22 - Open zlibvc.sln with Microsoft Visual C++ 7.0 or 7.1
23 (Visual Studio .Net 2002 or 2003).
24
25
26 Important
27 ---------
28 - To use zlibwapi.dll in your application, you must define the
29 macro ZLIB_WINAPI when compiling your application's source files.
30
31
32 Additional notes
33 ----------------
34 - This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built
35 by Gilles Vollant from the zlib 1.1.x sources, and distributed at
36 http://www.winimage.com/zLibDll
37 It uses the WINAPI calling convention for the exported functions, and
38 includes the minizip functionality. If your application needs that
39 particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.
40
41 - The new DLL was renamed because there exist several incompatible
42 versions of zlib.dll on the Internet.
43
44 - There is also an official DLL build of zlib, named zlib1.dll. This one
45 is exporting the functions using the CDECL convention. See the file
46 win32\DLL_FAQ.txt found in this zlib distribution.
47
48 - There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol
49 has a slightly different effect. To avoid compatibility problems, do
50 not define it here.
51
52
53 Gilles Vollant
54 info@winimage.com
0 <?xml version="1.0" encoding = "Windows-1252"?>
1 <VisualStudioProject
2 ProjectType="Visual C++"
3 Version="7.00"
4 Name="miniunz"
5 ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
6 Keyword="Win32Proj">
7 <Platforms>
8 <Platform
9 Name="Win32"/>
10 </Platforms>
11 <Configurations>
12 <Configuration
13 Name="Debug|Win32"
14 OutputDirectory="Debug"
15 IntermediateDirectory="Debug"
16 ConfigurationType="1"
17 CharacterSet="2">
18 <Tool
19 Name="VCCLCompilerTool"
20 Optimization="0"
21 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
22 MinimalRebuild="TRUE"
23 BasicRuntimeChecks="3"
24 RuntimeLibrary="5"
25 UsePrecompiledHeader="0"
26 WarningLevel="3"
27 Detect64BitPortabilityProblems="TRUE"
28 DebugInformationFormat="4"/>
29 <Tool
30 Name="VCCustomBuildTool"/>
31 <Tool
32 Name="VCLinkerTool"
33 OutputFile="$(OutDir)/miniunz.exe"
34 LinkIncremental="2"
35 GenerateDebugInformation="TRUE"
36 ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
37 SubSystem="1"
38 TargetMachine="1"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCWebDeploymentTool"/>
53 </Configuration>
54 <Configuration
55 Name="Release|Win32"
56 OutputDirectory="Release"
57 IntermediateDirectory="Release"
58 ConfigurationType="1"
59 CharacterSet="2">
60 <Tool
61 Name="VCCLCompilerTool"
62 Optimization="2"
63 InlineFunctionExpansion="1"
64 OmitFramePointers="TRUE"
65 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
66 StringPooling="TRUE"
67 RuntimeLibrary="4"
68 EnableFunctionLevelLinking="TRUE"
69 UsePrecompiledHeader="0"
70 WarningLevel="3"
71 Detect64BitPortabilityProblems="TRUE"
72 DebugInformationFormat="3"/>
73 <Tool
74 Name="VCCustomBuildTool"/>
75 <Tool
76 Name="VCLinkerTool"
77 OutputFile="$(OutDir)/miniunz.exe"
78 LinkIncremental="1"
79 GenerateDebugInformation="TRUE"
80 SubSystem="1"
81 OptimizeReferences="2"
82 EnableCOMDATFolding="2"
83 OptimizeForWindows98="1"
84 TargetMachine="1"/>
85 <Tool
86 Name="VCMIDLTool"/>
87 <Tool
88 Name="VCPostBuildEventTool"/>
89 <Tool
90 Name="VCPreBuildEventTool"/>
91 <Tool
92 Name="VCPreLinkEventTool"/>
93 <Tool
94 Name="VCResourceCompilerTool"/>
95 <Tool
96 Name="VCWebServiceProxyGeneratorTool"/>
97 <Tool
98 Name="VCWebDeploymentTool"/>
99 </Configuration>
100 </Configurations>
101 <Files>
102 <Filter
103 Name="Source Files"
104 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
105 <File
106 RelativePath="miniunz.c">
107 </File>
108 </Filter>
109 <Filter
110 Name="Header Files"
111 Filter="h;hpp;hxx;hm;inl;inc">
112 </Filter>
113 <Filter
114 Name="Resource Files"
115 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
116 </Filter>
117 <File
118 RelativePath="zlibwapi.lib">
119 </File>
120 </Files>
121 <Globals>
122 </Globals>
123 </VisualStudioProject>
0 <?xml version="1.0" encoding = "Windows-1252"?>
1 <VisualStudioProject
2 ProjectType="Visual C++"
3 Version="7.00"
4 Name="minizip"
5 ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
6 Keyword="Win32Proj">
7 <Platforms>
8 <Platform
9 Name="Win32"/>
10 </Platforms>
11 <Configurations>
12 <Configuration
13 Name="Debug|Win32"
14 OutputDirectory="Debug"
15 IntermediateDirectory="Debug"
16 ConfigurationType="1"
17 CharacterSet="2">
18 <Tool
19 Name="VCCLCompilerTool"
20 Optimization="0"
21 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
22 MinimalRebuild="TRUE"
23 BasicRuntimeChecks="3"
24 RuntimeLibrary="5"
25 UsePrecompiledHeader="0"
26 WarningLevel="3"
27 Detect64BitPortabilityProblems="TRUE"
28 DebugInformationFormat="4"/>
29 <Tool
30 Name="VCCustomBuildTool"/>
31 <Tool
32 Name="VCLinkerTool"
33 OutputFile="$(OutDir)/minizip.exe"
34 LinkIncremental="2"
35 GenerateDebugInformation="TRUE"
36 ProgramDatabaseFile="$(OutDir)/minizip.pdb"
37 SubSystem="1"
38 TargetMachine="1"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"/>
49 <Tool
50 Name="VCWebServiceProxyGeneratorTool"/>
51 <Tool
52 Name="VCWebDeploymentTool"/>
53 </Configuration>
54 <Configuration
55 Name="Release|Win32"
56 OutputDirectory="Release"
57 IntermediateDirectory="Release"
58 ConfigurationType="1"
59 CharacterSet="2">
60 <Tool
61 Name="VCCLCompilerTool"
62 Optimization="2"
63 InlineFunctionExpansion="1"
64 OmitFramePointers="TRUE"
65 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
66 StringPooling="TRUE"
67 RuntimeLibrary="4"
68 EnableFunctionLevelLinking="TRUE"
69 UsePrecompiledHeader="0"
70 WarningLevel="3"
71 Detect64BitPortabilityProblems="TRUE"
72 DebugInformationFormat="3"/>
73 <Tool
74 Name="VCCustomBuildTool"/>
75 <Tool
76 Name="VCLinkerTool"
77 OutputFile="$(OutDir)/minizip.exe"
78 LinkIncremental="1"
79 GenerateDebugInformation="TRUE"
80 SubSystem="1"
81 OptimizeReferences="2"
82 EnableCOMDATFolding="2"
83 OptimizeForWindows98="1"
84 TargetMachine="1"/>
85 <Tool
86 Name="VCMIDLTool"/>
87 <Tool
88 Name="VCPostBuildEventTool"/>
89 <Tool
90 Name="VCPreBuildEventTool"/>
91 <Tool
92 Name="VCPreLinkEventTool"/>
93 <Tool
94 Name="VCResourceCompilerTool"/>
95 <Tool
96 Name="VCWebServiceProxyGeneratorTool"/>
97 <Tool
98 Name="VCWebDeploymentTool"/>
99 </Configuration>
100 </Configurations>
101 <Files>
102 <Filter
103 Name="Source Files"
104 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
105 <File
106 RelativePath="minizip.c">
107 </File>
108 </Filter>
109 <Filter
110 Name="Header Files"
111 Filter="h;hpp;hxx;hm;inl;inc">
112 </Filter>
113 <Filter
114 Name="Resource Files"
115 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
116 </Filter>
117 <File
118 RelativePath="zlibwapi.lib">
119 </File>
120 </Files>
121 <Globals>
122 </Globals>
123 </VisualStudioProject>
0 #include <windows.h>
1
2 #define IDR_VERSION1 1
3 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
4 FILEVERSION 1,2,2,2
5 PRODUCTVERSION 1,2,2,2
6 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
7 FILEFLAGS 0
8 FILEOS VOS_DOS_WINDOWS32
9 FILETYPE VFT_DLL
10 FILESUBTYPE 0 // not used
11 BEGIN
12 BLOCK "StringFileInfo"
13 BEGIN
14 BLOCK "040904E4"
15 //language ID = U.S. English, char set = Windows, Multilingual
16
17 BEGIN
18 VALUE "FileDescription", "zlib data compression library\0"
19 VALUE "FileVersion", "1.2.2.2\0"
20 VALUE "InternalName", "zlib\0"
21 VALUE "OriginalFilename", "zlib.dll\0"
22 VALUE "ProductName", "ZLib.DLL\0"
23 VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
24 VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0"
25 END
26 END
27 BLOCK "VarFileInfo"
28 BEGIN
29 VALUE "Translation", 0x0409, 1252
30 END
31 END
0 <?xml version="1.0" encoding = "Windows-1252"?>
1 <VisualStudioProject
2 ProjectType="Visual C++"
3 Version="7.00"
4 Name="zlibstat"
5 SccProjectName=""
6 SccLocalPath="">
7 <Platforms>
8 <Platform
9 Name="Win32"/>
10 </Platforms>
11 <Configurations>
12 <Configuration
13 Name="Debug|Win32"
14 OutputDirectory=".\zlibstatDebug"
15 IntermediateDirectory=".\zlibstatDebug"
16 ConfigurationType="4"
17 UseOfMFC="0"
18 ATLMinimizesCRunTimeLibraryUsage="FALSE">
19 <Tool
20 Name="VCCLCompilerTool"
21 Optimization="0"
22 PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
23 ExceptionHandling="FALSE"
24 RuntimeLibrary="5"
25 PrecompiledHeaderFile=".\zlibstatDebug/zlibstat.pch"
26 AssemblerListingLocation=".\zlibstatDebug/"
27 ObjectFile=".\zlibstatDebug/"
28 ProgramDataBaseFileName=".\zlibstatDebug/"
29 WarningLevel="3"
30 SuppressStartupBanner="TRUE"
31 DebugInformationFormat="1"/>
32 <Tool
33 Name="VCCustomBuildTool"/>
34 <Tool
35 Name="VCLibrarianTool"
36 AdditionalOptions="/NODEFAULTLIB "
37 OutputFile=".\zlibstatDebug\zlibstat.lib"
38 SuppressStartupBanner="TRUE"/>
39 <Tool
40 Name="VCMIDLTool"/>
41 <Tool
42 Name="VCPostBuildEventTool"/>
43 <Tool
44 Name="VCPreBuildEventTool"/>
45 <Tool
46 Name="VCPreLinkEventTool"/>
47 <Tool
48 Name="VCResourceCompilerTool"
49 Culture="1036"/>
50 <Tool
51 Name="VCWebServiceProxyGeneratorTool"/>
52 </Configuration>
53 <Configuration
54 Name="ReleaseAxp|Win32"
55 OutputDirectory=".\zlibsta0"
56 IntermediateDirectory=".\zlibsta0"
57 ConfigurationType="4"
58 UseOfMFC="0"
59 ATLMinimizesCRunTimeLibraryUsage="FALSE">
60 <Tool
61 Name="VCCLCompilerTool"
62 InlineFunctionExpansion="1"
63 PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
64 StringPooling="TRUE"
65 ExceptionHandling="FALSE"
66 RuntimeLibrary="4"
67 EnableFunctionLevelLinking="TRUE"
68 PrecompiledHeaderFile=".\zlibsta0/zlibstat.pch"
69 AssemblerListingLocation=".\zlibsta0/"
70 ObjectFile=".\zlibsta0/"
71 ProgramDataBaseFileName=".\zlibsta0/"
72 WarningLevel="3"
73 SuppressStartupBanner="TRUE"/>
74 <Tool
75 Name="VCCustomBuildTool"/>
76 <Tool
77 Name="VCLibrarianTool"
78 AdditionalOptions="/NODEFAULTLIB "
79 OutputFile=".\zlibsta0\zlibstat.lib"
80 SuppressStartupBanner="TRUE"/>
81 <Tool
82 Name="VCMIDLTool"/>
83 <Tool
84 Name="VCPostBuildEventTool"/>
85 <Tool
86 Name="VCPreBuildEventTool"/>
87 <Tool
88 Name="VCPreLinkEventTool"/>
89 <Tool
90 Name="VCResourceCompilerTool"/>
91 <Tool
92 Name="VCWebServiceProxyGeneratorTool"/>
93 </Configuration>
94 <Configuration
95 Name="Release|Win32"
96 OutputDirectory=".\zlibstat"
97 IntermediateDirectory=".\zlibstat"
98 ConfigurationType="4"
99 UseOfMFC="0"
100 ATLMinimizesCRunTimeLibraryUsage="FALSE">
101 <Tool
102 Name="VCCLCompilerTool"
103 InlineFunctionExpansion="1"
104 PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF"
105 StringPooling="TRUE"
106 ExceptionHandling="FALSE"
107 RuntimeLibrary="4"
108 EnableFunctionLevelLinking="TRUE"
109 PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
110 AssemblerListingLocation=".\zlibstat/"
111 ObjectFile=".\zlibstat/"
112 ProgramDataBaseFileName=".\zlibstat/"
113 WarningLevel="3"
114 SuppressStartupBanner="TRUE"/>
115 <Tool
116 Name="VCCustomBuildTool"/>
117 <Tool
118 Name="VCLibrarianTool"
119 AdditionalOptions="gvmat32.obj inffas32.obj /NODEFAULTLIB "
120 OutputFile=".\zlibstat\zlibstat.lib"
121 SuppressStartupBanner="TRUE"/>
122 <Tool
123 Name="VCMIDLTool"/>
124 <Tool
125 Name="VCPostBuildEventTool"/>
126 <Tool
127 Name="VCPreBuildEventTool"/>
128 <Tool
129 Name="VCPreLinkEventTool"/>
130 <Tool
131 Name="VCResourceCompilerTool"
132 Culture="1036"/>
133 <Tool
134 Name="VCWebServiceProxyGeneratorTool"/>
135 </Configuration>
136 <Configuration
137 Name="ReleaseWithoutAsm|Win32"
138 OutputDirectory="zlibstatWithoutAsm"
139 IntermediateDirectory="zlibstatWithoutAsm"
140 ConfigurationType="4"
141 UseOfMFC="0"
142 ATLMinimizesCRunTimeLibraryUsage="FALSE">
143 <Tool
144 Name="VCCLCompilerTool"
145 InlineFunctionExpansion="1"
146 PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
147 StringPooling="TRUE"
148 ExceptionHandling="FALSE"
149 RuntimeLibrary="4"
150 EnableFunctionLevelLinking="TRUE"
151 PrecompiledHeaderFile=".\zlibstat/zlibstat.pch"
152 AssemblerListingLocation=".\zlibstatWithoutAsm/"
153 ObjectFile=".\zlibstatWithoutAsm/"
154 ProgramDataBaseFileName=".\zlibstatWithoutAsm/"
155 WarningLevel="3"
156 SuppressStartupBanner="TRUE"/>
157 <Tool
158 Name="VCCustomBuildTool"/>
159 <Tool
160 Name="VCLibrarianTool"
161 AdditionalOptions=" /NODEFAULTLIB "
162 OutputFile=".\zlibstatWithoutAsm\zlibstat.lib"
163 SuppressStartupBanner="TRUE"/>
164 <Tool
165 Name="VCMIDLTool"/>
166 <Tool
167 Name="VCPostBuildEventTool"/>
168 <Tool
169 Name="VCPreBuildEventTool"/>
170 <Tool
171 Name="VCPreLinkEventTool"/>
172 <Tool
173 Name="VCResourceCompilerTool"
174 Culture="1036"/>
175 <Tool
176 Name="VCWebServiceProxyGeneratorTool"/>
177 </Configuration>
178 </Configurations>
179 <Files>
180 <Filter
181 Name="Source Files"
182 Filter="">
183 <File
184 RelativePath=".\adler32.c">
185 </File>
186 <File
187 RelativePath=".\compress.c">
188 </File>
189 <File
190 RelativePath=".\crc32.c">
191 </File>
192 <File
193 RelativePath=".\deflate.c">
194 </File>
195 <File
196 RelativePath=".\gvmat32c.c">
197 </File>
198 <File
199 RelativePath=".\gzio.c">
200 </File>
201 <File
202 RelativePath=".\infback.c">
203 </File>
204 <File
205 RelativePath=".\inffast.c">
206 </File>
207 <File
208 RelativePath=".\inflate.c">
209 </File>
210 <File
211 RelativePath=".\inftrees.c">
212 </File>
213 <File
214 RelativePath=".\ioapi.c">
215 </File>
216 <File
217 RelativePath=".\trees.c">
218 </File>
219 <File
220 RelativePath=".\uncompr.c">
221 </File>
222 <File
223 RelativePath=".\unzip.c">
224 </File>
225 <File
226 RelativePath=".\zip.c">
227 </File>
228 <File
229 RelativePath=".\zlib.rc">
230 </File>
231 <File
232 RelativePath=".\zlibvc.def">
233 </File>
234 <File
235 RelativePath=".\zutil.c">
236 </File>
237 </Filter>
238 </Files>
239 <Globals>
240 </Globals>
241 </VisualStudioProject>
0
1 VERSION 1.21
2
3 HEAPSIZE 1048576,8192
4
5 EXPORTS
6 adler32 @1
7 compress @2
8 crc32 @3
9 deflate @4
10 deflateCopy @5
11 deflateEnd @6
12 deflateInit2_ @7
13 deflateInit_ @8
14 deflateParams @9
15 deflateReset @10
16 deflateSetDictionary @11
17 gzclose @12
18 gzdopen @13
19 gzerror @14
20 gzflush @15
21 gzopen @16
22 gzread @17
23 gzwrite @18
24 inflate @19
25 inflateEnd @20
26 inflateInit2_ @21
27 inflateInit_ @22
28 inflateReset @23
29 inflateSetDictionary @24
30 inflateSync @25
31 uncompress @26
32 zlibVersion @27
33 gzprintf @28
34 gzputc @29
35 gzgetc @30
36 gzseek @31
37 gzrewind @32
38 gztell @33
39 gzeof @34
40 gzsetparams @35
41 zError @36
42 inflateSyncPoint @37
43 get_crc_table @38
44 compress2 @39
45 gzputs @40
46 gzgets @41
47 inflateCopy @42
48 inflateBackInit_ @43
49 inflateBack @44
50 inflateBackEnd @45
51 compressBound @46
52 deflateBound @47
53 gzclearerr @48
54 gzungetc @49
55 zlibCompileFlags @50
56 deflatePrime @51
57
58 unzOpen @61
59 unzClose @62
60 unzGetGlobalInfo @63
61 unzGetCurrentFileInfo @64
62 unzGoToFirstFile @65
63 unzGoToNextFile @66
64 unzOpenCurrentFile @67
65 unzReadCurrentFile @68
66 unzOpenCurrentFile3 @69
67 unztell @70
68 unzeof @71
69 unzCloseCurrentFile @72
70 unzGetGlobalComment @73
71 unzStringFileNameCompare @74
72 unzLocateFile @75
73 unzGetLocalExtrafield @76
74 unzOpen2 @77
75 unzOpenCurrentFile2 @78
76 unzOpenCurrentFilePassword @79
77
78 zipOpen @80
79 zipOpenNewFileInZip @81
80 zipWriteInFileInZip @82
81 zipCloseFileInZip @83
82 zipClose @84
83 zipOpenNewFileInZip2 @86
84 zipCloseFileInZipRaw @87
85 zipOpen2 @88
86 zipOpenNewFileInZip3 @89
87
88 unzGetFilePos @100
89 unzGoToFilePos @101
90
91 fill_win32_filefunc @110
0 Microsoft Visual Studio Solution File, Format Version 7.00
1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
2 EndProject
3 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
4 EndProject
5 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
6 EndProject
7 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
8 EndProject
9 Global
10 GlobalSection(SolutionConfiguration) = preSolution
11 ConfigName.0 = Debug
12 ConfigName.1 = Release
13 ConfigName.2 = ReleaseAxp
14 ConfigName.3 = ReleaseWithoutAsm
15 ConfigName.4 = ReleaseWithoutCrtdll
16 EndGlobalSection
17 GlobalSection(ProjectDependencies) = postSolution
18 EndGlobalSection
19 GlobalSection(ProjectConfiguration) = postSolution
20 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.ActiveCfg = Debug|Win32
21 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug.Build.0 = Debug|Win32
22 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.ActiveCfg = Release|Win32
23 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release.Build.0 = Release|Win32
24 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
25 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
26 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
27 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
28 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseAxp|Win32
29 {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutCrtdll.Build.0 = ReleaseAxp|Win32
30 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.ActiveCfg = Debug|Win32
31 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug.Build.0 = Debug|Win32
32 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.ActiveCfg = Release|Win32
33 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release.Build.0 = Release|Win32
34 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.ActiveCfg = ReleaseAxp|Win32
35 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseAxp.Build.0 = ReleaseAxp|Win32
36 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.ActiveCfg = ReleaseWithoutAsm|Win32
37 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm.Build.0 = ReleaseWithoutAsm|Win32
38 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.ActiveCfg = ReleaseWithoutCrtdll|Win32
39 {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutCrtdll.Build.0 = ReleaseWithoutCrtdll|Win32
40 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.ActiveCfg = Debug|Win32
41 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug.Build.0 = Debug|Win32
42 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.ActiveCfg = Release|Win32
43 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release.Build.0 = Release|Win32
44 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.ActiveCfg = Release|Win32
45 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAxp.Build.0 = Release|Win32
46 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
47 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm.Build.0 = Release|Win32
48 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
49 {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
50 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.ActiveCfg = Debug|Win32
51 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug.Build.0 = Debug|Win32
52 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.ActiveCfg = Release|Win32
53 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release.Build.0 = Release|Win32
54 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.ActiveCfg = Release|Win32
55 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseAxp.Build.0 = Release|Win32
56 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
57 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.Build.0 = Release|Win32
58 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
59 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
60 EndGlobalSection
61 GlobalSection(ExtensibilityGlobals) = postSolution
62 EndGlobalSection
63 GlobalSection(ExtensibilityAddIns) = postSolution
64 EndGlobalSection
65 EndGlobal
0 <?xml version="1.0" encoding = "Windows-1252"?>
1 <VisualStudioProject
2 ProjectType="Visual C++"
3 Version="7.00"
4 Name="zlibvc"
5 SccProjectName=""
6 SccLocalPath="">
7 <Platforms>
8 <Platform
9 Name="Win32"/>
10 </Platforms>
11 <Configurations>
12 <Configuration
13 Name="Debug|Win32"
14 OutputDirectory=".\DebugDll"
15 IntermediateDirectory=".\DebugDll"
16 ConfigurationType="2"
17 UseOfMFC="0"
18 ATLMinimizesCRunTimeLibraryUsage="FALSE">
19 <Tool
20 Name="VCCLCompilerTool"
21 Optimization="0"
22 PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
23 ExceptionHandling="FALSE"
24 RuntimeLibrary="1"
25 PrecompiledHeaderFile=".\DebugDll/zlibvc.pch"
26 AssemblerListingLocation=".\DebugDll/"
27 ObjectFile=".\DebugDll/"
28 ProgramDataBaseFileName=".\DebugDll/"
29 WarningLevel="3"
30 SuppressStartupBanner="TRUE"
31 DebugInformationFormat="4"/>
32 <Tool
33 Name="VCCustomBuildTool"/>
34 <Tool
35 Name="VCLinkerTool"
36 AdditionalOptions="/MACHINE:I386"
37 AdditionalDependencies="gvmat32.obj inffas32.obj"
38 OutputFile=".\DebugDll\zlibwapi.dll"
39 LinkIncremental="2"
40 SuppressStartupBanner="TRUE"
41 ModuleDefinitionFile=".\zlibvc.def"
42 GenerateDebugInformation="TRUE"
43 ProgramDatabaseFile=".\DebugDll/zlibwapi.pdb"
44 SubSystem="2"
45 ImportLibrary=".\DebugDll/zlibwapi.lib"/>
46 <Tool
47 Name="VCMIDLTool"
48 PreprocessorDefinitions="_DEBUG"
49 MkTypLibCompatible="TRUE"
50 SuppressStartupBanner="TRUE"
51 TargetEnvironment="1"
52 TypeLibraryName=".\DebugDll/zlibvc.tlb"/>
53 <Tool
54 Name="VCPostBuildEventTool"/>
55 <Tool
56 Name="VCPreBuildEventTool"/>
57 <Tool
58 Name="VCPreLinkEventTool"/>
59 <Tool
60 Name="VCResourceCompilerTool"
61 PreprocessorDefinitions="_DEBUG"
62 Culture="1036"/>
63 <Tool
64 Name="VCWebServiceProxyGeneratorTool"/>
65 <Tool
66 Name="VCWebDeploymentTool"/>
67 </Configuration>
68 <Configuration
69 Name="ReleaseWithoutAsm|Win32"
70 OutputDirectory=".\zlibDllWithoutAsm"
71 IntermediateDirectory=".\zlibDllWithoutAsm"
72 ConfigurationType="2"
73 UseOfMFC="0"
74 ATLMinimizesCRunTimeLibraryUsage="FALSE">
75 <Tool
76 Name="VCCLCompilerTool"
77 InlineFunctionExpansion="1"
78 PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
79 StringPooling="TRUE"
80 ExceptionHandling="FALSE"
81 RuntimeLibrary="0"
82 EnableFunctionLevelLinking="TRUE"
83 PrecompiledHeaderFile=".\zlibDllWithoutAsm/zlibvc.pch"
84 AssemblerOutput="2"
85 AssemblerListingLocation=".\zlibDllWithoutAsm/"
86 ObjectFile=".\zlibDllWithoutAsm/"
87 ProgramDataBaseFileName=".\zlibDllWithoutAsm/"
88 BrowseInformation="1"
89 WarningLevel="3"
90 SuppressStartupBanner="TRUE"/>
91 <Tool
92 Name="VCCustomBuildTool"/>
93 <Tool
94 Name="VCLinkerTool"
95 AdditionalOptions="/MACHINE:I386"
96 AdditionalDependencies="crtdll.lib"
97 OutputFile=".\zlibDllWithoutAsm\zlibwapi.dll"
98 LinkIncremental="1"
99 SuppressStartupBanner="TRUE"
100 IgnoreAllDefaultLibraries="TRUE"
101 ModuleDefinitionFile=".\zlibvc.def"
102 ProgramDatabaseFile=".\zlibDllWithoutAsm/zlibwapi.pdb"
103 GenerateMapFile="TRUE"
104 MapFileName=".\zlibDllWithoutAsm/zlibwapi.map"
105 SubSystem="2"
106 OptimizeForWindows98="1"
107 ImportLibrary=".\zlibDllWithoutAsm/zlibwapi.lib"/>
108 <Tool
109 Name="VCMIDLTool"
110 PreprocessorDefinitions="NDEBUG"
111 MkTypLibCompatible="TRUE"
112 SuppressStartupBanner="TRUE"
113 TargetEnvironment="1"
114 TypeLibraryName=".\zlibDllWithoutAsm/zlibvc.tlb"/>
115 <Tool
116 Name="VCPostBuildEventTool"/>
117 <Tool
118 Name="VCPreBuildEventTool"/>
119 <Tool
120 Name="VCPreLinkEventTool"/>
121 <Tool
122 Name="VCResourceCompilerTool"
123 PreprocessorDefinitions="NDEBUG"
124 Culture="1036"/>
125 <Tool
126 Name="VCWebServiceProxyGeneratorTool"/>
127 <Tool
128 Name="VCWebDeploymentTool"/>
129 </Configuration>
130 <Configuration
131 Name="ReleaseWithoutCrtdll|Win32"
132 OutputDirectory=".\zlibDllWithoutCrtDll"
133 IntermediateDirectory=".\zlibDllWithoutCrtDll"
134 ConfigurationType="2"
135 UseOfMFC="0"
136 ATLMinimizesCRunTimeLibraryUsage="FALSE">
137 <Tool
138 Name="VCCLCompilerTool"
139 InlineFunctionExpansion="1"
140 PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
141 StringPooling="TRUE"
142 ExceptionHandling="FALSE"
143 RuntimeLibrary="0"
144 EnableFunctionLevelLinking="TRUE"
145 PrecompiledHeaderFile=".\zlibDllWithoutCrtDll/zlibvc.pch"
146 AssemblerOutput="2"
147 AssemblerListingLocation=".\zlibDllWithoutCrtDll/"
148 ObjectFile=".\zlibDllWithoutCrtDll/"
149 ProgramDataBaseFileName=".\zlibDllWithoutCrtDll/"
150 BrowseInformation="1"
151 WarningLevel="3"
152 SuppressStartupBanner="TRUE"/>
153 <Tool
154 Name="VCCustomBuildTool"/>
155 <Tool
156 Name="VCLinkerTool"
157 AdditionalOptions="/MACHINE:I386"
158 AdditionalDependencies="gvmat32.obj inffas32.obj "
159 OutputFile=".\zlibDllWithoutCrtDll\zlibwapi.dll"
160 LinkIncremental="1"
161 SuppressStartupBanner="TRUE"
162 IgnoreAllDefaultLibraries="FALSE"
163 ModuleDefinitionFile=".\zlibvc.def"
164 ProgramDatabaseFile=".\zlibDllWithoutCrtDll/zlibwapi.pdb"
165 GenerateMapFile="TRUE"
166 MapFileName=".\zlibDllWithoutCrtDll/zlibwapi.map"
167 SubSystem="2"
168 OptimizeForWindows98="1"
169 ImportLibrary=".\zlibDllWithoutCrtDll/zlibwapi.lib"/>
170 <Tool
171 Name="VCMIDLTool"
172 PreprocessorDefinitions="NDEBUG"
173 MkTypLibCompatible="TRUE"
174 SuppressStartupBanner="TRUE"
175 TargetEnvironment="1"
176 TypeLibraryName=".\zlibDllWithoutCrtDll/zlibvc.tlb"/>
177 <Tool
178 Name="VCPostBuildEventTool"/>
179 <Tool
180 Name="VCPreBuildEventTool"/>
181 <Tool
182 Name="VCPreLinkEventTool"/>
183 <Tool
184 Name="VCResourceCompilerTool"
185 PreprocessorDefinitions="NDEBUG"
186 Culture="1036"/>
187 <Tool
188 Name="VCWebServiceProxyGeneratorTool"/>
189 <Tool
190 Name="VCWebDeploymentTool"/>
191 </Configuration>
192 <Configuration
193 Name="ReleaseAxp|Win32"
194 OutputDirectory=".\zlibvc__"
195 IntermediateDirectory=".\zlibvc__"
196 ConfigurationType="2"
197 UseOfMFC="0"
198 ATLMinimizesCRunTimeLibraryUsage="FALSE">
199 <Tool
200 Name="VCCLCompilerTool"
201 InlineFunctionExpansion="1"
202 PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
203 StringPooling="TRUE"
204 ExceptionHandling="FALSE"
205 RuntimeLibrary="0"
206 EnableFunctionLevelLinking="TRUE"
207 PrecompiledHeaderFile=".\zlibvc__/zlibvc.pch"
208 AssemblerOutput="2"
209 AssemblerListingLocation=".\zlibvc__/"
210 ObjectFile=".\zlibvc__/"
211 ProgramDataBaseFileName=".\zlibvc__/"
212 BrowseInformation="1"
213 WarningLevel="3"
214 SuppressStartupBanner="TRUE"/>
215 <Tool
216 Name="VCCustomBuildTool"/>
217 <Tool
218 Name="VCLinkerTool"
219 AdditionalDependencies="crtdll.lib"
220 OutputFile="zlibvc__\zlibwapi.dll"
221 LinkIncremental="1"
222 SuppressStartupBanner="TRUE"
223 IgnoreAllDefaultLibraries="TRUE"
224 ModuleDefinitionFile=".\zlibvc.def"
225 ProgramDatabaseFile=".\zlibvc__/zlibwapi.pdb"
226 GenerateMapFile="TRUE"
227 MapFileName=".\zlibvc__/zlibwapi.map"
228 SubSystem="2"
229 ImportLibrary=".\zlibvc__/zlibwapi.lib"/>
230 <Tool
231 Name="VCMIDLTool"
232 PreprocessorDefinitions="NDEBUG"
233 MkTypLibCompatible="TRUE"
234 SuppressStartupBanner="TRUE"
235 TargetEnvironment="1"
236 TypeLibraryName=".\zlibvc__/zlibvc.tlb"/>
237 <Tool
238 Name="VCPostBuildEventTool"/>
239 <Tool
240 Name="VCPreBuildEventTool"/>
241 <Tool
242 Name="VCPreLinkEventTool"/>
243 <Tool
244 Name="VCResourceCompilerTool"
245 PreprocessorDefinitions="NDEBUG"
246 Culture="1036"/>
247 <Tool
248 Name="VCWebServiceProxyGeneratorTool"/>
249 <Tool
250 Name="VCWebDeploymentTool"/>
251 </Configuration>
252 <Configuration
253 Name="Release|Win32"
254 OutputDirectory=".\ReleaseDll"
255 IntermediateDirectory=".\ReleaseDll"
256 ConfigurationType="2"
257 UseOfMFC="0"
258 ATLMinimizesCRunTimeLibraryUsage="FALSE">
259 <Tool
260 Name="VCCLCompilerTool"
261 InlineFunctionExpansion="1"
262 PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
263 StringPooling="TRUE"
264 ExceptionHandling="FALSE"
265 RuntimeLibrary="0"
266 EnableFunctionLevelLinking="TRUE"
267 PrecompiledHeaderFile=".\ReleaseDll/zlibvc.pch"
268 AssemblerOutput="2"
269 AssemblerListingLocation=".\ReleaseDll/"
270 ObjectFile=".\ReleaseDll/"
271 ProgramDataBaseFileName=".\ReleaseDll/"
272 BrowseInformation="1"
273 WarningLevel="3"
274 SuppressStartupBanner="TRUE"/>
275 <Tool
276 Name="VCCustomBuildTool"/>
277 <Tool
278 Name="VCLinkerTool"
279 AdditionalOptions="/MACHINE:I386"
280 AdditionalDependencies="gvmat32.obj inffas32.obj crtdll.lib"
281 OutputFile=".\ReleaseDll\zlibwapi.dll"
282 LinkIncremental="1"
283 SuppressStartupBanner="TRUE"
284 IgnoreAllDefaultLibraries="TRUE"
285 ModuleDefinitionFile=".\zlibvc.def"
286 ProgramDatabaseFile=".\ReleaseDll/zlibwapi.pdb"
287 GenerateMapFile="TRUE"
288 MapFileName=".\ReleaseDll/zlibwapi.map"
289 SubSystem="2"
290 OptimizeForWindows98="1"
291 ImportLibrary=".\ReleaseDll/zlibwapi.lib"/>
292 <Tool
293 Name="VCMIDLTool"
294 PreprocessorDefinitions="NDEBUG"
295 MkTypLibCompatible="TRUE"
296 SuppressStartupBanner="TRUE"
297 TargetEnvironment="1"
298 TypeLibraryName=".\Release/zlibvc.tlb"/>
299 <Tool
300 Name="VCPostBuildEventTool"/>
301 <Tool
302 Name="VCPreBuildEventTool"/>
303 <Tool
304 Name="VCPreLinkEventTool"/>
305 <Tool
306 Name="VCResourceCompilerTool"
307 PreprocessorDefinitions="NDEBUG"
308 Culture="1036"/>
309 <Tool
310 Name="VCWebServiceProxyGeneratorTool"/>
311 <Tool
312 Name="VCWebDeploymentTool"/>
313 </Configuration>
314 </Configurations>
315 <Files>
316 <Filter
317 Name="Source Files"
318 Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90">
319 <File
320 RelativePath=".\adler32.c">
321 </File>
322 <File
323 RelativePath=".\compress.c">
324 </File>
325 <File
326 RelativePath=".\crc32.c">
327 </File>
328 <File
329 RelativePath=".\deflate.c">
330 </File>
331 <File
332 RelativePath=".\gvmat32c.c">
333 <FileConfiguration
334 Name="ReleaseWithoutAsm|Win32"
335 ExcludedFromBuild="TRUE">
336 <Tool
337 Name="VCCLCompilerTool"/>
338 </FileConfiguration>
339 </File>
340 <File
341 RelativePath=".\gzio.c">
342 </File>
343 <File
344 RelativePath=".\infback.c">
345 </File>
346 <File
347 RelativePath=".\inffast.c">
348 </File>
349 <File
350 RelativePath=".\inflate.c">
351 </File>
352 <File
353 RelativePath=".\inftrees.c">
354 </File>
355 <File
356 RelativePath=".\ioapi.c">
357 </File>
358 <File
359 RelativePath=".\iowin32.c">
360 </File>
361 <File
362 RelativePath=".\trees.c">
363 </File>
364 <File
365 RelativePath=".\uncompr.c">
366 </File>
367 <File
368 RelativePath=".\unzip.c">
369 <FileConfiguration
370 Name="Release|Win32">
371 <Tool
372 Name="VCCLCompilerTool"
373 AdditionalIncludeDirectories=""
374 PreprocessorDefinitions="ZLIB_INTERNAL"/>
375 </FileConfiguration>
376 </File>
377 <File
378 RelativePath=".\zip.c">
379 <FileConfiguration
380 Name="Release|Win32">
381 <Tool
382 Name="VCCLCompilerTool"
383 AdditionalIncludeDirectories=""
384 PreprocessorDefinitions="ZLIB_INTERNAL"/>
385 </FileConfiguration>
386 </File>
387 <File
388 RelativePath=".\zlib.rc">
389 </File>
390 <File
391 RelativePath=".\zlibvc.def">
392 </File>
393 <File
394 RelativePath=".\zutil.c">
395 </File>
396 </Filter>
397 <Filter
398 Name="Header Files"
399 Filter="h;hpp;hxx;hm;inl;fi;fd">
400 <File
401 RelativePath=".\deflate.h">
402 </File>
403 <File
404 RelativePath=".\infblock.h">
405 </File>
406 <File
407 RelativePath=".\infcodes.h">
408 </File>
409 <File
410 RelativePath=".\inffast.h">
411 </File>
412 <File
413 RelativePath=".\inftrees.h">
414 </File>
415 <File
416 RelativePath=".\infutil.h">
417 </File>
418 <File
419 RelativePath=".\zconf.h">
420 </File>
421 <File
422 RelativePath=".\zlib.h">
423 </File>
424 <File
425 RelativePath=".\zutil.h">
426 </File>
427 </Filter>
428 <Filter
429 Name="Resource Files"
430 Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
431 </Filter>
432 </Files>
433 <Globals>
434 </Globals>
435 </VisualStudioProject>
0 /* crc32.c -- compute the CRC-32 of a data stream
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 *
4 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
5 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
6 * tables for updating the shift register in one step with three exclusive-ors
7 * instead of four steps with four exclusive-ors. This results in about a
8 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
9 */
10
11 /* @(#) $Id$ */
12
13 /*
14 Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
15 protection on the static variables used to control the first-use generation
16 of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
17 first call get_crc_table() to initialize the tables before allowing more than
18 one thread to use crc32().
19 */
20
21 #ifdef MAKECRCH
22 # include <stdio.h>
23 # ifndef DYNAMIC_CRC_TABLE
24 # define DYNAMIC_CRC_TABLE
25 # endif /* !DYNAMIC_CRC_TABLE */
26 #endif /* MAKECRCH */
27
28 #include "zutil.h" /* for STDC and FAR definitions */
29
30 #define local static
31
32 /* Find a four-byte integer type for crc32_little() and crc32_big(). */
33 #ifndef NOBYFOUR
34 # ifdef STDC /* need ANSI C limits.h to determine sizes */
35 # include <limits.h>
36 # define BYFOUR
37 # if (UINT_MAX == 0xffffffffUL)
38 typedef unsigned int u4;
39 # else
40 # if (ULONG_MAX == 0xffffffffUL)
41 typedef unsigned long u4;
42 # else
43 # if (USHRT_MAX == 0xffffffffUL)
44 typedef unsigned short u4;
45 # else
46 # undef BYFOUR /* can't find a four-byte integer type! */
47 # endif
48 # endif
49 # endif
50 # endif /* STDC */
51 #endif /* !NOBYFOUR */
52
53 /* Definitions for doing the crc four data bytes at a time. */
54 #ifdef BYFOUR
55 # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
56 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
57 local unsigned long crc32_little OF((unsigned long,
58 const unsigned char FAR *, unsigned));
59 local unsigned long crc32_big OF((unsigned long,
60 const unsigned char FAR *, unsigned));
61 # define TBLS 8
62 #else
63 # define TBLS 1
64 #endif /* BYFOUR */
65
66 #ifdef DYNAMIC_CRC_TABLE
67
68 local volatile int crc_table_empty = 1;
69 local unsigned long FAR crc_table[TBLS][256];
70 local void make_crc_table OF((void));
71 #ifdef MAKECRCH
72 local void write_table OF((FILE *, const unsigned long FAR *));
73 #endif /* MAKECRCH */
74 local unsigned long gf2_matrix_times OF((unsigned long *mat,
75 unsigned long vec));
76 local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
77
78 /*
79 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
80 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.
81
82 Polynomials over GF(2) are represented in binary, one bit per coefficient,
83 with the lowest powers in the most significant bit. Then adding polynomials
84 is just exclusive-or, and multiplying a polynomial by x is a right shift by
85 one. If we call the above polynomial p, and represent a byte as the
86 polynomial q, also with the lowest power in the most significant bit (so the
87 byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
88 where a mod b means the remainder after dividing a by b.
89
90 This calculation is done using the shift-register method of multiplying and
91 taking the remainder. The register is initialized to zero, and for each
92 incoming bit, x^32 is added mod p to the register if the bit is a one (where
93 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
94 x (which is shifting right by one and adding x^32 mod p if the bit shifted
95 out is a one). We start with the highest power (least significant bit) of
96 q and repeat for all eight bits of q.
97
98 The first table is simply the CRC of all possible eight bit values. This is
99 all the information needed to generate CRCs on data a byte at a time for all
100 combinations of CRC register values and incoming bytes. The remaining tables
101 allow for word-at-a-time CRC calculation for both big-endian and little-
102 endian machines, where a word is four bytes.
103 */
104 local void make_crc_table()
105 {
106 unsigned long c;
107 int n, k;
108 unsigned long poly; /* polynomial exclusive-or pattern */
109 /* terms of polynomial defining this crc (except x^32): */
110 static volatile int first = 1; /* flag to limit concurrent making */
111 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
112
113 /* See if another task is already doing this (not thread-safe, but better
114 than nothing -- significantly reduces duration of vulnerability in
115 case the advice about DYNAMIC_CRC_TABLE is ignored) */
116 if (first) {
117 first = 0;
118
119 /* make exclusive-or pattern from polynomial (0xedb88320UL) */
120 poly = 0UL;
121 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
122 poly |= 1UL << (31 - p[n]);
123
124 /* generate a crc for every 8-bit value */
125 for (n = 0; n < 256; n++) {
126 c = (unsigned long)n;
127 for (k = 0; k < 8; k++)
128 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
129 crc_table[0][n] = c;
130 }
131
132 #ifdef BYFOUR
133 /* generate crc for each value followed by one, two, and three zeros,
134 and then the byte reversal of those as well as the first table */
135 for (n = 0; n < 256; n++) {
136 c = crc_table[0][n];
137 crc_table[4][n] = REV(c);
138 for (k = 1; k < 4; k++) {
139 c = crc_table[0][c & 0xff] ^ (c >> 8);
140 crc_table[k][n] = c;
141 crc_table[k + 4][n] = REV(c);
142 }
143 }
144 #endif /* BYFOUR */
145
146 crc_table_empty = 0;
147 }
148 else { /* not first */
149 /* wait for the other guy to finish (not efficient, but rare) */
150 while (crc_table_empty)
151 ;
152 }
153
154 #ifdef MAKECRCH
155 /* write out CRC tables to crc32.h */
156 {
157 FILE *out;
158
159 out = fopen("crc32.h", "w");
160 if (out == NULL) return;
161 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
162 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
163 fprintf(out, "local const unsigned long FAR ");
164 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
165 write_table(out, crc_table[0]);
166 # ifdef BYFOUR
167 fprintf(out, "#ifdef BYFOUR\n");
168 for (k = 1; k < 8; k++) {
169 fprintf(out, " },\n {\n");
170 write_table(out, crc_table[k]);
171 }
172 fprintf(out, "#endif\n");
173 # endif /* BYFOUR */
174 fprintf(out, " }\n};\n");
175 fclose(out);
176 }
177 #endif /* MAKECRCH */
178 }
179
180 #ifdef MAKECRCH
181 local void write_table(out, table)
182 FILE *out;
183 const unsigned long FAR *table;
184 {
185 int n;
186
187 for (n = 0; n < 256; n++)
188 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
189 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
190 }
191 #endif /* MAKECRCH */
192
193 #else /* !DYNAMIC_CRC_TABLE */
194 /* ========================================================================
195 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
196 */
197 #include "crc32.h"
198 #endif /* DYNAMIC_CRC_TABLE */
199
200 /* =========================================================================
201 * This function can be used by asm versions of crc32()
202 */
203 const unsigned long FAR * ZEXPORT get_crc_table()
204 {
205 #ifdef DYNAMIC_CRC_TABLE
206 if (crc_table_empty)
207 make_crc_table();
208 #endif /* DYNAMIC_CRC_TABLE */
209 return (const unsigned long FAR *)crc_table;
210 }
211
212 /* ========================================================================= */
213 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
214 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
215
216 /* ========================================================================= */
217 unsigned long ZEXPORT crc32(crc, buf, len)
218 unsigned long crc;
219 const unsigned char FAR *buf;
220 unsigned len;
221 {
222 if (buf == Z_NULL) return 0UL;
223
224 #ifdef DYNAMIC_CRC_TABLE
225 if (crc_table_empty)
226 make_crc_table();
227 #endif /* DYNAMIC_CRC_TABLE */
228
229 #ifdef BYFOUR
230 if (sizeof(void *) == sizeof(ptrdiff_t)) {
231 u4 endian;
232
233 endian = 1;
234 if (*((unsigned char *)(&endian)))
235 return crc32_little(crc, buf, len);
236 else
237 return crc32_big(crc, buf, len);
238 }
239 #endif /* BYFOUR */
240 crc = crc ^ 0xffffffffUL;
241 while (len >= 8) {
242 DO8;
243 len -= 8;
244 }
245 if (len) do {
246 DO1;
247 } while (--len);
248 return crc ^ 0xffffffffUL;
249 }
250
251 #ifdef BYFOUR
252
253 /* ========================================================================= */
254 #define DOLIT4 c ^= *buf4++; \
255 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
256 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
257 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
258
259 /* ========================================================================= */
260 local unsigned long crc32_little(crc, buf, len)
261 unsigned long crc;
262 const unsigned char FAR *buf;
263 unsigned len;
264 {
265 register u4 c;
266 register const u4 FAR *buf4;
267
268 c = (u4)crc;
269 c = ~c;
270 while (len && ((ptrdiff_t)buf & 3)) {
271 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
272 len--;
273 }
274
275 buf4 = (const u4 FAR *)buf;
276 while (len >= 32) {
277 DOLIT32;
278 len -= 32;
279 }
280 while (len >= 4) {
281 DOLIT4;
282 len -= 4;
283 }
284 buf = (const unsigned char FAR *)buf4;
285
286 if (len) do {
287 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
288 } while (--len);
289 c = ~c;
290 return (unsigned long)c;
291 }
292
293 /* ========================================================================= */
294 #define DOBIG4 c ^= *++buf4; \
295 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
296 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
297 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
298
299 /* ========================================================================= */
300 local unsigned long crc32_big(crc, buf, len)
301 unsigned long crc;
302 const unsigned char FAR *buf;
303 unsigned len;
304 {
305 register u4 c;
306 register const u4 FAR *buf4;
307
308 c = REV((u4)crc);
309 c = ~c;
310 while (len && ((ptrdiff_t)buf & 3)) {
311 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
312 len--;
313 }
314
315 buf4 = (const u4 FAR *)buf;
316 buf4--;
317 while (len >= 32) {
318 DOBIG32;
319 len -= 32;
320 }
321 while (len >= 4) {
322 DOBIG4;
323 len -= 4;
324 }
325 buf4++;
326 buf = (const unsigned char FAR *)buf4;
327
328 if (len) do {
329 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
330 } while (--len);
331 c = ~c;
332 return (unsigned long)(REV(c));
333 }
334
335 #endif /* BYFOUR */
336
337 #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
338
339 /* ========================================================================= */
340 local unsigned long gf2_matrix_times(mat, vec)
341 unsigned long *mat;
342 unsigned long vec;
343 {
344 unsigned long sum;
345
346 sum = 0;
347 while (vec) {
348 if (vec & 1)
349 sum ^= *mat;
350 vec >>= 1;
351 mat++;
352 }
353 return sum;
354 }
355
356 /* ========================================================================= */
357 local void gf2_matrix_square(square, mat)
358 unsigned long *square;
359 unsigned long *mat;
360 {
361 int n;
362
363 for (n = 0; n < GF2_DIM; n++)
364 square[n] = gf2_matrix_times(mat, mat[n]);
365 }
366
367 /* ========================================================================= */
368 uLong ZEXPORT crc32_combine(crc1, crc2, len2)
369 uLong crc1;
370 uLong crc2;
371 z_off_t len2;
372 {
373 int n;
374 unsigned long row;
375 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
376 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
377
378 /* degenerate case */
379 if (len2 == 0)
380 return crc1;
381
382 /* put operator for one zero bit in odd */
383 odd[0] = 0xedb88320L; /* CRC-32 polynomial */
384 row = 1;
385 for (n = 1; n < GF2_DIM; n++) {
386 odd[n] = row;
387 row <<= 1;
388 }
389
390 /* put operator for two zero bits in even */
391 gf2_matrix_square(even, odd);
392
393 /* put operator for four zero bits in odd */
394 gf2_matrix_square(odd, even);
395
396 /* apply len2 zeros to crc1 (first square will put the operator for one
397 zero byte, eight zero bits, in even) */
398 do {
399 /* apply zeros operator for this bit of len2 */
400 gf2_matrix_square(even, odd);
401 if (len2 & 1)
402 crc1 = gf2_matrix_times(even, crc1);
403 len2 >>= 1;
404
405 /* if no more bits set, then done */
406 if (len2 == 0)
407 break;
408
409 /* another iteration of the loop with odd and even swapped */
410 gf2_matrix_square(odd, even);
411 if (len2 & 1)
412 crc1 = gf2_matrix_times(odd, crc1);
413 len2 >>= 1;
414
415 /* if no more bits set, then done */
416 } while (len2 != 0);
417
418 /* return combined crc */
419 crc1 ^= crc2;
420 return crc1;
421 }
0 /* crc32.h -- tables for rapid CRC calculation
1 * Generated automatically by crc32.c
2 */
3
4 local const unsigned long FAR crc_table[TBLS][256] =
5 {
6 {
7 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
8 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
9 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
10 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
11 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
12 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
13 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
14 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
15 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
16 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
17 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
18 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
19 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
20 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
21 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
22 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
23 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
24 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
25 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
26 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
27 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
28 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
29 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
30 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
31 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
32 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
33 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
34 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
35 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
36 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
37 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
38 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
39 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
40 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
41 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
42 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
43 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
44 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
45 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
46 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
47 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
48 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
49 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
50 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
51 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
52 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
53 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
54 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
55 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
56 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
57 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
58 0x2d02ef8dUL
59 #ifdef BYFOUR
60 },
61 {
62 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
63 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
64 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
65 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
66 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
67 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
68 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
69 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
70 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
71 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
72 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
73 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
74 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
75 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
76 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
77 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
78 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
79 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
80 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
81 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
82 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
83 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
84 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
85 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
86 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
87 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
88 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
89 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
90 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
91 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
92 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
93 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
94 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
95 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
96 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
97 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
98 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
99 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
100 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
101 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
102 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
103 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
104 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
105 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
106 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
107 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
108 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
109 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
110 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
111 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
112 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
113 0x9324fd72UL
114 },
115 {
116 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
117 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
118 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
119 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
120 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
121 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
122 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
123 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
124 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
125 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
126 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
127 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
128 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
129 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
130 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
131 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
132 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
133 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
134 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
135 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
136 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
137 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
138 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
139 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
140 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
141 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
142 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
143 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
144 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
145 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
146 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
147 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
148 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
149 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
150 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
151 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
152 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
153 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
154 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
155 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
156 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
157 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
158 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
159 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
160 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
161 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
162 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
163 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
164 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
165 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
166 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
167 0xbe9834edUL
168 },
169 {
170 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
171 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
172 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
173 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
174 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
175 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
176 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
177 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
178 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
179 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
180 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
181 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
182 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
183 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
184 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
185 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
186 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
187 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
188 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
189 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
190 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
191 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
192 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
193 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
194 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
195 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
196 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
197 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
198 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
199 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
200 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
201 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
202 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
203 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
204 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
205 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
206 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
207 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
208 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
209 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
210 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
211 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
212 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
213 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
214 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
215 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
216 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
217 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
218 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
219 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
220 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
221 0xde0506f1UL
222 },
223 {
224 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
225 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
226 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
227 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
228 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
229 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
230 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
231 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
232 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
233 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
234 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
235 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
236 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
237 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
238 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
239 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
240 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
241 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
242 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
243 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
244 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
245 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
246 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
247 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
248 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
249 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
250 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
251 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
252 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
253 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
254 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
255 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
256 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
257 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
258 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
259 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
260 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
261 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
262 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
263 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
264 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
265 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
266 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
267 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
268 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
269 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
270 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
271 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
272 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
273 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
274 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
275 0x8def022dUL
276 },
277 {
278 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
279 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
280 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
281 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
282 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
283 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
284 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
285 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
286 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
287 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
288 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
289 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
290 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
291 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
292 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
293 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
294 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
295 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
296 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
297 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
298 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
299 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
300 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
301 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
302 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
303 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
304 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
305 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
306 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
307 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
308 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
309 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
310 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
311 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
312 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
313 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
314 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
315 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
316 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
317 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
318 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
319 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
320 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
321 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
322 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
323 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
324 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
325 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
326 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
327 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
328 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
329 0x72fd2493UL
330 },
331 {
332 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
333 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
334 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
335 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
336 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
337 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
338 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
339 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
340 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
341 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
342 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
343 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
344 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
345 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
346 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
347 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
348 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
349 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
350 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
351 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
352 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
353 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
354 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
355 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
356 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
357 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
358 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
359 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
360 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
361 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
362 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
363 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
364 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
365 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
366 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
367 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
368 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
369 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
370 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
371 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
372 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
373 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
374 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
375 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
376 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
377 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
378 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
379 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
380 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
381 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
382 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
383 0xed3498beUL
384 },
385 {
386 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
387 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
388 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
389 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
390 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
391 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
392 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
393 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
394 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
395 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
396 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
397 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
398 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
399 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
400 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
401 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
402 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
403 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
404 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
405 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
406 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
407 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
408 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
409 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
410 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
411 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
412 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
413 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
414 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
415 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
416 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
417 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
418 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
419 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
420 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
421 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
422 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
423 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
424 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
425 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
426 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
427 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
428 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
429 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
430 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
431 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
432 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
433 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
434 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
435 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
436 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
437 0xf10605deUL
438 #endif
439 }
440 };
0 /* deflate.c -- compress data using the deflation algorithm
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 * ALGORITHM
7 *
8 * The "deflation" process depends on being able to identify portions
9 * of the input text which are identical to earlier input (within a
10 * sliding window trailing behind the input currently being processed).
11 *
12 * The most straightforward technique turns out to be the fastest for
13 * most input files: try all possible matches and select the longest.
14 * The key feature of this algorithm is that insertions into the string
15 * dictionary are very simple and thus fast, and deletions are avoided
16 * completely. Insertions are performed at each input character, whereas
17 * string matches are performed only when the previous match ends. So it
18 * is preferable to spend more time in matches to allow very fast string
19 * insertions and avoid deletions. The matching algorithm for small
20 * strings is inspired from that of Rabin & Karp. A brute force approach
21 * is used to find longer strings when a small match has been found.
22 * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
23 * (by Leonid Broukhis).
24 * A previous version of this file used a more sophisticated algorithm
25 * (by Fiala and Greene) which is guaranteed to run in linear amortized
26 * time, but has a larger average cost, uses more memory and is patented.
27 * However the F&G algorithm may be faster for some highly redundant
28 * files if the parameter max_chain_length (described below) is too large.
29 *
30 * ACKNOWLEDGEMENTS
31 *
32 * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
33 * I found it in 'freeze' written by Leonid Broukhis.
34 * Thanks to many people for bug reports and testing.
35 *
36 * REFERENCES
37 *
38 * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
39 * Available in http://www.ietf.org/rfc/rfc1951.txt
40 *
41 * A description of the Rabin and Karp algorithm is given in the book
42 * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
43 *
44 * Fiala,E.R., and Greene,D.H.
45 * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
46 *
47 */
48
49 /* @(#) $Id$ */
50
51 #include "deflate.h"
52
53 const char deflate_copyright[] =
54 " deflate 1.2.2.2 Copyright 1995-2004 Jean-loup Gailly ";
55 /*
56 If you use the zlib library in a product, an acknowledgment is welcome
57 in the documentation of your product. If for some reason you cannot
58 include such an acknowledgment, I would appreciate that you keep this
59 copyright string in the executable of your product.
60 */
61
62 /* ===========================================================================
63 * Function prototypes.
64 */
65 typedef enum {
66 need_more, /* block not completed, need more input or more output */
67 block_done, /* block flush performed */
68 finish_started, /* finish started, need only more output at next deflate */
69 finish_done /* finish done, accept no more input or output */
70 } block_state;
71
72 typedef block_state (*compress_func) OF((deflate_state *s, int flush));
73 /* Compression function. Returns the block state after the call. */
74
75 local void fill_window OF((deflate_state *s));
76 local block_state deflate_stored OF((deflate_state *s, int flush));
77 local block_state deflate_fast OF((deflate_state *s, int flush));
78 #ifndef FASTEST
79 local block_state deflate_slow OF((deflate_state *s, int flush));
80 #endif
81 local void lm_init OF((deflate_state *s));
82 local void putShortMSB OF((deflate_state *s, uInt b));
83 local void flush_pending OF((z_streamp strm));
84 local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
85 #ifndef FASTEST
86 #ifdef ASMV
87 void match_init OF((void)); /* asm code initialization */
88 uInt longest_match OF((deflate_state *s, IPos cur_match));
89 #else
90 local uInt longest_match OF((deflate_state *s, IPos cur_match));
91 #endif
92 #endif
93 local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
94
95 #ifdef DEBUG
96 local void check_match OF((deflate_state *s, IPos start, IPos match,
97 int length));
98 #endif
99
100 /* ===========================================================================
101 * Local data
102 */
103
104 #define NIL 0
105 /* Tail of hash chains */
106
107 #ifndef TOO_FAR
108 # define TOO_FAR 4096
109 #endif
110 /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
111
112 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
113 /* Minimum amount of lookahead, except at the end of the input file.
114 * See deflate.c for comments about the MIN_MATCH+1.
115 */
116
117 #ifndef RSYNC_WIN
118 # define RSYNC_WIN 4096
119 #endif
120 /* Size of rsync window, must be < MAX_DIST */
121
122 #define RSYNC_SUM_MATCH(sum) ((sum) % RSYNC_WIN == 0)
123 /* Whether window sum matches magic value */
124
125 /* Values for max_lazy_match, good_match and max_chain_length, depending on
126 * the desired pack level (0..9). The values given below have been tuned to
127 * exclude worst case performance for pathological files. Better values may be
128 * found for specific files.
129 */
130 typedef struct config_s {
131 ush good_length; /* reduce lazy search above this match length */
132 ush max_lazy; /* do not perform lazy search above this match length */
133 ush nice_length; /* quit search above this match length */
134 ush max_chain;
135 compress_func func;
136 } config;
137
138 #ifdef FASTEST
139 local const config configuration_table[2] = {
140 /* good lazy nice chain */
141 /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
142 /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
143 #else
144 local const config configuration_table[10] = {
145 /* good lazy nice chain */
146 /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
147 /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
148 /* 2 */ {4, 5, 16, 8, deflate_fast},
149 /* 3 */ {4, 6, 32, 32, deflate_fast},
150
151 /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
152 /* 5 */ {8, 16, 32, 32, deflate_slow},
153 /* 6 */ {8, 16, 128, 128, deflate_slow},
154 /* 7 */ {8, 32, 128, 256, deflate_slow},
155 /* 8 */ {32, 128, 258, 1024, deflate_slow},
156 /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
157 #endif
158
159 /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
160 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
161 * meaning.
162 */
163
164 #define EQUAL 0
165 /* result of memcmp for equal strings */
166
167 #ifndef NO_DUMMY_DECL
168 struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
169 #endif
170
171 /* ===========================================================================
172 * Update a hash value with the given input byte
173 * IN assertion: all calls to to UPDATE_HASH are made with consecutive
174 * input characters, so that a running hash key can be computed from the
175 * previous key instead of complete recalculation each time.
176 */
177 #define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
178
179
180 /* ===========================================================================
181 * Insert string str in the dictionary and set match_head to the previous head
182 * of the hash chain (the most recent string with same hash key). Return
183 * the previous length of the hash chain.
184 * If this file is compiled with -DFASTEST, the compression level is forced
185 * to 1, and no hash chains are maintained.
186 * IN assertion: all calls to to INSERT_STRING are made with consecutive
187 * input characters and the first MIN_MATCH bytes of str are valid
188 * (except for the last MIN_MATCH-1 bytes of the input file).
189 */
190 #ifdef FASTEST
191 #define INSERT_STRING(s, str, match_head) \
192 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
193 match_head = s->head[s->ins_h], \
194 s->head[s->ins_h] = (Pos)(str))
195 #else
196 #define INSERT_STRING(s, str, match_head) \
197 (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
198 match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
199 s->head[s->ins_h] = (Pos)(str))
200 #endif
201
202 /* ===========================================================================
203 * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
204 * prev[] will be initialized on the fly.
205 */
206 #define CLEAR_HASH(s) \
207 s->head[s->hash_size-1] = NIL; \
208 zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
209
210 /* ========================================================================= */
211 int ZEXPORT deflateInit_(strm, level, version, stream_size)
212 z_streamp strm;
213 int level;
214 const char *version;
215 int stream_size;
216 {
217 return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
218 Z_DEFAULT_STRATEGY, version, stream_size);
219 /* To do: ignore strm->next_in if we use it as window */
220 }
221
222 /* ========================================================================= */
223 int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
224 version, stream_size)
225 z_streamp strm;
226 int level;
227 int method;
228 int windowBits;
229 int memLevel;
230 int strategy;
231 const char *version;
232 int stream_size;
233 {
234 deflate_state *s;
235 int wrap = 1;
236 int rsyncable = 0;
237 static const char my_version[] = ZLIB_VERSION;
238
239 ushf *overlay;
240 /* We overlay pending_buf and d_buf+l_buf. This works since the average
241 * output size for (length,distance) codes is <= 24 bits.
242 */
243
244 if (version == Z_NULL || version[0] != my_version[0] ||
245 stream_size != sizeof(z_stream)) {
246 return Z_VERSION_ERROR;
247 }
248 if (strm == Z_NULL) return Z_STREAM_ERROR;
249
250 strm->msg = Z_NULL;
251 if (strm->zalloc == (alloc_func)0) {
252 strm->zalloc = zcalloc;
253 strm->opaque = (voidpf)0;
254 }
255 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
256
257 #ifdef FASTEST
258 if (level != 0) level = 1;
259 #else
260 if (level == Z_DEFAULT_COMPRESSION) level = 6;
261 #endif
262
263 if (windowBits < 0) { /* suppress zlib wrapper */
264 wrap = 0;
265 windowBits = -windowBits;
266 }
267 #ifdef GZIP
268 else if (windowBits > 15) {
269 wrap = 2; /* write gzip wrapper instead */
270 windowBits -= 16;
271 }
272 #endif
273 if ((strategy & Z_RSYNCABLE) != 0) {
274 strategy ^= Z_RSYNCABLE;
275 rsyncable = 1;
276 }
277 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
278 windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
279 strategy < 0 || strategy > Z_FIXED) {
280 return Z_STREAM_ERROR;
281 }
282 if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
283 s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
284 if (s == Z_NULL) return Z_MEM_ERROR;
285 strm->state = (struct internal_state FAR *)s;
286 s->strm = strm;
287
288 s->wrap = wrap;
289 s->gzhead = Z_NULL;
290 s->w_bits = windowBits;
291 s->w_size = 1 << s->w_bits;
292 s->w_mask = s->w_size - 1;
293
294 s->hash_bits = memLevel + 7;
295 s->hash_size = 1 << s->hash_bits;
296 s->hash_mask = s->hash_size - 1;
297 s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
298
299 s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
300 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
301 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
302
303 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
304
305 overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
306 s->pending_buf = (uchf *) overlay;
307 s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
308
309 if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
310 s->pending_buf == Z_NULL) {
311 s->status = FINISH_STATE;
312 strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
313 deflateEnd (strm);
314 return Z_MEM_ERROR;
315 }
316 s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
317 s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
318
319 s->level = level;
320 s->strategy = strategy;
321 s->method = (Byte)method;
322 s->rsyncable = rsyncable;
323
324 return deflateReset(strm);
325 }
326
327 /* ========================================================================= */
328 int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
329 z_streamp strm;
330 const Bytef *dictionary;
331 uInt dictLength;
332 {
333 deflate_state *s;
334 uInt length = dictLength;
335 uInt n;
336 IPos hash_head = 0;
337
338 if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
339 strm->state->wrap == 2 ||
340 (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
341 return Z_STREAM_ERROR;
342
343 s = strm->state;
344 if (s->wrap)
345 strm->adler = adler32(strm->adler, dictionary, dictLength);
346
347 if (length < MIN_MATCH) return Z_OK;
348 if (length > MAX_DIST(s)) {
349 length = MAX_DIST(s);
350 #ifndef USE_DICT_HEAD
351 dictionary += dictLength - length; /* use the tail of the dictionary */
352 #endif
353 }
354 zmemcpy(s->window, dictionary, length);
355 s->strstart = length;
356 s->block_start = (long)length;
357
358 /* Insert all strings in the hash table (except for the last two bytes).
359 * s->lookahead stays null, so s->ins_h will be recomputed at the next
360 * call of fill_window.
361 */
362 s->ins_h = s->window[0];
363 UPDATE_HASH(s, s->ins_h, s->window[1]);
364 for (n = 0; n <= length - MIN_MATCH; n++) {
365 INSERT_STRING(s, n, hash_head);
366 }
367 if (hash_head) hash_head = 0; /* to make compiler happy */
368 return Z_OK;
369 }
370
371 /* ========================================================================= */
372 int ZEXPORT deflateReset (strm)
373 z_streamp strm;
374 {
375 deflate_state *s;
376
377 if (strm == Z_NULL || strm->state == Z_NULL ||
378 strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
379 return Z_STREAM_ERROR;
380 }
381
382 strm->total_in = strm->total_out = 0;
383 strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
384 strm->data_type = Z_UNKNOWN;
385
386 s = (deflate_state *)strm->state;
387 s->pending = 0;
388 s->pending_out = s->pending_buf;
389
390 if (s->wrap < 0) {
391 s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
392 }
393 s->status = s->wrap ? INIT_STATE : BUSY_STATE;
394 strm->adler =
395 #ifdef GZIP
396 s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
397 #endif
398 adler32(0L, Z_NULL, 0);
399 s->last_flush = Z_NO_FLUSH;
400
401 _tr_init(s);
402 lm_init(s);
403
404 return Z_OK;
405 }
406
407 /* ========================================================================= */
408 int ZEXPORT deflateSetHeader (strm, head)
409 z_streamp strm;
410 gz_headerp head;
411 {
412 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
413 if (strm->state->wrap != 2) return Z_STREAM_ERROR;
414 strm->state->gzhead = head;
415 return Z_OK;
416 }
417
418 /* ========================================================================= */
419 int ZEXPORT deflatePrime (strm, bits, value)
420 z_streamp strm;
421 int bits;
422 int value;
423 {
424 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
425 strm->state->bi_valid = bits;
426 strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
427 return Z_OK;
428 }
429
430 /* ========================================================================= */
431 int ZEXPORT deflateParams(strm, level, strategy)
432 z_streamp strm;
433 int level;
434 int strategy;
435 {
436 deflate_state *s;
437 compress_func func;
438 int err = Z_OK;
439
440 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
441 s = strm->state;
442
443 #ifdef FASTEST
444 if (level != 0) level = 1;
445 #else
446 if (level == Z_DEFAULT_COMPRESSION) level = 6;
447 #endif
448 if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
449 return Z_STREAM_ERROR;
450 }
451 func = configuration_table[s->level].func;
452
453 if (func != configuration_table[level].func && strm->total_in != 0) {
454 /* Flush the last buffer: */
455 err = deflate(strm, Z_PARTIAL_FLUSH);
456 }
457 if (s->level != level) {
458 s->level = level;
459 s->max_lazy_match = configuration_table[level].max_lazy;
460 s->good_match = configuration_table[level].good_length;
461 s->nice_match = configuration_table[level].nice_length;
462 s->max_chain_length = configuration_table[level].max_chain;
463 }
464 s->strategy = strategy;
465 return err;
466 }
467
468 /* =========================================================================
469 * For the default windowBits of 15 and memLevel of 8, this function returns
470 * a close to exact, as well as small, upper bound on the compressed size.
471 * They are coded as constants here for a reason--if the #define's are
472 * changed, then this function needs to be changed as well. The return
473 * value for 15 and 8 only works for those exact settings.
474 *
475 * For any setting other than those defaults for windowBits and memLevel,
476 * the value returned is a conservative worst case for the maximum expansion
477 * resulting from using fixed blocks instead of stored blocks, which deflate
478 * can emit on compressed data for some combinations of the parameters.
479 *
480 * This function could be more sophisticated to provide closer upper bounds
481 * for every combination of windowBits and memLevel, as well as wrap.
482 * But even the conservative upper bound of about 14% expansion does not
483 * seem onerous for output buffer allocation.
484 */
485 uLong ZEXPORT deflateBound(strm, sourceLen)
486 z_streamp strm;
487 uLong sourceLen;
488 {
489 deflate_state *s;
490 uLong destLen;
491
492 /* conservative upper bound */
493 destLen = sourceLen +
494 ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
495
496 /* if can't get parameters, return conservative bound */
497 if (strm == Z_NULL || strm->state == Z_NULL)
498 return destLen;
499
500 /* if not default parameters, return conservative bound */
501 s = strm->state;
502 if (s->w_bits != 15 || s->hash_bits != 8 + 7)
503 return destLen;
504
505 /* default settings: return tight bound for that case */
506 return compressBound(sourceLen);
507 }
508
509 /* =========================================================================
510 * Put a short in the pending buffer. The 16-bit value is put in MSB order.
511 * IN assertion: the stream state is correct and there is enough room in
512 * pending_buf.
513 */
514 local void putShortMSB (s, b)
515 deflate_state *s;
516 uInt b;
517 {
518 put_byte(s, (Byte)(b >> 8));
519 put_byte(s, (Byte)(b & 0xff));
520 }
521
522 /* =========================================================================
523 * Flush as much pending output as possible. All deflate() output goes
524 * through this function so some applications may wish to modify it
525 * to avoid allocating a large strm->next_out buffer and copying into it.
526 * (See also read_buf()).
527 */
528 local void flush_pending(strm)
529 z_streamp strm;
530 {
531 unsigned len = strm->state->pending;
532
533 if (len > strm->avail_out) len = strm->avail_out;
534 if (len == 0) return;
535
536 zmemcpy(strm->next_out, strm->state->pending_out, len);
537 strm->next_out += len;
538 strm->state->pending_out += len;
539 strm->total_out += len;
540 strm->avail_out -= len;
541 strm->state->pending -= len;
542 if (strm->state->pending == 0) {
543 strm->state->pending_out = strm->state->pending_buf;
544 }
545 }
546
547 /* ========================================================================= */
548 int ZEXPORT deflate (strm, flush)
549 z_streamp strm;
550 int flush;
551 {
552 int old_flush; /* value of flush param for previous deflate call */
553 deflate_state *s;
554
555 if (strm == Z_NULL || strm->state == Z_NULL ||
556 flush > Z_FINISH || flush < 0) {
557 return Z_STREAM_ERROR;
558 }
559 s = strm->state;
560
561 if (strm->next_out == Z_NULL ||
562 (strm->next_in == Z_NULL && strm->avail_in != 0) ||
563 (s->status == FINISH_STATE && flush != Z_FINISH)) {
564 ERR_RETURN(strm, Z_STREAM_ERROR);
565 }
566 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
567
568 s->strm = strm; /* just in case */
569 old_flush = s->last_flush;
570 s->last_flush = flush;
571
572 /* Write the header */
573 if (s->status == INIT_STATE) {
574 #ifdef GZIP
575 if (s->wrap == 2) {
576 strm->adler = crc32(0L, Z_NULL, 0);
577 put_byte(s, 31);
578 put_byte(s, 139);
579 put_byte(s, 8);
580 if (s->gzhead == NULL) {
581 put_byte(s, 0);
582 put_byte(s, 0);
583 put_byte(s, 0);
584 put_byte(s, 0);
585 put_byte(s, 0);
586 put_byte(s, s->level == 9 ? 2 :
587 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
588 4 : 0));
589 put_byte(s, OS_CODE);
590 s->status = BUSY_STATE;
591 }
592 else {
593 put_byte(s, (s->gzhead->text ? 1 : 0) +
594 (s->gzhead->hcrc ? 2 : 0) +
595 (s->gzhead->extra == Z_NULL ? 0 : 4) +
596 (s->gzhead->name == Z_NULL ? 0 : 8) +
597 (s->gzhead->comment == Z_NULL ? 0 : 16)
598 );
599 put_byte(s, s->gzhead->time & 0xff);
600 put_byte(s, (s->gzhead->time >> 8) & 0xff);
601 put_byte(s, (s->gzhead->time >> 16) & 0xff);
602 put_byte(s, (s->gzhead->time >> 24) & 0xff);
603 put_byte(s, s->level == 9 ? 2 :
604 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
605 4 : 0));
606 put_byte(s, s->gzhead->os & 0xff);
607 if (s->gzhead->extra != NULL) {
608 put_byte(s, s->gzhead->extra_len & 0xff);
609 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
610 }
611 if (s->gzhead->hcrc)
612 strm->adler = crc32(strm->adler, s->pending_buf,
613 s->pending);
614 s->gzindex = 0;
615 s->status = EXTRA_STATE;
616 }
617 }
618 else
619 #endif
620 {
621 uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
622 uInt level_flags;
623
624 if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
625 level_flags = 0;
626 else if (s->level < 6)
627 level_flags = 1;
628 else if (s->level == 6)
629 level_flags = 2;
630 else
631 level_flags = 3;
632 header |= (level_flags << 6);
633 if (s->strstart != 0) header |= PRESET_DICT;
634 header += 31 - (header % 31);
635
636 s->status = BUSY_STATE;
637 putShortMSB(s, header);
638
639 /* Save the adler32 of the preset dictionary: */
640 if (s->strstart != 0) {
641 putShortMSB(s, (uInt)(strm->adler >> 16));
642 putShortMSB(s, (uInt)(strm->adler & 0xffff));
643 }
644 strm->adler = adler32(0L, Z_NULL, 0);
645 }
646 }
647 #ifdef GZIP
648 if (s->status == EXTRA_STATE) {
649 if (s->gzhead->extra != NULL) {
650 int beg = s->pending; /* start of bytes to update crc */
651
652 while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
653 if (s->pending == s->pending_buf_size) {
654 if (s->gzhead->hcrc && s->pending > beg)
655 strm->adler = crc32(strm->adler, s->pending_buf + beg,
656 s->pending - beg);
657 flush_pending(strm);
658 beg = s->pending;
659 if (s->pending == s->pending_buf_size)
660 break;
661 }
662 put_byte(s, s->gzhead->extra[s->gzindex]);
663 s->gzindex++;
664 }
665 if (s->gzhead->hcrc && s->pending > beg)
666 strm->adler = crc32(strm->adler, s->pending_buf + beg,
667 s->pending - beg);
668 if (s->gzindex == s->gzhead->extra_len) {
669 s->gzindex = 0;
670 s->status = NAME_STATE;
671 }
672 }
673 else
674 s->status = NAME_STATE;
675 }
676 if (s->status == NAME_STATE) {
677 if (s->gzhead->name != NULL) {
678 int beg = s->pending; /* start of bytes to update crc */
679 int val;
680
681 do {
682 if (s->pending == s->pending_buf_size) {
683 if (s->gzhead->hcrc && s->pending > beg)
684 strm->adler = crc32(strm->adler, s->pending_buf + beg,
685 s->pending - beg);
686 flush_pending(strm);
687 beg = s->pending;
688 if (s->pending == s->pending_buf_size) {
689 val = 1;
690 break;
691 }
692 }
693 val = s->gzhead->name[s->gzindex++];
694 put_byte(s, val);
695 } while (val != 0);
696 if (s->gzhead->hcrc && s->pending > beg)
697 strm->adler = crc32(strm->adler, s->pending_buf + beg,
698 s->pending - beg);
699 if (val == 0) {
700 s->gzindex = 0;
701 s->status = COMMENT_STATE;
702 }
703 }
704 else
705 s->status = COMMENT_STATE;
706 }
707 if (s->status == COMMENT_STATE) {
708 if (s->gzhead->comment != NULL) {
709 int beg = s->pending; /* start of bytes to update crc */
710 int val;
711
712 do {
713 if (s->pending == s->pending_buf_size) {
714 if (s->gzhead->hcrc && s->pending > beg)
715 strm->adler = crc32(strm->adler, s->pending_buf + beg,
716 s->pending - beg);
717 flush_pending(strm);
718 beg = s->pending;
719 if (s->pending == s->pending_buf_size) {
720 val = 1;
721 break;
722 }
723 }
724 val = s->gzhead->comment[s->gzindex++];
725 put_byte(s, val);
726 } while (val != 0);
727 if (s->gzhead->hcrc && s->pending > beg)
728 strm->adler = crc32(strm->adler, s->pending_buf + beg,
729 s->pending - beg);
730 if (val == 0)
731 s->status = HCRC_STATE;
732 }
733 else
734 s->status = HCRC_STATE;
735 }
736 if (s->status == HCRC_STATE) {
737 if (s->gzhead->hcrc) {
738 if (s->pending + 2 > s->pending_buf_size)
739 flush_pending(strm);
740 if (s->pending + 2 <= s->pending_buf_size) {
741 put_byte(s, strm->adler & 0xff);
742 put_byte(s, (strm->adler >> 8) & 0xff);
743 strm->adler = crc32(0L, Z_NULL, 0);
744 s->status = BUSY_STATE;
745 }
746 }
747 else
748 s->status = BUSY_STATE;
749 }
750 #endif
751
752 /* Flush as much pending output as possible */
753 if (s->pending != 0) {
754 flush_pending(strm);
755 if (strm->avail_out == 0) {
756 /* Since avail_out is 0, deflate will be called again with
757 * more output space, but possibly with both pending and
758 * avail_in equal to zero. There won't be anything to do,
759 * but this is not an error situation so make sure we
760 * return OK instead of BUF_ERROR at next call of deflate:
761 */
762 s->last_flush = -1;
763 return Z_OK;
764 }
765
766 /* Make sure there is something to do and avoid duplicate consecutive
767 * flushes. For repeated and useless calls with Z_FINISH, we keep
768 * returning Z_STREAM_END instead of Z_BUF_ERROR.
769 */
770 } else if (strm->avail_in == 0 && flush <= old_flush &&
771 flush != Z_FINISH) {
772 ERR_RETURN(strm, Z_BUF_ERROR);
773 }
774
775 /* User must not provide more input after the first FINISH: */
776 if (s->status == FINISH_STATE && strm->avail_in != 0) {
777 ERR_RETURN(strm, Z_BUF_ERROR);
778 }
779
780 /* Start a new block or continue the current one.
781 */
782 if (strm->avail_in != 0 || s->lookahead != 0 ||
783 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
784 block_state bstate;
785
786 bstate = (*(configuration_table[s->level].func))(s, flush);
787
788 if (bstate == finish_started || bstate == finish_done) {
789 s->status = FINISH_STATE;
790 }
791 if (bstate == need_more || bstate == finish_started) {
792 if (strm->avail_out == 0) {
793 s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
794 }
795 return Z_OK;
796 /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
797 * of deflate should use the same flush parameter to make sure
798 * that the flush is complete. So we don't have to output an
799 * empty block here, this will be done at next call. This also
800 * ensures that for a very small output buffer, we emit at most
801 * one empty block.
802 */
803 }
804 if (bstate == block_done) {
805 if (flush == Z_PARTIAL_FLUSH) {
806 _tr_align(s);
807 } else { /* FULL_FLUSH or SYNC_FLUSH */
808 _tr_stored_block(s, (char*)0, 0L, 0);
809 /* For a full flush, this empty block will be recognized
810 * as a special marker by inflate_sync().
811 */
812 if (flush == Z_FULL_FLUSH) {
813 CLEAR_HASH(s); /* forget history */
814 }
815 }
816 flush_pending(strm);
817 if (strm->avail_out == 0) {
818 s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
819 return Z_OK;
820 }
821 }
822 }
823 Assert(strm->avail_out > 0, "bug2");
824
825 if (flush != Z_FINISH) return Z_OK;
826 if (s->wrap <= 0) return Z_STREAM_END;
827
828 /* Write the trailer */
829 #ifdef GZIP
830 if (s->wrap == 2) {
831 put_byte(s, (Byte)(strm->adler & 0xff));
832 put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
833 put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
834 put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
835 put_byte(s, (Byte)(strm->total_in & 0xff));
836 put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
837 put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
838 put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
839 }
840 else
841 #endif
842 {
843 putShortMSB(s, (uInt)(strm->adler >> 16));
844 putShortMSB(s, (uInt)(strm->adler & 0xffff));
845 }
846 flush_pending(strm);
847 /* If avail_out is zero, the application will call deflate again
848 * to flush the rest.
849 */
850 if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
851 return s->pending != 0 ? Z_OK : Z_STREAM_END;
852 }
853
854 /* ========================================================================= */
855 int ZEXPORT deflateEnd (strm)
856 z_streamp strm;
857 {
858 int status;
859
860 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
861
862 status = strm->state->status;
863 if (status != INIT_STATE &&
864 status != EXTRA_STATE &&
865 status != NAME_STATE &&
866 status != COMMENT_STATE &&
867 status != HCRC_STATE &&
868 status != BUSY_STATE &&
869 status != FINISH_STATE) {
870 return Z_STREAM_ERROR;
871 }
872
873 /* Deallocate in reverse order of allocations: */
874 TRY_FREE(strm, strm->state->pending_buf);
875 TRY_FREE(strm, strm->state->head);
876 TRY_FREE(strm, strm->state->prev);
877 TRY_FREE(strm, strm->state->window);
878
879 ZFREE(strm, strm->state);
880 strm->state = Z_NULL;
881
882 return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
883 }
884
885 /* =========================================================================
886 * Copy the source state to the destination state.
887 * To simplify the source, this is not supported for 16-bit MSDOS (which
888 * doesn't have enough memory anyway to duplicate compression states).
889 */
890 int ZEXPORT deflateCopy (dest, source)
891 z_streamp dest;
892 z_streamp source;
893 {
894 #ifdef MAXSEG_64K
895 return Z_STREAM_ERROR;
896 #else
897 deflate_state *ds;
898 deflate_state *ss;
899 ushf *overlay;
900
901
902 if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
903 return Z_STREAM_ERROR;
904 }
905
906 ss = source->state;
907
908 zmemcpy(dest, source, sizeof(z_stream));
909
910 ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
911 if (ds == Z_NULL) return Z_MEM_ERROR;
912 dest->state = (struct internal_state FAR *) ds;
913 zmemcpy(ds, ss, sizeof(deflate_state));
914 ds->strm = dest;
915
916 ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
917 ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
918 ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
919 overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
920 ds->pending_buf = (uchf *) overlay;
921
922 if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
923 ds->pending_buf == Z_NULL) {
924 deflateEnd (dest);
925 return Z_MEM_ERROR;
926 }
927 /* following zmemcpy do not work for 16-bit MSDOS */
928 zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
929 zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
930 zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
931 zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
932
933 ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
934 ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
935 ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
936
937 ds->l_desc.dyn_tree = ds->dyn_ltree;
938 ds->d_desc.dyn_tree = ds->dyn_dtree;
939 ds->bl_desc.dyn_tree = ds->bl_tree;
940
941 return Z_OK;
942 #endif /* MAXSEG_64K */
943 }
944
945 /* ===========================================================================
946 * Read a new buffer from the current input stream, update the adler32
947 * and total number of bytes read. All deflate() input goes through
948 * this function so some applications may wish to modify it to avoid
949 * allocating a large strm->next_in buffer and copying from it.
950 * (See also flush_pending()).
951 */
952 local int read_buf(strm, buf, size)
953 z_streamp strm;
954 Bytef *buf;
955 unsigned size;
956 {
957 unsigned len = strm->avail_in;
958
959 if (len > size) len = size;
960 if (len == 0) return 0;
961
962 strm->avail_in -= len;
963
964 if (strm->state->wrap == 1) {
965 strm->adler = adler32(strm->adler, strm->next_in, len);
966 }
967 #ifdef GZIP
968 else if (strm->state->wrap == 2) {
969 strm->adler = crc32(strm->adler, strm->next_in, len);
970 }
971 #endif
972 zmemcpy(buf, strm->next_in, len);
973 strm->next_in += len;
974 strm->total_in += len;
975
976 return (int)len;
977 }
978
979 /* ===========================================================================
980 * Initialize the "longest match" routines for a new zlib stream
981 */
982 local void lm_init (s)
983 deflate_state *s;
984 {
985 s->window_size = (ulg)2L*s->w_size;
986
987 CLEAR_HASH(s);
988
989 /* Set the default configuration parameters:
990 */
991 s->max_lazy_match = configuration_table[s->level].max_lazy;
992 s->good_match = configuration_table[s->level].good_length;
993 s->nice_match = configuration_table[s->level].nice_length;
994 s->max_chain_length = configuration_table[s->level].max_chain;
995
996 s->strstart = 0;
997 s->block_start = 0L;
998 s->lookahead = 0;
999 s->match_length = s->prev_length = MIN_MATCH-1;
1000 s->match_available = 0;
1001 s->ins_h = 0;
1002 #ifdef ASMV
1003 match_init(); /* initialize the asm code */
1004 #endif
1005
1006 /* rsync params */
1007 s->rsync_chunk_end = 0xFFFFFFFFUL;
1008 s->rsync_sum = 0;
1009 }
1010
1011 #ifndef FASTEST
1012 /* ===========================================================================
1013 * Set match_start to the longest match starting at the given string and
1014 * return its length. Matches shorter or equal to prev_length are discarded,
1015 * in which case the result is equal to prev_length and match_start is
1016 * garbage.
1017 * IN assertions: cur_match is the head of the hash chain for the current
1018 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
1019 * OUT assertion: the match length is not greater than s->lookahead.
1020 */
1021 #ifndef ASMV
1022 /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
1023 * match.S. The code will be functionally equivalent.
1024 */
1025 local uInt longest_match(s, cur_match)
1026 deflate_state *s;
1027 IPos cur_match; /* current match */
1028 {
1029 unsigned chain_length = s->max_chain_length;/* max hash chain length */
1030 register Bytef *scan = s->window + s->strstart; /* current string */
1031 register Bytef *match; /* matched string */
1032 register int len; /* length of current match */
1033 int best_len = s->prev_length; /* best match length so far */
1034 int nice_match = s->nice_match; /* stop if match long enough */
1035 IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
1036 s->strstart - (IPos)MAX_DIST(s) : NIL;
1037 /* Stop when cur_match becomes <= limit. To simplify the code,
1038 * we prevent matches with the string of window index 0.
1039 */
1040 Posf *prev = s->prev;
1041 uInt wmask = s->w_mask;
1042
1043 #ifdef UNALIGNED_OK
1044 /* Compare two bytes at a time. Note: this is not always beneficial.
1045 * Try with and without -DUNALIGNED_OK to check.
1046 */
1047 register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
1048 register ush scan_start = *(ushf*)scan;
1049 register ush scan_end = *(ushf*)(scan+best_len-1);
1050 #else
1051 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1052 register Byte scan_end1 = scan[best_len-1];
1053 register Byte scan_end = scan[best_len];
1054 #endif
1055
1056 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1057 * It is easy to get rid of this optimization if necessary.
1058 */
1059 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1060
1061 /* Do not waste too much time if we already have a good match: */
1062 if (s->prev_length >= s->good_match) {
1063 chain_length >>= 2;
1064 }
1065 /* Do not look for matches beyond the end of the input. This is necessary
1066 * to make deflate deterministic.
1067 */
1068 if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
1069
1070 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
1071
1072 do {
1073 Assert(cur_match < s->strstart, "no future");
1074 match = s->window + cur_match;
1075
1076 /* Skip to next match if the match length cannot increase
1077 * or if the match length is less than 2. Note that the checks below
1078 * for insufficient lookahead only occur occasionally for performance
1079 * reasons. Therefore uninitialized memory will be accessed, and
1080 * conditional jumps will be made that depend on those values.
1081 * However the length of the match is limited to the lookahead, so
1082 * the output of deflate is not affected by the uninitialized values.
1083 */
1084 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
1085 /* This code assumes sizeof(unsigned short) == 2. Do not use
1086 * UNALIGNED_OK if your compiler uses a different size.
1087 */
1088 if (*(ushf*)(match+best_len-1) != scan_end ||
1089 *(ushf*)match != scan_start) continue;
1090
1091 /* It is not necessary to compare scan[2] and match[2] since they are
1092 * always equal when the other bytes match, given that the hash keys
1093 * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
1094 * strstart+3, +5, ... up to strstart+257. We check for insufficient
1095 * lookahead only every 4th comparison; the 128th check will be made
1096 * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
1097 * necessary to put more guard bytes at the end of the window, or
1098 * to check more often for insufficient lookahead.
1099 */
1100 Assert(scan[2] == match[2], "scan[2]?");
1101 scan++, match++;
1102 do {
1103 } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1104 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1105 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1106 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
1107 scan < strend);
1108 /* The funny "do {}" generates better code on most compilers */
1109
1110 /* Here, scan <= window+strstart+257 */
1111 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1112 if (*scan == *match) scan++;
1113
1114 len = (MAX_MATCH - 1) - (int)(strend-scan);
1115 scan = strend - (MAX_MATCH-1);
1116
1117 #else /* UNALIGNED_OK */
1118
1119 if (match[best_len] != scan_end ||
1120 match[best_len-1] != scan_end1 ||
1121 *match != *scan ||
1122 *++match != scan[1]) continue;
1123
1124 /* The check at best_len-1 can be removed because it will be made
1125 * again later. (This heuristic is not always a win.)
1126 * It is not necessary to compare scan[2] and match[2] since they
1127 * are always equal when the other bytes match, given that
1128 * the hash keys are equal and that HASH_BITS >= 8.
1129 */
1130 scan += 2, match++;
1131 Assert(*scan == *match, "match[2]?");
1132
1133 /* We check for insufficient lookahead only every 8th comparison;
1134 * the 256th check will be made at strstart+258.
1135 */
1136 do {
1137 } while (*++scan == *++match && *++scan == *++match &&
1138 *++scan == *++match && *++scan == *++match &&
1139 *++scan == *++match && *++scan == *++match &&
1140 *++scan == *++match && *++scan == *++match &&
1141 scan < strend);
1142
1143 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1144
1145 len = MAX_MATCH - (int)(strend - scan);
1146 scan = strend - MAX_MATCH;
1147
1148 #endif /* UNALIGNED_OK */
1149
1150 if (len > best_len) {
1151 s->match_start = cur_match;
1152 best_len = len;
1153 if (len >= nice_match) break;
1154 #ifdef UNALIGNED_OK
1155 scan_end = *(ushf*)(scan+best_len-1);
1156 #else
1157 scan_end1 = scan[best_len-1];
1158 scan_end = scan[best_len];
1159 #endif
1160 }
1161 } while ((cur_match = prev[cur_match & wmask]) > limit
1162 && --chain_length != 0);
1163
1164 if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
1165 return s->lookahead;
1166 }
1167 #endif /* ASMV */
1168 #endif /* FASTEST */
1169
1170 /* ---------------------------------------------------------------------------
1171 * Optimized version for level == 1 or strategy == Z_RLE only
1172 */
1173 local uInt longest_match_fast(s, cur_match)
1174 deflate_state *s;
1175 IPos cur_match; /* current match */
1176 {
1177 register Bytef *scan = s->window + s->strstart; /* current string */
1178 register Bytef *match; /* matched string */
1179 register int len; /* length of current match */
1180 register Bytef *strend = s->window + s->strstart + MAX_MATCH;
1181
1182 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1183 * It is easy to get rid of this optimization if necessary.
1184 */
1185 Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
1186
1187 Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
1188
1189 Assert(cur_match < s->strstart, "no future");
1190
1191 match = s->window + cur_match;
1192
1193 /* Return failure if the match length is less than 2:
1194 */
1195 if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
1196
1197 /* The check at best_len-1 can be removed because it will be made
1198 * again later. (This heuristic is not always a win.)
1199 * It is not necessary to compare scan[2] and match[2] since they
1200 * are always equal when the other bytes match, given that
1201 * the hash keys are equal and that HASH_BITS >= 8.
1202 */
1203 scan += 2, match += 2;
1204 Assert(*scan == *match, "match[2]?");
1205
1206 /* We check for insufficient lookahead only every 8th comparison;
1207 * the 256th check will be made at strstart+258.
1208 */
1209 do {
1210 } while (*++scan == *++match && *++scan == *++match &&
1211 *++scan == *++match && *++scan == *++match &&
1212 *++scan == *++match && *++scan == *++match &&
1213 *++scan == *++match && *++scan == *++match &&
1214 scan < strend);
1215
1216 Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
1217
1218 len = MAX_MATCH - (int)(strend - scan);
1219
1220 if (len < MIN_MATCH) return MIN_MATCH - 1;
1221
1222 s->match_start = cur_match;
1223 return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
1224 }
1225
1226 #ifdef DEBUG
1227 /* ===========================================================================
1228 * Check that the match at match_start is indeed a match.
1229 */
1230 local void check_match(s, start, match, length)
1231 deflate_state *s;
1232 IPos start, match;
1233 int length;
1234 {
1235 /* check that the match is indeed a match */
1236 if (zmemcmp(s->window + match,
1237 s->window + start, length) != EQUAL) {
1238 fprintf(stderr, " start %u, match %u, length %d\n",
1239 start, match, length);
1240 do {
1241 fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
1242 } while (--length != 0);
1243 z_error("invalid match");
1244 }
1245 if (z_verbose > 1) {
1246 fprintf(stderr,"\\[%d,%d]", start-match, length);
1247 do { putc(s->window[start++], stderr); } while (--length != 0);
1248 }
1249 }
1250 #else
1251 # define check_match(s, start, match, length)
1252 #endif /* DEBUG */
1253
1254 /* ===========================================================================
1255 * Fill the window when the lookahead becomes insufficient.
1256 * Updates strstart and lookahead.
1257 *
1258 * IN assertion: lookahead < MIN_LOOKAHEAD
1259 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
1260 * At least one byte has been read, or avail_in == 0; reads are
1261 * performed for at least two bytes (required for the zip translate_eol
1262 * option -- not supported here).
1263 */
1264 local void fill_window(s)
1265 deflate_state *s;
1266 {
1267 register unsigned n, m;
1268 register Posf *p;
1269 unsigned more; /* Amount of free space at the end of the window. */
1270 uInt wsize = s->w_size;
1271
1272 do {
1273 more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
1274
1275 /* Deal with !@#$% 64K limit: */
1276 if (sizeof(int) <= 2) {
1277 if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
1278 more = wsize;
1279
1280 } else if (more == (unsigned)(-1)) {
1281 /* Very unlikely, but possible on 16 bit machine if
1282 * strstart == 0 && lookahead == 1 (input done a byte at time)
1283 */
1284 more--;
1285 }
1286 }
1287
1288 /* If the window is almost full and there is insufficient lookahead,
1289 * move the upper half to the lower one to make room in the upper half.
1290 */
1291 if (s->strstart >= wsize+MAX_DIST(s)) {
1292
1293 zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
1294 s->match_start -= wsize;
1295 s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
1296 if (s->rsync_chunk_end != 0xFFFFFFFFUL)
1297 s->rsync_chunk_end -= wsize;
1298 s->block_start -= (long) wsize;
1299
1300 /* Slide the hash table (could be avoided with 32 bit values
1301 at the expense of memory usage). We slide even when level == 0
1302 to keep the hash table consistent if we switch back to level > 0
1303 later. (Using level 0 permanently is not an optimal usage of
1304 zlib, so we don't care about this pathological case.)
1305 */
1306 n = s->hash_size;
1307 p = &s->head[n];
1308 do {
1309 m = *--p;
1310 *p = (Pos)(m >= wsize ? m-wsize : NIL);
1311 } while (--n);
1312
1313 n = wsize;
1314 #ifndef FASTEST
1315 p = &s->prev[n];
1316 do {
1317 m = *--p;
1318 *p = (Pos)(m >= wsize ? m-wsize : NIL);
1319 /* If n is not on any hash chain, prev[n] is garbage but
1320 * its value will never be used.
1321 */
1322 } while (--n);
1323 #endif
1324 more += wsize;
1325 }
1326 if (s->strm->avail_in == 0) return;
1327
1328 /* If there was no sliding:
1329 * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
1330 * more == window_size - lookahead - strstart
1331 * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
1332 * => more >= window_size - 2*WSIZE + 2
1333 * In the BIG_MEM or MMAP case (not yet supported),
1334 * window_size == input_size + MIN_LOOKAHEAD &&
1335 * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
1336 * Otherwise, window_size == 2*WSIZE so more >= 2.
1337 * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
1338 */
1339 Assert(more >= 2, "more < 2");
1340
1341 n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
1342 s->lookahead += n;
1343
1344 /* Initialize the hash value now that we have some input: */
1345 if (s->lookahead >= MIN_MATCH) {
1346 s->ins_h = s->window[s->strstart];
1347 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1348 #if MIN_MATCH != 3
1349 Call UPDATE_HASH() MIN_MATCH-3 more times
1350 #endif
1351 }
1352 /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
1353 * but this is not important since only literal bytes will be emitted.
1354 */
1355
1356 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1357 }
1358
1359 local void rsync_roll(s, start, num)
1360 deflate_state *s;
1361 unsigned start;
1362 unsigned num;
1363 {
1364 unsigned i;
1365
1366 if (start < RSYNC_WIN) {
1367 /* before window fills. */
1368 for (i = start; i < RSYNC_WIN; i++) {
1369 if (i == start + num) return;
1370 s->rsync_sum += (ulg)s->window[i];
1371 }
1372 num -= (RSYNC_WIN - start);
1373 start = RSYNC_WIN;
1374 }
1375
1376 /* buffer after window full */
1377 for (i = start; i < start+num; i++) {
1378 /* New character in */
1379 s->rsync_sum += (ulg)s->window[i];
1380 /* Old character out */
1381 s->rsync_sum -= (ulg)s->window[i - RSYNC_WIN];
1382 if (s->rsync_chunk_end == 0xFFFFFFFFUL
1383 && RSYNC_SUM_MATCH(s->rsync_sum))
1384 s->rsync_chunk_end = i;
1385 }
1386 }
1387
1388 /* ===========================================================================
1389 * Set rsync_chunk_end if window sum matches magic value.
1390 */
1391 #define RSYNC_ROLL(s, start, num) \
1392 do { if ((s)->rsyncable) rsync_roll((s), (start), (num)); } while(0)
1393
1394 /* ===========================================================================
1395 * Flush the current block, with given end-of-file flag.
1396 * IN assertion: strstart is set to the end of the current match.
1397 */
1398 #define FLUSH_BLOCK_ONLY(s, eof, pad) { \
1399 _tr_flush_block(s, (s->block_start >= 0L ? \
1400 (charf *)&s->window[(unsigned)s->block_start] : \
1401 (charf *)Z_NULL), \
1402 (ulg)((long)s->strstart - s->block_start), \
1403 (pad), \
1404 (eof)); \
1405 s->block_start = s->strstart; \
1406 flush_pending(s->strm); \
1407 Tracev((stderr,"[FLUSH]")); \
1408 }
1409
1410 /* Same but force premature exit if necessary. */
1411 #define FLUSH_BLOCK(s, eof, pad) { \
1412 FLUSH_BLOCK_ONLY(s, eof, pad); \
1413 if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
1414 }
1415
1416 /* ===========================================================================
1417 * Copy without compression as much as possible from the input stream, return
1418 * the current block state.
1419 * This function does not insert new strings in the dictionary since
1420 * uncompressible data is probably not useful. This function is used
1421 * only for the level=0 compression option.
1422 * NOTE: this function should be optimized to avoid extra copying from
1423 * window to pending_buf.
1424 */
1425 local block_state deflate_stored(s, flush)
1426 deflate_state *s;
1427 int flush;
1428 {
1429 /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
1430 * to pending_buf_size, and each stored block has a 5 byte header:
1431 */
1432 ulg max_block_size = 0xffff;
1433 ulg max_start;
1434
1435 if (max_block_size > s->pending_buf_size - 5) {
1436 max_block_size = s->pending_buf_size - 5;
1437 }
1438
1439 /* Copy as much as possible from input to output: */
1440 for (;;) {
1441 /* Fill the window as much as possible: */
1442 if (s->lookahead <= 1) {
1443
1444 Assert(s->strstart < s->w_size+MAX_DIST(s) ||
1445 s->block_start >= (long)s->w_size, "slide too late");
1446
1447 fill_window(s);
1448 if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
1449
1450 if (s->lookahead == 0) break; /* flush the current block */
1451 }
1452 Assert(s->block_start >= 0L, "block gone");
1453
1454 s->strstart += s->lookahead;
1455 s->lookahead = 0;
1456
1457 /* Emit a stored block if pending_buf will be full: */
1458 max_start = s->block_start + max_block_size;
1459 if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
1460 /* strstart == 0 is possible when wraparound on 16-bit machine */
1461 s->lookahead = (uInt)(s->strstart - max_start);
1462 s->strstart = (uInt)max_start;
1463 FLUSH_BLOCK(s, 0, 0);
1464 }
1465 /* Flush if we may have to slide, otherwise block_start may become
1466 * negative and the data will be gone:
1467 */
1468 if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
1469 FLUSH_BLOCK(s, 0, 0);
1470 }
1471 }
1472 FLUSH_BLOCK(s, flush == Z_FINISH, 0);
1473 return flush == Z_FINISH ? finish_done : block_done;
1474 }
1475
1476 /* ===========================================================================
1477 * Compress as much as possible from the input stream, return the current
1478 * block state.
1479 * This function does not perform lazy evaluation of matches and inserts
1480 * new strings in the dictionary only for unmatched strings or for short
1481 * matches. It is used only for the fast compression options.
1482 */
1483 local block_state deflate_fast(s, flush)
1484 deflate_state *s;
1485 int flush;
1486 {
1487 IPos hash_head = NIL; /* head of the hash chain */
1488 int bflush = 1; /* set if current block must be flushed */
1489
1490 for (;;) {
1491 /* Make sure that we always have enough lookahead, except
1492 * at the end of the input file. We need MAX_MATCH bytes
1493 * for the next match, plus MIN_MATCH bytes to insert the
1494 * string following the next match.
1495 */
1496 if (s->lookahead < MIN_LOOKAHEAD) {
1497 fill_window(s);
1498 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1499 return need_more;
1500 }
1501 if (s->lookahead == 0) break; /* flush the current block */
1502 }
1503
1504 /* Insert the string window[strstart .. strstart+2] in the
1505 * dictionary, and set hash_head to the head of the hash chain:
1506 */
1507 if (s->lookahead >= MIN_MATCH) {
1508 INSERT_STRING(s, s->strstart, hash_head);
1509 }
1510
1511 /* Find the longest match, discarding those <= prev_length.
1512 * At this point we have always match_length < MIN_MATCH
1513 */
1514 if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
1515 /* To simplify the code, we prevent matches with the string
1516 * of window index 0 (in particular we have to avoid a match
1517 * of the string with itself at the start of the input file).
1518 */
1519 #ifdef FASTEST
1520 if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
1521 (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
1522 s->match_length = longest_match_fast (s, hash_head);
1523 }
1524 #else
1525 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
1526 s->match_length = longest_match (s, hash_head);
1527 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
1528 s->match_length = longest_match_fast (s, hash_head);
1529 }
1530 #endif
1531 /* longest_match() or longest_match_fast() sets match_start */
1532 }
1533 if (s->match_length >= MIN_MATCH) {
1534 check_match(s, s->strstart, s->match_start, s->match_length);
1535
1536 _tr_tally_dist(s, s->strstart - s->match_start,
1537 s->match_length - MIN_MATCH, bflush);
1538
1539 s->lookahead -= s->match_length;
1540
1541 RSYNC_ROLL(s, s->strstart, s->match_length);
1542 /* Insert new strings in the hash table only if the match length
1543 * is not too large. This saves time but degrades compression.
1544 */
1545 #ifndef FASTEST
1546 if (s->match_length <= s->max_insert_length &&
1547 s->lookahead >= MIN_MATCH) {
1548 s->match_length--; /* string at strstart already in table */
1549 do {
1550 s->strstart++;
1551 INSERT_STRING(s, s->strstart, hash_head);
1552 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
1553 * always MIN_MATCH bytes ahead.
1554 */
1555 } while (--s->match_length != 0);
1556 s->strstart++;
1557 } else
1558 #endif
1559 {
1560 s->strstart += s->match_length;
1561 s->match_length = 0;
1562 s->ins_h = s->window[s->strstart];
1563 UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
1564 #if MIN_MATCH != 3
1565 Call UPDATE_HASH() MIN_MATCH-3 more times
1566 #endif
1567 /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
1568 * matter since it will be recomputed at next deflate call.
1569 */
1570 }
1571 } else {
1572 /* No match, output a literal byte */
1573 Tracevv((stderr,"%c", s->window[s->strstart]));
1574 _tr_tally_lit (s, s->window[s->strstart], bflush);
1575 RSYNC_ROLL(s, s->strstart, 1);
1576 s->lookahead--;
1577 s->strstart++;
1578 }
1579 if (s->rsyncable && s->strstart > s->rsync_chunk_end) {
1580 s->rsync_chunk_end = 0xFFFFFFFFUL;
1581 bflush = 2;
1582 }
1583 if (bflush) FLUSH_BLOCK(s, 0, bflush-1);
1584 }
1585 FLUSH_BLOCK(s, flush == Z_FINISH, bflush-1);
1586 return flush == Z_FINISH ? finish_done : block_done;
1587 }
1588
1589 #ifndef FASTEST
1590 /* ===========================================================================
1591 * Same as above, but achieves better compression. We use a lazy
1592 * evaluation for matches: a match is finally adopted only if there is
1593 * no better match at the next window position.
1594 */
1595 local block_state deflate_slow(s, flush)
1596 deflate_state *s;
1597 int flush;
1598 {
1599 IPos hash_head = NIL; /* head of hash chain */
1600 int bflush = 1; /* set if current block must be flushed */
1601
1602 /* Process the input block. */
1603 for (;;) {
1604 /* Make sure that we always have enough lookahead, except
1605 * at the end of the input file. We need MAX_MATCH bytes
1606 * for the next match, plus MIN_MATCH bytes to insert the
1607 * string following the next match.
1608 */
1609 if (s->lookahead < MIN_LOOKAHEAD) {
1610 fill_window(s);
1611 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1612 return need_more;
1613 }
1614 if (s->lookahead == 0) break; /* flush the current block */
1615 }
1616
1617 /* Insert the string window[strstart .. strstart+2] in the
1618 * dictionary, and set hash_head to the head of the hash chain:
1619 */
1620 if (s->lookahead >= MIN_MATCH) {
1621 INSERT_STRING(s, s->strstart, hash_head);
1622 }
1623
1624 /* Find the longest match, discarding those <= prev_length.
1625 */
1626 s->prev_length = s->match_length, s->prev_match = s->match_start;
1627 s->match_length = MIN_MATCH-1;
1628
1629 if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
1630 s->strstart - hash_head <= MAX_DIST(s)) {
1631 /* To simplify the code, we prevent matches with the string
1632 * of window index 0 (in particular we have to avoid a match
1633 * of the string with itself at the start of the input file).
1634 */
1635 if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
1636 s->match_length = longest_match (s, hash_head);
1637 } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
1638 s->match_length = longest_match_fast (s, hash_head);
1639 }
1640 /* longest_match() or longest_match_fast() sets match_start */
1641
1642 if (s->match_length <= 5 && (s->strategy == Z_FILTERED
1643 #if TOO_FAR <= 32767
1644 || (s->match_length == MIN_MATCH &&
1645 s->strstart - s->match_start > TOO_FAR)
1646 #endif
1647 )) {
1648
1649 /* If prev_match is also MIN_MATCH, match_start is garbage
1650 * but we will ignore the current match anyway.
1651 */
1652 s->match_length = MIN_MATCH-1;
1653 }
1654 }
1655 /* If there was a match at the previous step and the current
1656 * match is not better, output the previous match:
1657 */
1658 if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
1659 uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
1660 /* Do not insert strings in hash table beyond this. */
1661
1662 check_match(s, s->strstart-1, s->prev_match, s->prev_length);
1663
1664 _tr_tally_dist(s, s->strstart -1 - s->prev_match,
1665 s->prev_length - MIN_MATCH, bflush);
1666
1667 /* Insert in hash table all strings up to the end of the match.
1668 * strstart-1 and strstart are already inserted. If there is not
1669 * enough lookahead, the last two strings are not inserted in
1670 * the hash table.
1671 */
1672 s->lookahead -= s->prev_length-1;
1673 s->prev_length -= 2;
1674 RSYNC_ROLL(s, s->strstart, s->prev_length+1);
1675 do {
1676 if (++s->strstart <= max_insert) {
1677 INSERT_STRING(s, s->strstart, hash_head);
1678 }
1679 } while (--s->prev_length != 0);
1680 s->match_available = 0;
1681 s->match_length = MIN_MATCH-1;
1682 s->strstart++;
1683
1684 if (s->rsyncable && s->strstart > s->rsync_chunk_end) {
1685 s->rsync_chunk_end = 0xFFFFFFFFUL;
1686 bflush = 2;
1687 }
1688 if (bflush) FLUSH_BLOCK(s, 0, bflush-1);
1689
1690 } else if (s->match_available) {
1691 /* If there was no match at the previous position, output a
1692 * single literal. If there was a match but the current match
1693 * is longer, truncate the previous match to a single literal.
1694 */
1695 Tracevv((stderr,"%c", s->window[s->strstart-1]));
1696 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1697 if (s->rsyncable && s->strstart > s->rsync_chunk_end) {
1698 s->rsync_chunk_end = 0xFFFFFFFFUL;
1699 bflush = 2;
1700 }
1701 if (bflush) {
1702 FLUSH_BLOCK_ONLY(s, 0, bflush-1);
1703 }
1704 RSYNC_ROLL(s, s->strstart, 1);
1705 s->strstart++;
1706 s->lookahead--;
1707 if (s->strm->avail_out == 0) return need_more;
1708 } else {
1709 /* There is no previous match to compare with, wait for
1710 * the next step to decide.
1711 */
1712 if (s->rsyncable && s->strstart > s->rsync_chunk_end) {
1713 /* Reset huffman tree */
1714 s->rsync_chunk_end = 0xFFFFFFFFUL;
1715 bflush = 2;
1716 FLUSH_BLOCK(s, 0, bflush-1);
1717 }
1718 s->match_available = 1;
1719 RSYNC_ROLL(s, s->strstart, 1);
1720 s->strstart++;
1721 s->lookahead--;
1722 }
1723 }
1724 Assert (flush != Z_NO_FLUSH, "no flush?");
1725 if (s->match_available) {
1726 Tracevv((stderr,"%c", s->window[s->strstart-1]));
1727 _tr_tally_lit(s, s->window[s->strstart-1], bflush);
1728 s->match_available = 0;
1729 }
1730 FLUSH_BLOCK(s, flush == Z_FINISH, bflush-1);
1731 return flush == Z_FINISH ? finish_done : block_done;
1732 }
1733 #endif /* FASTEST */
0 /* deflate.h -- internal compression state
1 * Copyright (C) 1995-2004 Jean-loup Gailly
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* @(#) $Id$ */
11
12 #ifndef DEFLATE_H
13 #define DEFLATE_H
14
15 #include "zutil.h"
16
17 /* define NO_GZIP when compiling if you want to disable gzip header and
18 trailer creation by deflate(). NO_GZIP would be used to avoid linking in
19 the crc code when it is not needed. For shared libraries, gzip encoding
20 should be left enabled. */
21 #ifndef NO_GZIP
22 # define GZIP
23 #endif
24
25 /* ===========================================================================
26 * Internal compression state.
27 */
28
29 #define LENGTH_CODES 29
30 /* number of length codes, not counting the special END_BLOCK code */
31
32 #define LITERALS 256
33 /* number of literal bytes 0..255 */
34
35 #define L_CODES (LITERALS+1+LENGTH_CODES)
36 /* number of Literal or Length codes, including the END_BLOCK code */
37
38 #define D_CODES 30
39 /* number of distance codes */
40
41 #define BL_CODES 19
42 /* number of codes used to transfer the bit lengths */
43
44 #define HEAP_SIZE (2*L_CODES+1)
45 /* maximum heap size */
46
47 #define MAX_BITS 15
48 /* All codes must not exceed MAX_BITS bits */
49
50 #define INIT_STATE 42
51 #define EXTRA_STATE 69
52 #define NAME_STATE 73
53 #define COMMENT_STATE 91
54 #define HCRC_STATE 103
55 #define BUSY_STATE 113
56 #define FINISH_STATE 666
57 /* Stream status */
58
59
60 /* Data structure describing a single value and its code string. */
61 typedef struct ct_data_s {
62 union {
63 ush freq; /* frequency count */
64 ush code; /* bit string */
65 } fc;
66 union {
67 ush dad; /* father node in Huffman tree */
68 ush len; /* length of bit string */
69 } dl;
70 } FAR ct_data;
71
72 #define Freq fc.freq
73 #define Code fc.code
74 #define Dad dl.dad
75 #define Len dl.len
76
77 typedef struct static_tree_desc_s static_tree_desc;
78
79 typedef struct tree_desc_s {
80 ct_data *dyn_tree; /* the dynamic tree */
81 int max_code; /* largest code with non zero frequency */
82 static_tree_desc *stat_desc; /* the corresponding static tree */
83 } FAR tree_desc;
84
85 typedef ush Pos;
86 typedef Pos FAR Posf;
87 typedef unsigned IPos;
88
89 /* A Pos is an index in the character window. We use short instead of int to
90 * save space in the various tables. IPos is used only for parameter passing.
91 */
92
93 typedef struct internal_state {
94 z_streamp strm; /* pointer back to this zlib stream */
95 int status; /* as the name implies */
96 Bytef *pending_buf; /* output still pending */
97 ulg pending_buf_size; /* size of pending_buf */
98 Bytef *pending_out; /* next pending byte to output to the stream */
99 int pending; /* nb of bytes in the pending buffer */
100 int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
101 gz_headerp gzhead; /* gzip header information to write */
102 int gzindex; /* where in extra, name, or comment */
103 Byte method; /* STORED (for zip only) or DEFLATED */
104 int last_flush; /* value of flush param for previous deflate call */
105
106 /* used by deflate.c: */
107
108 uInt w_size; /* LZ77 window size (32K by default) */
109 uInt w_bits; /* log2(w_size) (8..16) */
110 uInt w_mask; /* w_size - 1 */
111
112 Bytef *window;
113 /* Sliding window. Input bytes are read into the second half of the window,
114 * and move to the first half later to keep a dictionary of at least wSize
115 * bytes. With this organization, matches are limited to a distance of
116 * wSize-MAX_MATCH bytes, but this ensures that IO is always
117 * performed with a length multiple of the block size. Also, it limits
118 * the window size to 64K, which is quite useful on MSDOS.
119 * To do: use the user input buffer as sliding window.
120 */
121
122 ulg window_size;
123 /* Actual size of window: 2*wSize, except when the user input buffer
124 * is directly used as sliding window.
125 */
126
127 Posf *prev;
128 /* Link to older string with same hash index. To limit the size of this
129 * array to 64K, this link is maintained only for the last 32K strings.
130 * An index in this array is thus a window index modulo 32K.
131 */
132
133 Posf *head; /* Heads of the hash chains or NIL. */
134
135 uInt ins_h; /* hash index of string to be inserted */
136 uInt hash_size; /* number of elements in hash table */
137 uInt hash_bits; /* log2(hash_size) */
138 uInt hash_mask; /* hash_size-1 */
139
140 uInt hash_shift;
141 /* Number of bits by which ins_h must be shifted at each input
142 * step. It must be such that after MIN_MATCH steps, the oldest
143 * byte no longer takes part in the hash key, that is:
144 * hash_shift * MIN_MATCH >= hash_bits
145 */
146
147 long block_start;
148 /* Window position at the beginning of the current output block. Gets
149 * negative when the window is moved backwards.
150 */
151
152 uInt match_length; /* length of best match */
153 IPos prev_match; /* previous match */
154 int match_available; /* set if previous match exists */
155 uInt strstart; /* start of string to insert */
156 uInt match_start; /* start of matching string */
157 uInt lookahead; /* number of valid bytes ahead in window */
158
159 uInt prev_length;
160 /* Length of the best match at previous step. Matches not greater than this
161 * are discarded. This is used in the lazy match evaluation.
162 */
163
164 uInt max_chain_length;
165 /* To speed up deflation, hash chains are never searched beyond this
166 * length. A higher limit improves compression ratio but degrades the
167 * speed.
168 */
169
170 uInt max_lazy_match;
171 /* Attempt to find a better match only when the current match is strictly
172 * smaller than this value. This mechanism is used only for compression
173 * levels >= 4.
174 */
175 # define max_insert_length max_lazy_match
176 /* Insert new strings in the hash table only if the match length is not
177 * greater than this length. This saves time but degrades compression.
178 * max_insert_length is used only for compression levels <= 3.
179 */
180
181 int level; /* compression level (1..9) */
182 int strategy; /* favor or force Huffman coding*/
183 int rsyncable;
184
185 uInt good_match;
186 /* Use a faster search when the previous match is longer than this */
187
188 int nice_match; /* Stop searching when current match exceeds this */
189
190 /* used by trees.c: */
191 /* Didn't use ct_data typedef below to supress compiler warning */
192 struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
193 struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
194 struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
195
196 struct tree_desc_s l_desc; /* desc. for literal tree */
197 struct tree_desc_s d_desc; /* desc. for distance tree */
198 struct tree_desc_s bl_desc; /* desc. for bit length tree */
199
200 ush bl_count[MAX_BITS+1];
201 /* number of codes at each bit length for an optimal tree */
202
203 int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
204 int heap_len; /* number of elements in the heap */
205 int heap_max; /* element of largest frequency */
206 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
207 * The same heap array is used to build all trees.
208 */
209
210 uch depth[2*L_CODES+1];
211 /* Depth of each subtree used as tie breaker for trees of equal frequency
212 */
213
214 uchf *l_buf; /* buffer for literals or lengths */
215
216 uInt lit_bufsize;
217 /* Size of match buffer for literals/lengths. There are 4 reasons for
218 * limiting lit_bufsize to 64K:
219 * - frequencies can be kept in 16 bit counters
220 * - if compression is not successful for the first block, all input
221 * data is still in the window so we can still emit a stored block even
222 * when input comes from standard input. (This can also be done for
223 * all blocks if lit_bufsize is not greater than 32K.)
224 * - if compression is not successful for a file smaller than 64K, we can
225 * even emit a stored file instead of a stored block (saving 5 bytes).
226 * This is applicable only for zip (not gzip or zlib).
227 * - creating new Huffman trees less frequently may not provide fast
228 * adaptation to changes in the input data statistics. (Take for
229 * example a binary file with poorly compressible code followed by
230 * a highly compressible string table.) Smaller buffer sizes give
231 * fast adaptation but have of course the overhead of transmitting
232 * trees more frequently.
233 * - I can't count above 4
234 */
235
236 uInt last_lit; /* running index in l_buf */
237
238 ushf *d_buf;
239 /* Buffer for distances. To simplify the code, d_buf and l_buf have
240 * the same number of elements. To use different lengths, an extra flag
241 * array would be necessary.
242 */
243
244 ulg opt_len; /* bit length of current block with optimal trees */
245 ulg static_len; /* bit length of current block with static trees */
246 uInt matches; /* number of string matches in current block */
247 int last_eob_len; /* bit length of EOB code for last block */
248
249 #ifdef DEBUG
250 ulg compressed_len; /* total bit length of compressed file mod 2^32 */
251 ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
252 #endif
253
254 ush bi_buf;
255 /* Output buffer. bits are inserted starting at the bottom (least
256 * significant bits).
257 */
258 int bi_valid;
259 /* Number of valid bits in bi_buf. All bits above the last valid bit
260 * are always zero.
261 */
262
263 ulg rsync_sum; /* rolling sum of rsync window */
264 ulg rsync_chunk_end; /* next rsync sequence point */
265
266 } FAR deflate_state;
267
268 /* Output a byte on the stream.
269 * IN assertion: there is enough room in pending_buf.
270 */
271 #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
272
273
274 #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
275 /* Minimum amount of lookahead, except at the end of the input file.
276 * See deflate.c for comments about the MIN_MATCH+1.
277 */
278
279 #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
280 /* In order to simplify the code, particularly on 16 bit machines, match
281 * distances are limited to MAX_DIST instead of WSIZE.
282 */
283
284 /* in trees.c */
285 void _tr_init OF((deflate_state *s));
286 int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
287 void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
288 int pad, int eof));
289 void _tr_align OF((deflate_state *s));
290 void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
291 int eof));
292
293 #define d_code(dist) \
294 ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
295 /* Mapping from a distance to a distance code. dist is the distance - 1 and
296 * must not have side effects. _dist_code[256] and _dist_code[257] are never
297 * used.
298 */
299
300 #ifndef DEBUG
301 /* Inline versions of _tr_tally for speed: */
302
303 #if defined(GEN_TREES_H) || !defined(STDC)
304 extern uch _length_code[];
305 extern uch _dist_code[];
306 #else
307 extern const uch _length_code[];
308 extern const uch _dist_code[];
309 #endif
310
311 # define _tr_tally_lit(s, c, flush) \
312 { uch cc = (c); \
313 s->d_buf[s->last_lit] = 0; \
314 s->l_buf[s->last_lit++] = cc; \
315 s->dyn_ltree[cc].Freq++; \
316 flush = (s->last_lit == s->lit_bufsize-1); \
317 }
318 # define _tr_tally_dist(s, distance, length, flush) \
319 { uch len = (length); \
320 ush dist = (distance); \
321 s->d_buf[s->last_lit] = dist; \
322 s->l_buf[s->last_lit++] = len; \
323 dist--; \
324 s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
325 s->dyn_dtree[d_code(dist)].Freq++; \
326 flush = (s->last_lit == s->lit_bufsize-1); \
327 }
328 #else
329 # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
330 # define _tr_tally_dist(s, distance, length, flush) \
331 flush = _tr_tally(s, distance, length)
332 #endif
333
334 #endif /* DEFLATE_H */
0 /* example.c -- usage example of the zlib compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #include <stdio.h>
8 #include "zlib.h"
9
10 #ifdef STDC
11 # include <string.h>
12 # include <stdlib.h>
13 #endif
14
15 #if defined(VMS) || defined(RISCOS)
16 # define TESTFILE "foo-gz"
17 #else
18 # define TESTFILE "foo.gz"
19 #endif
20
21 #define CHECK_ERR(err, msg) { \
22 if (err != Z_OK) { \
23 fprintf(stderr, "%s error: %d\n", msg, err); \
24 exit(1); \
25 } \
26 }
27
28 const char hello[] = "hello, hello!";
29 /* "hello world" would be more standard, but the repeated "hello"
30 * stresses the compression code better, sorry...
31 */
32
33 const char dictionary[] = "hello";
34 uLong dictId; /* Adler32 value of the dictionary */
35
36 void test_compress OF((Byte *compr, uLong comprLen,
37 Byte *uncompr, uLong uncomprLen));
38 void test_gzio OF((const char *fname,
39 Byte *uncompr, uLong uncomprLen));
40 void test_deflate OF((Byte *compr, uLong comprLen));
41 void test_inflate OF((Byte *compr, uLong comprLen,
42 Byte *uncompr, uLong uncomprLen));
43 void test_large_deflate OF((Byte *compr, uLong comprLen,
44 Byte *uncompr, uLong uncomprLen));
45 void test_large_inflate OF((Byte *compr, uLong comprLen,
46 Byte *uncompr, uLong uncomprLen));
47 void test_flush OF((Byte *compr, uLong *comprLen));
48 void test_sync OF((Byte *compr, uLong comprLen,
49 Byte *uncompr, uLong uncomprLen));
50 void test_dict_deflate OF((Byte *compr, uLong comprLen));
51 void test_dict_inflate OF((Byte *compr, uLong comprLen,
52 Byte *uncompr, uLong uncomprLen));
53 int main OF((int argc, char *argv[]));
54
55 /* ===========================================================================
56 * Test compress() and uncompress()
57 */
58 void test_compress(compr, comprLen, uncompr, uncomprLen)
59 Byte *compr, *uncompr;
60 uLong comprLen, uncomprLen;
61 {
62 int err;
63 uLong len = (uLong)strlen(hello)+1;
64
65 err = compress(compr, &comprLen, (const Bytef*)hello, len);
66 CHECK_ERR(err, "compress");
67
68 strcpy((char*)uncompr, "garbage");
69
70 err = uncompress(uncompr, &uncomprLen, compr, comprLen);
71 CHECK_ERR(err, "uncompress");
72
73 if (strcmp((char*)uncompr, hello)) {
74 fprintf(stderr, "bad uncompress\n");
75 exit(1);
76 } else {
77 printf("uncompress(): %s\n", (char *)uncompr);
78 }
79 }
80
81 /* ===========================================================================
82 * Test read/write of .gz files
83 */
84 void test_gzio(fname, uncompr, uncomprLen)
85 const char *fname; /* compressed file name */
86 Byte *uncompr;
87 uLong uncomprLen;
88 {
89 #ifdef NO_GZCOMPRESS
90 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
91 #else
92 int err;
93 int len = (int)strlen(hello)+1;
94 gzFile file;
95 z_off_t pos;
96
97 file = gzopen(fname, "wb");
98 if (file == NULL) {
99 fprintf(stderr, "gzopen error\n");
100 exit(1);
101 }
102 gzputc(file, 'h');
103 if (gzputs(file, "ello") != 4) {
104 fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
105 exit(1);
106 }
107 if (gzprintf(file, ", %s!", "hello") != 8) {
108 fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
109 exit(1);
110 }
111 gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
112 gzclose(file);
113
114 file = gzopen(fname, "rb");
115 if (file == NULL) {
116 fprintf(stderr, "gzopen error\n");
117 exit(1);
118 }
119 strcpy((char*)uncompr, "garbage");
120
121 if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
122 fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
123 exit(1);
124 }
125 if (strcmp((char*)uncompr, hello)) {
126 fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
127 exit(1);
128 } else {
129 printf("gzread(): %s\n", (char*)uncompr);
130 }
131
132 pos = gzseek(file, -8L, SEEK_CUR);
133 if (pos != 6 || gztell(file) != pos) {
134 fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
135 (long)pos, (long)gztell(file));
136 exit(1);
137 }
138
139 if (gzgetc(file) != ' ') {
140 fprintf(stderr, "gzgetc error\n");
141 exit(1);
142 }
143
144 if (gzungetc(' ', file) != ' ') {
145 fprintf(stderr, "gzungetc error\n");
146 exit(1);
147 }
148
149 gzgets(file, (char*)uncompr, (int)uncomprLen);
150 if (strlen((char*)uncompr) != 7) { /* " hello!" */
151 fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
152 exit(1);
153 }
154 if (strcmp((char*)uncompr, hello + 6)) {
155 fprintf(stderr, "bad gzgets after gzseek\n");
156 exit(1);
157 } else {
158 printf("gzgets() after gzseek: %s\n", (char*)uncompr);
159 }
160
161 gzclose(file);
162 #endif
163 }
164
165 /* ===========================================================================
166 * Test deflate() with small buffers
167 */
168 void test_deflate(compr, comprLen)
169 Byte *compr;
170 uLong comprLen;
171 {
172 z_stream c_stream; /* compression stream */
173 int err;
174 uLong len = (uLong)strlen(hello)+1;
175
176 c_stream.zalloc = (alloc_func)0;
177 c_stream.zfree = (free_func)0;
178 c_stream.opaque = (voidpf)0;
179
180 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
181 CHECK_ERR(err, "deflateInit");
182
183 c_stream.next_in = (Bytef*)hello;
184 c_stream.next_out = compr;
185
186 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
187 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
188 err = deflate(&c_stream, Z_NO_FLUSH);
189 CHECK_ERR(err, "deflate");
190 }
191 /* Finish the stream, still forcing small buffers: */
192 for (;;) {
193 c_stream.avail_out = 1;
194 err = deflate(&c_stream, Z_FINISH);
195 if (err == Z_STREAM_END) break;
196 CHECK_ERR(err, "deflate");
197 }
198
199 err = deflateEnd(&c_stream);
200 CHECK_ERR(err, "deflateEnd");
201 }
202
203 /* ===========================================================================
204 * Test inflate() with small buffers
205 */
206 void test_inflate(compr, comprLen, uncompr, uncomprLen)
207 Byte *compr, *uncompr;
208 uLong comprLen, uncomprLen;
209 {
210 int err;
211 z_stream d_stream; /* decompression stream */
212
213 strcpy((char*)uncompr, "garbage");
214
215 d_stream.zalloc = (alloc_func)0;
216 d_stream.zfree = (free_func)0;
217 d_stream.opaque = (voidpf)0;
218
219 d_stream.next_in = compr;
220 d_stream.avail_in = 0;
221 d_stream.next_out = uncompr;
222
223 err = inflateInit(&d_stream);
224 CHECK_ERR(err, "inflateInit");
225
226 while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
227 d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
228 err = inflate(&d_stream, Z_NO_FLUSH);
229 if (err == Z_STREAM_END) break;
230 CHECK_ERR(err, "inflate");
231 }
232
233 err = inflateEnd(&d_stream);
234 CHECK_ERR(err, "inflateEnd");
235
236 if (strcmp((char*)uncompr, hello)) {
237 fprintf(stderr, "bad inflate\n");
238 exit(1);
239 } else {
240 printf("inflate(): %s\n", (char *)uncompr);
241 }
242 }
243
244 /* ===========================================================================
245 * Test deflate() with large buffers and dynamic change of compression level
246 */
247 void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
248 Byte *compr, *uncompr;
249 uLong comprLen, uncomprLen;
250 {
251 z_stream c_stream; /* compression stream */
252 int err;
253
254 c_stream.zalloc = (alloc_func)0;
255 c_stream.zfree = (free_func)0;
256 c_stream.opaque = (voidpf)0;
257
258 err = deflateInit(&c_stream, Z_BEST_SPEED);
259 CHECK_ERR(err, "deflateInit");
260
261 c_stream.next_out = compr;
262 c_stream.avail_out = (uInt)comprLen;
263
264 /* At this point, uncompr is still mostly zeroes, so it should compress
265 * very well:
266 */
267 c_stream.next_in = uncompr;
268 c_stream.avail_in = (uInt)uncomprLen;
269 err = deflate(&c_stream, Z_NO_FLUSH);
270 CHECK_ERR(err, "deflate");
271 if (c_stream.avail_in != 0) {
272 fprintf(stderr, "deflate not greedy\n");
273 exit(1);
274 }
275
276 /* Feed in already compressed data and switch to no compression: */
277 deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
278 c_stream.next_in = compr;
279 c_stream.avail_in = (uInt)comprLen/2;
280 err = deflate(&c_stream, Z_NO_FLUSH);
281 CHECK_ERR(err, "deflate");
282
283 /* Switch back to compressing mode: */
284 deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
285 c_stream.next_in = uncompr;
286 c_stream.avail_in = (uInt)uncomprLen;
287 err = deflate(&c_stream, Z_NO_FLUSH);
288 CHECK_ERR(err, "deflate");
289
290 err = deflate(&c_stream, Z_FINISH);
291 if (err != Z_STREAM_END) {
292 fprintf(stderr, "deflate should report Z_STREAM_END\n");
293 exit(1);
294 }
295 err = deflateEnd(&c_stream);
296 CHECK_ERR(err, "deflateEnd");
297 }
298
299 /* ===========================================================================
300 * Test inflate() with large buffers
301 */
302 void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
303 Byte *compr, *uncompr;
304 uLong comprLen, uncomprLen;
305 {
306 int err;
307 z_stream d_stream; /* decompression stream */
308
309 strcpy((char*)uncompr, "garbage");
310
311 d_stream.zalloc = (alloc_func)0;
312 d_stream.zfree = (free_func)0;
313 d_stream.opaque = (voidpf)0;
314
315 d_stream.next_in = compr;
316 d_stream.avail_in = (uInt)comprLen;
317
318 err = inflateInit(&d_stream);
319 CHECK_ERR(err, "inflateInit");
320
321 for (;;) {
322 d_stream.next_out = uncompr; /* discard the output */
323 d_stream.avail_out = (uInt)uncomprLen;
324 err = inflate(&d_stream, Z_NO_FLUSH);
325 if (err == Z_STREAM_END) break;
326 CHECK_ERR(err, "large inflate");
327 }
328
329 err = inflateEnd(&d_stream);
330 CHECK_ERR(err, "inflateEnd");
331
332 if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
333 fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
334 exit(1);
335 } else {
336 printf("large_inflate(): OK\n");
337 }
338 }
339
340 /* ===========================================================================
341 * Test deflate() with full flush
342 */
343 void test_flush(compr, comprLen)
344 Byte *compr;
345 uLong *comprLen;
346 {
347 z_stream c_stream; /* compression stream */
348 int err;
349 uInt len = (uInt)strlen(hello)+1;
350
351 c_stream.zalloc = (alloc_func)0;
352 c_stream.zfree = (free_func)0;
353 c_stream.opaque = (voidpf)0;
354
355 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
356 CHECK_ERR(err, "deflateInit");
357
358 c_stream.next_in = (Bytef*)hello;
359 c_stream.next_out = compr;
360 c_stream.avail_in = 3;
361 c_stream.avail_out = (uInt)*comprLen;
362 err = deflate(&c_stream, Z_FULL_FLUSH);
363 CHECK_ERR(err, "deflate");
364
365 compr[3]++; /* force an error in first compressed block */
366 c_stream.avail_in = len - 3;
367
368 err = deflate(&c_stream, Z_FINISH);
369 if (err != Z_STREAM_END) {
370 CHECK_ERR(err, "deflate");
371 }
372 err = deflateEnd(&c_stream);
373 CHECK_ERR(err, "deflateEnd");
374
375 *comprLen = c_stream.total_out;
376 }
377
378 /* ===========================================================================
379 * Test inflateSync()
380 */
381 void test_sync(compr, comprLen, uncompr, uncomprLen)
382 Byte *compr, *uncompr;
383 uLong comprLen, uncomprLen;
384 {
385 int err;
386 z_stream d_stream; /* decompression stream */
387
388 strcpy((char*)uncompr, "garbage");
389
390 d_stream.zalloc = (alloc_func)0;
391 d_stream.zfree = (free_func)0;
392 d_stream.opaque = (voidpf)0;
393
394 d_stream.next_in = compr;
395 d_stream.avail_in = 2; /* just read the zlib header */
396
397 err = inflateInit(&d_stream);
398 CHECK_ERR(err, "inflateInit");
399
400 d_stream.next_out = uncompr;
401 d_stream.avail_out = (uInt)uncomprLen;
402
403 inflate(&d_stream, Z_NO_FLUSH);
404 CHECK_ERR(err, "inflate");
405
406 d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
407 err = inflateSync(&d_stream); /* but skip the damaged part */
408 CHECK_ERR(err, "inflateSync");
409
410 err = inflate(&d_stream, Z_FINISH);
411 if (err != Z_DATA_ERROR) {
412 fprintf(stderr, "inflate should report DATA_ERROR\n");
413 /* Because of incorrect adler32 */
414 exit(1);
415 }
416 err = inflateEnd(&d_stream);
417 CHECK_ERR(err, "inflateEnd");
418
419 printf("after inflateSync(): hel%s\n", (char *)uncompr);
420 }
421
422 /* ===========================================================================
423 * Test deflate() with preset dictionary
424 */
425 void test_dict_deflate(compr, comprLen)
426 Byte *compr;
427 uLong comprLen;
428 {
429 z_stream c_stream; /* compression stream */
430 int err;
431
432 c_stream.zalloc = (alloc_func)0;
433 c_stream.zfree = (free_func)0;
434 c_stream.opaque = (voidpf)0;
435
436 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
437 CHECK_ERR(err, "deflateInit");
438
439 err = deflateSetDictionary(&c_stream,
440 (const Bytef*)dictionary, sizeof(dictionary));
441 CHECK_ERR(err, "deflateSetDictionary");
442
443 dictId = c_stream.adler;
444 c_stream.next_out = compr;
445 c_stream.avail_out = (uInt)comprLen;
446
447 c_stream.next_in = (Bytef*)hello;
448 c_stream.avail_in = (uInt)strlen(hello)+1;
449
450 err = deflate(&c_stream, Z_FINISH);
451 if (err != Z_STREAM_END) {
452 fprintf(stderr, "deflate should report Z_STREAM_END\n");
453 exit(1);
454 }
455 err = deflateEnd(&c_stream);
456 CHECK_ERR(err, "deflateEnd");
457 }
458
459 /* ===========================================================================
460 * Test inflate() with a preset dictionary
461 */
462 void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
463 Byte *compr, *uncompr;
464 uLong comprLen, uncomprLen;
465 {
466 int err;
467 z_stream d_stream; /* decompression stream */
468
469 strcpy((char*)uncompr, "garbage");
470
471 d_stream.zalloc = (alloc_func)0;
472 d_stream.zfree = (free_func)0;
473 d_stream.opaque = (voidpf)0;
474
475 d_stream.next_in = compr;
476 d_stream.avail_in = (uInt)comprLen;
477
478 err = inflateInit(&d_stream);
479 CHECK_ERR(err, "inflateInit");
480
481 d_stream.next_out = uncompr;
482 d_stream.avail_out = (uInt)uncomprLen;
483
484 for (;;) {
485 err = inflate(&d_stream, Z_NO_FLUSH);
486 if (err == Z_STREAM_END) break;
487 if (err == Z_NEED_DICT) {
488 if (d_stream.adler != dictId) {
489 fprintf(stderr, "unexpected dictionary");
490 exit(1);
491 }
492 err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
493 sizeof(dictionary));
494 }
495 CHECK_ERR(err, "inflate with dict");
496 }
497
498 err = inflateEnd(&d_stream);
499 CHECK_ERR(err, "inflateEnd");
500
501 if (strcmp((char*)uncompr, hello)) {
502 fprintf(stderr, "bad inflate with dict\n");
503 exit(1);
504 } else {
505 printf("inflate with dictionary: %s\n", (char *)uncompr);
506 }
507 }
508
509 /* ===========================================================================
510 * Usage: example [output.gz [input.gz]]
511 */
512
513 int main(argc, argv)
514 int argc;
515 char *argv[];
516 {
517 Byte *compr, *uncompr;
518 uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
519 uLong uncomprLen = comprLen;
520 static const char* myVersion = ZLIB_VERSION;
521
522 if (zlibVersion()[0] != myVersion[0]) {
523 fprintf(stderr, "incompatible zlib version\n");
524 exit(1);
525
526 } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
527 fprintf(stderr, "warning: different zlib version\n");
528 }
529
530 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
531 ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
532
533 compr = (Byte*)calloc((uInt)comprLen, 1);
534 uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
535 /* compr and uncompr are cleared to avoid reading uninitialized
536 * data and to ensure that uncompr compresses well.
537 */
538 if (compr == Z_NULL || uncompr == Z_NULL) {
539 printf("out of memory\n");
540 exit(1);
541 }
542 test_compress(compr, comprLen, uncompr, uncomprLen);
543
544 test_gzio((argc > 1 ? argv[1] : TESTFILE),
545 uncompr, uncomprLen);
546
547 test_deflate(compr, comprLen);
548 test_inflate(compr, comprLen, uncompr, uncomprLen);
549
550 test_large_deflate(compr, comprLen, uncompr, uncomprLen);
551 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
552
553 test_flush(compr, &comprLen);
554 test_sync(compr, comprLen, uncompr, uncomprLen);
555 comprLen = uncomprLen;
556
557 test_dict_deflate(compr, comprLen);
558 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
559
560 free(compr);
561 free(uncompr);
562
563 return 0;
564 }
0 This directory contains examples of the use of zlib.
1
2 fitblk.c
3 compress just enough input to nearly fill a requested output size
4 - zlib isn't designed to do this, but fitblk does it anyway
5
6 gzappend.c
7 append to a gzip file
8 - illustrates the use of the Z_BLOCK flush parameter for inflate()
9 - illustrates the use of deflatePrime() to start at any bit
10
11 gzjoin.c
12 join gzip files without recalculating the crc or recompressing
13 - illustrates the use of the Z_BLOCK flush parameter for inflate()
14 - illustrates the use of crc32_combine()
15
16 gzlog.c
17 gzlog.h
18 efficiently maintain a message log file in gzip format
19 - illustrates use of raw deflate and Z_SYNC_FLUSH
20 - illustrates use of gzip header extra field
21
22 zlib_how.html
23 painfully comprehensive description of zpipe.c (see below)
24 - describes in excruciating detail the use of deflate() and inflate()
25
26 zpipe.c
27 reads and writes zlib streams from stdin to stdout
28 - illustrates the proper use of deflate() and inflate()
0 /* fitblk.c: example of fitting compressed output to a specified size
1 Not copyrighted -- provided to the public domain
2 Version 1.1 25 November 2004 Mark Adler */
3
4 /* Version history:
5 1.0 24 Nov 2004 First version
6 1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
7 Use fixed-size, stack-allocated raw buffers
8 Simplify code moving compression to subroutines
9 Use assert() for internal errors
10 Add detailed description of approach
11 */
12
13 /* Approach to just fitting a requested compressed size:
14
15 fitblk performs three compression passes on a portion of the input
16 data in order to determine how much of that input will compress to
17 nearly the requested output block size. The first pass generates
18 enough deflate blocks to produce output to fill the requested
19 output size plus a specfied excess amount (see the EXCESS define
20 below). The last deflate block may go quite a bit past that, but
21 is discarded. The second pass decompresses and recompresses just
22 the compressed data that fit in the requested plus excess sized
23 buffer. The deflate process is terminated after that amount of
24 input, which is less than the amount consumed on the first pass.
25 The last deflate block of the result will be of a comparable size
26 to the final product, so that the header for that deflate block and
27 the compression ratio for that block will be about the same as in
28 the final product. The third compression pass decompresses the
29 result of the second step, but only the compressed data up to the
30 requested size minus an amount to allow the compressed stream to
31 complete (see the MARGIN define below). That will result in a
32 final compressed stream whose length is less than or equal to the
33 requested size. Assuming sufficient input and a requested size
34 greater than a few hundred bytes, the shortfall will typically be
35 less than ten bytes.
36
37 If the input is short enough that the first compression completes
38 before filling the requested output size, then that compressed
39 stream is return with no recompression.
40
41 EXCESS is chosen to be just greater than the shortfall seen in a
42 two pass approach similar to the above. That shortfall is due to
43 the last deflate block compressing more efficiently with a smaller
44 header on the second pass. EXCESS is set to be large enough so
45 that there is enough uncompressed data for the second pass to fill
46 out the requested size, and small enough so that the final deflate
47 block of the second pass will be close in size to the final deflate
48 block of the third and final pass. MARGIN is chosen to be just
49 large enough to assure that the final compression has enough room
50 to complete in all cases.
51 */
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <assert.h>
56 #include "zlib.h"
57
58 #define local static
59
60 /* print nastygram and leave */
61 local void quit(char *why)
62 {
63 fprintf(stderr, "fitblk abort: %s\n", why);
64 exit(1);
65 }
66
67 #define RAWLEN 4096 /* intermediate uncompressed buffer size */
68
69 /* compress from file to def until provided buffer is full or end of
70 input reached; return last deflate() return value, or Z_ERRNO if
71 there was read error on the file */
72 local int partcompress(FILE *in, z_streamp def)
73 {
74 int ret, flush;
75 char raw[RAWLEN];
76
77 flush = Z_NO_FLUSH;
78 do {
79 def->avail_in = fread(raw, 1, RAWLEN, in);
80 if (ferror(in))
81 return Z_ERRNO;
82 def->next_in = raw;
83 if (feof(in))
84 flush = Z_FINISH;
85 ret = deflate(def, flush);
86 assert(ret != Z_STREAM_ERROR);
87 } while (def->avail_out != 0 && flush == Z_NO_FLUSH);
88 return ret;
89 }
90
91 /* recompress from inf's input to def's output; the input for inf and
92 the output for def are set in those structures before calling;
93 return last deflate() return value, or Z_MEM_ERROR if inflate()
94 was not able to allocate enough memory when it needed to */
95 local int recompress(z_streamp inf, z_streamp def)
96 {
97 int ret, flush;
98 char raw[RAWLEN];
99
100 flush = Z_NO_FLUSH;
101 do {
102 /* decompress */
103 inf->avail_out = RAWLEN;
104 inf->next_out = raw;
105 ret = inflate(inf, Z_NO_FLUSH);
106 assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
107 ret != Z_NEED_DICT);
108 if (ret == Z_MEM_ERROR)
109 return ret;
110
111 /* compress what was decompresed until done or no room */
112 def->avail_in = RAWLEN - inf->avail_out;
113 def->next_in = raw;
114 if (inf->avail_out != 0)
115 flush = Z_FINISH;
116 ret = deflate(def, flush);
117 assert(ret != Z_STREAM_ERROR);
118 } while (ret != Z_STREAM_END && def->avail_out != 0);
119 return ret;
120 }
121
122 #define EXCESS 256 /* empirically determined stream overage */
123 #define MARGIN 8 /* amount to back off for completion */
124
125 /* compress from stdin to fixed-size block on stdout */
126 int main(int argc, char **argv)
127 {
128 int ret; /* return code */
129 unsigned size; /* requested fixed output block size */
130 unsigned have; /* bytes written by deflate() call */
131 char *blk; /* intermediate and final stream */
132 char *tmp; /* close to desired size stream */
133 z_stream def, inf; /* zlib deflate and inflate states */
134
135 /* get requested output size */
136 if (argc != 2)
137 quit("need one argument: size of output block");
138 ret = strtol(argv[1], argv + 1, 10);
139 if (argv[1][0] != 0)
140 quit("argument must be a number");
141 if (ret < 8) /* 8 is minimum zlib stream size */
142 quit("need positive size of 8 or greater");
143 size = (unsigned)ret;
144
145 /* allocate memory for buffers and compression engine */
146 blk = malloc(size + EXCESS);
147 def.zalloc = Z_NULL;
148 def.zfree = Z_NULL;
149 def.opaque = Z_NULL;
150 ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
151 if (ret != Z_OK || blk == NULL)
152 quit("out of memory");
153
154 /* compress from stdin until output full, or no more input */
155 def.avail_out = size + EXCESS;
156 def.next_out = blk;
157 ret = partcompress(stdin, &def);
158 if (ret == Z_ERRNO)
159 quit("error reading input");
160
161 /* if it all fit, then size was undersubscribed -- done! */
162 if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
163 /* write block to stdout */
164 have = size + EXCESS - def.avail_out;
165 ret = fwrite(blk, 1, have, stdout);
166 if (ret != have || ferror(stdout))
167 quit("error writing output");
168
169 /* clean up and print results to stderr */
170 ret = deflateEnd(&def);
171 assert(ret != Z_STREAM_ERROR);
172 free(blk);
173 fprintf(stderr,
174 "%u bytes unused out of %u requested (all input)\n",
175 size - have, size);
176 return 0;
177 }
178
179 /* it didn't all fit -- set up for recompression */
180 inf.zalloc = Z_NULL;
181 inf.zfree = Z_NULL;
182 inf.opaque = Z_NULL;
183 inf.avail_in = 0;
184 inf.next_in = Z_NULL;
185 ret = inflateInit(&inf);
186 tmp = malloc(size + EXCESS);
187 if (ret != Z_OK || tmp == NULL)
188 quit("out of memory");
189 ret = deflateReset(&def);
190 assert(ret != Z_STREAM_ERROR);
191
192 /* do first recompression close to the right amount */
193 inf.avail_in = size + EXCESS;
194 inf.next_in = blk;
195 def.avail_out = size + EXCESS;
196 def.next_out = tmp;
197 ret = recompress(&inf, &def);
198 if (ret == Z_MEM_ERROR)
199 quit("out of memory");
200
201 /* set up for next reocmpression */
202 ret = inflateReset(&inf);
203 assert(ret != Z_STREAM_ERROR);
204 ret = deflateReset(&def);
205 assert(ret != Z_STREAM_ERROR);
206
207 /* do second and final recompression (third compression) */
208 inf.avail_in = size - MARGIN; /* assure stream will complete */
209 inf.next_in = tmp;
210 def.avail_out = size;
211 def.next_out = blk;
212 ret = recompress(&inf, &def);
213 if (ret == Z_MEM_ERROR)
214 quit("out of memory");
215 assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
216
217 /* done -- write block to stdout */
218 have = size - def.avail_out;
219 ret = fwrite(blk, 1, have, stdout);
220 if (ret != have || ferror(stdout))
221 quit("error writing output");
222
223 /* clean up and print results to stderr */
224 free(tmp);
225 ret = inflateEnd(&inf);
226 assert(ret != Z_STREAM_ERROR);
227 ret = deflateEnd(&def);
228 assert(ret != Z_STREAM_ERROR);
229 free(blk);
230 fprintf(stderr,
231 "%u bytes unused out of %u requested (%lu input)\n",
232 size - have, size, def.total_in);
233 return 0;
234 }
0 /* gzappend -- command to append to a gzip file
1
2 Copyright (C) 2003 Mark Adler, all rights reserved
3 version 1.1, 4 Nov 2003
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the author be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21 Mark Adler madler@alumni.caltech.edu
22 */
23
24 /*
25 * Change history:
26 *
27 * 1.0 19 Oct 2003 - First version
28 * 1.1 4 Nov 2003 - Expand and clarify some comments and notes
29 * - Add version and copyright to help
30 * - Send help to stdout instead of stderr
31 * - Add some preemptive typecasts
32 * - Add L to constants in lseek() calls
33 * - Remove some debugging information in error messages
34 * - Use new data_type definition for zlib 1.2.1
35 * - Simplfy and unify file operations
36 * - Finish off gzip file in gztack()
37 * - Use deflatePrime() instead of adding empty blocks
38 * - Keep gzip file clean on appended file read errors
39 * - Use in-place rotate instead of auxiliary buffer
40 * (Why you ask? Because it was fun to write!)
41 */
42
43 /*
44 gzappend takes a gzip file and appends to it, compressing files from the
45 command line or data from stdin. The gzip file is written to directly, to
46 avoid copying that file, in case it's large. Note that this results in the
47 unfriendly behavior that if gzappend fails, the gzip file is corrupted.
48
49 This program was written to illustrate the use of the new Z_BLOCK option of
50 zlib 1.2.x's inflate() function. This option returns from inflate() at each
51 block boundary to facilitate locating and modifying the last block bit at
52 the start of the final deflate block. Also whether using Z_BLOCK or not,
53 another required feature of zlib 1.2.x is that inflate() now provides the
54 number of unusued bits in the last input byte used. gzappend will not work
55 with versions of zlib earlier than 1.2.1.
56
57 gzappend first decompresses the gzip file internally, discarding all but
58 the last 32K of uncompressed data, and noting the location of the last block
59 bit and the number of unused bits in the last byte of the compressed data.
60 The gzip trailer containing the CRC-32 and length of the uncompressed data
61 is verified. This trailer will be later overwritten.
62
63 Then the last block bit is cleared by seeking back in the file and rewriting
64 the byte that contains it. Seeking forward, the last byte of the compressed
65 data is saved along with the number of unused bits to initialize deflate.
66
67 A deflate process is initialized, using the last 32K of the uncompressed
68 data from the gzip file to initialize the dictionary. If the total
69 uncompressed data was less than 32K, then all of it is used to initialize
70 the dictionary. The deflate output bit buffer is also initialized with the
71 last bits from the original deflate stream. From here on, the data to
72 append is simply compressed using deflate, and written to the gzip file.
73 When that is complete, the new CRC-32 and uncompressed length are written
74 as the trailer of the gzip file.
75 */
76
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <string.h>
80 #include <fcntl.h>
81 #include <unistd.h>
82 #include "zlib.h"
83
84 #define local static
85 #define LGCHUNK 14
86 #define CHUNK (1U << LGCHUNK)
87 #define DSIZE 32768U
88
89 /* print an error message and terminate with extreme prejudice */
90 local void bye(char *msg1, char *msg2)
91 {
92 fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
93 exit(1);
94 }
95
96 /* return the greatest common divisor of a and b using Euclid's algorithm,
97 modified to be fast when one argument much greater than the other, and
98 coded to avoid unnecessary swapping */
99 local unsigned gcd(unsigned a, unsigned b)
100 {
101 unsigned c;
102
103 while (a && b)
104 if (a > b) {
105 c = b;
106 while (a - c >= c)
107 c <<= 1;
108 a -= c;
109 }
110 else {
111 c = a;
112 while (b - c >= c)
113 c <<= 1;
114 b -= c;
115 }
116 return a + b;
117 }
118
119 /* rotate list[0..len-1] left by rot positions, in place */
120 local void rotate(unsigned char *list, unsigned len, unsigned rot)
121 {
122 unsigned char tmp;
123 unsigned cycles;
124 unsigned char *start, *last, *to, *from;
125
126 /* normalize rot and handle degenerate cases */
127 if (len < 2) return;
128 if (rot >= len) rot %= len;
129 if (rot == 0) return;
130
131 /* pointer to last entry in list */
132 last = list + (len - 1);
133
134 /* do simple left shift by one */
135 if (rot == 1) {
136 tmp = *list;
137 memcpy(list, list + 1, len - 1);
138 *last = tmp;
139 return;
140 }
141
142 /* do simple right shift by one */
143 if (rot == len - 1) {
144 tmp = *last;
145 memmove(list + 1, list, len - 1);
146 *list = tmp;
147 return;
148 }
149
150 /* otherwise do rotate as a set of cycles in place */
151 cycles = gcd(len, rot); /* number of cycles */
152 do {
153 start = from = list + cycles; /* start index is arbitrary */
154 tmp = *from; /* save entry to be overwritten */
155 for (;;) {
156 to = from; /* next step in cycle */
157 from += rot; /* go right rot positions */
158 if (from > last) from -= len; /* (pointer better not wrap) */
159 if (from == start) break; /* all but one shifted */
160 *to = *from; /* shift left */
161 }
162 *to = tmp; /* complete the circle */
163 } while (--cycles);
164 }
165
166 /* structure for gzip file read operations */
167 typedef struct {
168 int fd; /* file descriptor */
169 int size; /* 1 << size is bytes in buf */
170 unsigned left; /* bytes available at next */
171 unsigned char *buf; /* buffer */
172 unsigned char *next; /* next byte in buffer */
173 char *name; /* file name for error messages */
174 } file;
175
176 /* reload buffer */
177 local int readin(file *in)
178 {
179 int len;
180
181 len = read(in->fd, in->buf, 1 << in->size);
182 if (len == -1) bye("error reading ", in->name);
183 in->left = (unsigned)len;
184 in->next = in->buf;
185 return len;
186 }
187
188 /* read from file in, exit if end-of-file */
189 local int readmore(file *in)
190 {
191 if (readin(in) == 0) bye("unexpected end of ", in->name);
192 return 0;
193 }
194
195 #define read1(in) (in->left == 0 ? readmore(in) : 0, \
196 in->left--, *(in->next)++)
197
198 /* skip over n bytes of in */
199 local void skip(file *in, unsigned n)
200 {
201 unsigned bypass;
202
203 if (n > in->left) {
204 n -= in->left;
205 bypass = n & ~((1U << in->size) - 1);
206 if (bypass) {
207 if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
208 bye("seeking ", in->name);
209 n -= bypass;
210 }
211 readmore(in);
212 if (n > in->left)
213 bye("unexpected end of ", in->name);
214 }
215 in->left -= n;
216 in->next += n;
217 }
218
219 /* read a four-byte unsigned integer, little-endian, from in */
220 unsigned long read4(file *in)
221 {
222 unsigned long val;
223
224 val = read1(in);
225 val += (unsigned)read1(in) << 8;
226 val += (unsigned long)read1(in) << 16;
227 val += (unsigned long)read1(in) << 24;
228 return val;
229 }
230
231 /* skip over gzip header */
232 local void gzheader(file *in)
233 {
234 int flags;
235 unsigned n;
236
237 if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
238 if (read1(in) != 8) bye("unknown compression method in", in->name);
239 flags = read1(in);
240 if (flags & 0xe0) bye("unknown header flags set in", in->name);
241 skip(in, 6);
242 if (flags & 4) {
243 n = read1(in);
244 n += (unsigned)(read1(in)) << 8;
245 skip(in, n);
246 }
247 if (flags & 8) while (read1(in) != 0) ;
248 if (flags & 16) while (read1(in) != 0) ;
249 if (flags & 2) skip(in, 2);
250 }
251
252 /* decompress gzip file "name", return strm with a deflate stream ready to
253 continue compression of the data in the gzip file, and return a file
254 descriptor pointing to where to write the compressed data -- the deflate
255 stream is initialized to compress using level "level" */
256 local int gzscan(char *name, z_stream *strm, int level)
257 {
258 int ret, lastbit, left, full;
259 unsigned have;
260 unsigned long crc, tot;
261 unsigned char *window;
262 off_t lastoff, end;
263 file gz;
264
265 /* open gzip file */
266 gz.name = name;
267 gz.fd = open(name, O_RDWR, 0);
268 if (gz.fd == -1) bye("cannot open ", name);
269 gz.buf = malloc(CHUNK);
270 if (gz.buf == NULL) bye("out of memory", "");
271 gz.size = LGCHUNK;
272 gz.left = 0;
273
274 /* skip gzip header */
275 gzheader(&gz);
276
277 /* prepare to decompress */
278 window = malloc(DSIZE);
279 if (window == NULL) bye("out of memory", "");
280 strm->zalloc = Z_NULL;
281 strm->zfree = Z_NULL;
282 strm->opaque = Z_NULL;
283 ret = inflateInit2(strm, -15);
284 if (ret != Z_OK) bye("out of memory", " or library mismatch");
285
286 /* decompress the deflate stream, saving append information */
287 lastbit = 0;
288 lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
289 left = 0;
290 strm->avail_in = gz.left;
291 strm->next_in = gz.next;
292 crc = crc32(0L, Z_NULL, 0);
293 have = full = 0;
294 do {
295 /* if needed, get more input */
296 if (strm->avail_in == 0) {
297 readmore(&gz);
298 strm->avail_in = gz.left;
299 strm->next_in = gz.next;
300 }
301
302 /* set up output to next available section of sliding window */
303 strm->avail_out = DSIZE - have;
304 strm->next_out = window + have;
305
306 /* inflate and check for errors */
307 ret = inflate(strm, Z_BLOCK);
308 if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
309 if (ret == Z_MEM_ERROR) bye("out of memory", "");
310 if (ret == Z_DATA_ERROR)
311 bye("invalid compressed data--format violated in", name);
312
313 /* update crc and sliding window pointer */
314 crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
315 if (strm->avail_out)
316 have = DSIZE - strm->avail_out;
317 else {
318 have = 0;
319 full = 1;
320 }
321
322 /* process end of block */
323 if (strm->data_type & 128) {
324 if (strm->data_type & 64)
325 left = strm->data_type & 0x1f;
326 else {
327 lastbit = strm->data_type & 0x1f;
328 lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
329 }
330 }
331 } while (ret != Z_STREAM_END);
332 inflateEnd(strm);
333 gz.left = strm->avail_in;
334 gz.next = strm->next_in;
335
336 /* save the location of the end of the compressed data */
337 end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
338
339 /* check gzip trailer and save total for deflate */
340 if (crc != read4(&gz))
341 bye("invalid compressed data--crc mismatch in ", name);
342 tot = strm->total_out;
343 if ((tot & 0xffffffffUL) != read4(&gz))
344 bye("invalid compressed data--length mismatch in", name);
345
346 /* if not at end of file, warn */
347 if (gz.left || readin(&gz))
348 fprintf(stderr,
349 "gzappend warning: junk at end of gzip file overwritten\n");
350
351 /* clear last block bit */
352 lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
353 if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
354 *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
355 lseek(gz.fd, -1L, SEEK_CUR);
356 if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
357
358 /* if window wrapped, build dictionary from window by rotating */
359 if (full) {
360 rotate(window, DSIZE, have);
361 have = DSIZE;
362 }
363
364 /* set up deflate stream with window, crc, total_in, and leftover bits */
365 ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
366 if (ret != Z_OK) bye("out of memory", "");
367 deflateSetDictionary(strm, window, have);
368 strm->adler = crc;
369 strm->total_in = tot;
370 if (left) {
371 lseek(gz.fd, --end, SEEK_SET);
372 if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
373 deflatePrime(strm, 8 - left, *gz.buf);
374 }
375 lseek(gz.fd, end, SEEK_SET);
376
377 /* clean up and return */
378 free(window);
379 free(gz.buf);
380 return gz.fd;
381 }
382
383 /* append file "name" to gzip file gd using deflate stream strm -- if last
384 is true, then finish off the deflate stream at the end */
385 local void gztack(char *name, int gd, z_stream *strm, int last)
386 {
387 int fd, len, ret;
388 unsigned left;
389 unsigned char *in, *out;
390
391 /* open file to compress and append */
392 fd = 0;
393 if (name != NULL) {
394 fd = open(name, O_RDONLY, 0);
395 if (fd == -1)
396 fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
397 name);
398 }
399
400 /* allocate buffers */
401 in = fd == -1 ? NULL : malloc(CHUNK);
402 out = malloc(CHUNK);
403 if (out == NULL) bye("out of memory", "");
404
405 /* compress input file and append to gzip file */
406 do {
407 /* get more input */
408 len = fd == -1 ? 0 : read(fd, in, CHUNK);
409 if (len == -1) {
410 fprintf(stderr,
411 "gzappend warning: error reading %s, skipping rest ...\n",
412 name);
413 len = 0;
414 }
415 strm->avail_in = (unsigned)len;
416 strm->next_in = in;
417 if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
418
419 /* compress and write all available output */
420 do {
421 strm->avail_out = CHUNK;
422 strm->next_out = out;
423 ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
424 left = CHUNK - strm->avail_out;
425 while (left) {
426 len = write(gd, out + CHUNK - strm->avail_out - left, left);
427 if (len == -1) bye("writing gzip file", "");
428 left -= (unsigned)len;
429 }
430 } while (strm->avail_out == 0 && ret != Z_STREAM_END);
431 } while (len != 0);
432
433 /* write trailer after last entry */
434 if (last) {
435 deflateEnd(strm);
436 out[0] = (unsigned char)(strm->adler);
437 out[1] = (unsigned char)(strm->adler >> 8);
438 out[2] = (unsigned char)(strm->adler >> 16);
439 out[3] = (unsigned char)(strm->adler >> 24);
440 out[4] = (unsigned char)(strm->total_in);
441 out[5] = (unsigned char)(strm->total_in >> 8);
442 out[6] = (unsigned char)(strm->total_in >> 16);
443 out[7] = (unsigned char)(strm->total_in >> 24);
444 len = 8;
445 do {
446 ret = write(gd, out + 8 - len, len);
447 if (ret == -1) bye("writing gzip file", "");
448 len -= ret;
449 } while (len);
450 close(gd);
451 }
452
453 /* clean up and return */
454 free(out);
455 if (in != NULL) free(in);
456 if (fd > 0) close(fd);
457 }
458
459 /* process the compression level option if present, scan the gzip file, and
460 append the specified files, or append the data from stdin if no other file
461 names are provided on the command line -- the gzip file must be writable
462 and seekable */
463 int main(int argc, char **argv)
464 {
465 int gd, level;
466 z_stream strm;
467
468 /* ignore command name */
469 argv++;
470
471 /* provide usage if no arguments */
472 if (*argv == NULL) {
473 printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n");
474 printf(
475 "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
476 return 0;
477 }
478
479 /* set compression level */
480 level = Z_DEFAULT_COMPRESSION;
481 if (argv[0][0] == '-') {
482 if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
483 bye("invalid compression level", "");
484 level = argv[0][1] - '0';
485 if (*++argv == NULL) bye("no gzip file name after options", "");
486 }
487
488 /* prepare to append to gzip file */
489 gd = gzscan(*argv++, &strm, level);
490
491 /* append files on command line, or from stdin if none */
492 if (*argv == NULL)
493 gztack(NULL, gd, &strm, 1);
494 else
495 do {
496 gztack(*argv, gd, &strm, argv[1] == NULL);
497 } while (*++argv != NULL);
498 return 0;
499 }
0 /* gzjoin -- command to join gzip files into one gzip file
1
2 Copyright (C) 2004 Mark Adler, all rights reserved
3 version 1.0, 11 Dec 2004
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the author be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21 Mark Adler madler@alumni.caltech.edu
22 */
23
24 /*
25 * Change history:
26 *
27 * 1.0 11 Dec 2004 - First version
28 */
29
30 /*
31 gzjoin takes one or more gzip files on the command line and writes out a
32 single gzip file that will uncompress to the concatenation of the
33 uncompressed data from the individual gzip files. gzjoin does this without
34 having to recompress any of the data and without having to calculate a new
35 crc32 for the concatenated uncompressed data. gzjoin does however have to
36 decompress all of the input data in order to find the bits in the compressed
37 data that need to be modified to concatenate the streams.
38
39 gzjoin does not do an integrity check on the input gzip files other than
40 checking the gzip header and decompressing the compressed data. They are
41 otherwise assumed to be complete and correct.
42
43 Each joint between gzip files removes at least 18 bytes of previous trailer
44 and subsequent header, and inserts an average of about three bytes to the
45 compressed data in order to connect the streams. The output gzip file
46 has a minimal ten-byte gzip header with no file name or modification time.
47
48 This program was written to illustrate the use of the Z_BLOCK option of
49 inflate() and the crc32_combine() function. gzjoin will not compile with
50 versions of zlib earlier than 1.2.3.
51 */
52
53 #include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
54 #include <stdlib.h> /* exit(), malloc(), free() */
55 #include <fcntl.h> /* open() */
56 #include <unistd.h> /* close(), read(), lseek() */
57 #include "zlib.h"
58 /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
59
60 #define local static
61
62 /* exit with an error (return a value to allow use in an expression) */
63 local int bail(char *why1, char *why2)
64 {
65 fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
66 exit(1);
67 return 0;
68 }
69
70 /* -- simple buffered file input with access to the buffer -- */
71
72 #define CHUNK 32768 /* must be a power of two and fit in unsigned */
73
74 /* bin buffered input file type */
75 typedef struct {
76 char *name; /* name of file for error messages */
77 int fd; /* file descriptor */
78 unsigned left; /* bytes remaining at next */
79 unsigned char *next; /* next byte to read */
80 unsigned char *buf; /* allocated buffer of length CHUNK */
81 } bin;
82
83 /* close a buffered file and free allocated memory */
84 local void bclose(bin *in)
85 {
86 if (in != NULL) {
87 if (in->fd != -1)
88 close(in->fd);
89 if (in->buf != NULL)
90 free(in->buf);
91 free(in);
92 }
93 }
94
95 /* open a buffered file for input, return a pointer to type bin, or NULL on
96 failure */
97 local bin *bopen(char *name)
98 {
99 bin *in;
100
101 in = malloc(sizeof(bin));
102 if (in == NULL)
103 return NULL;
104 in->buf = malloc(CHUNK);
105 in->fd = open(name, O_RDONLY, 0);
106 if (in->buf == NULL || in->fd == -1) {
107 bclose(in);
108 return NULL;
109 }
110 in->left = 0;
111 in->next = in->buf;
112 in->name = name;
113 return in;
114 }
115
116 /* load buffer from file, return -1 on read error, 0 or 1 on success, with
117 1 indicating that end-of-file was reached */
118 local int bload(bin *in)
119 {
120 ssize_t len;
121
122 if (in == NULL)
123 return -1;
124 if (in->left != 0)
125 return 0;
126 in->next = in->buf;
127 do {
128 len = read(in->fd, in->buf + in->left, CHUNK - in->left);
129 if (len < 0)
130 return -1;
131 in->left += (unsigned)len;
132 } while (len != 0 && in->left < CHUNK);
133 return len == 0 ? 1 : 0;
134 }
135
136 /* get a byte from the file, bail if end of file */
137 #define bget(in) (in->left ? 0 : bload(in), \
138 in->left ? (in->left--, *(in->next)++) : \
139 bail("unexpected end of file on ", in->name))
140
141 /* get a four-byte little-endian unsigned integer from file */
142 local unsigned long bget4(bin *in)
143 {
144 unsigned long val;
145
146 val = bget(in);
147 val += (unsigned long)(bget(in)) << 8;
148 val += (unsigned long)(bget(in)) << 16;
149 val += (unsigned long)(bget(in)) << 24;
150 return val;
151 }
152
153 /* skip bytes in file */
154 local void bskip(bin *in, unsigned skip)
155 {
156 /* check pointer */
157 if (in == NULL)
158 return;
159
160 /* easy case -- skip bytes in buffer */
161 if (skip <= in->left) {
162 in->left -= skip;
163 in->next += skip;
164 return;
165 }
166
167 /* skip what's in buffer, discard buffer contents */
168 skip -= in->left;
169 in->left = 0;
170
171 /* seek past multiples of CHUNK bytes */
172 if (skip > CHUNK) {
173 unsigned left;
174
175 left = skip & (CHUNK - 1);
176 if (left == 0) {
177 /* exact number of chunks: seek all the way minus one byte to check
178 for end-of-file with a read */
179 lseek(in->fd, skip - 1, SEEK_CUR);
180 if (read(in->fd, in->buf, 1) != 1)
181 bail("unexpected end of file on ", in->name);
182 return;
183 }
184
185 /* skip the integral chunks, update skip with remainder */
186 lseek(in->fd, skip - left, SEEK_CUR);
187 skip = left;
188 }
189
190 /* read more input and skip remainder */
191 bload(in);
192 if (skip > in->left)
193 bail("unexpected end of file on ", in->name);
194 in->left -= skip;
195 in->next += skip;
196 }
197
198 /* -- end of buffered input functions -- */
199
200 /* skip the gzip header from file in */
201 local void gzhead(bin *in)
202 {
203 int flags;
204
205 /* verify gzip magic header and compression method */
206 if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
207 bail(in->name, " is not a valid gzip file");
208
209 /* get and verify flags */
210 flags = bget(in);
211 if ((flags & 0xe0) != 0)
212 bail("unknown reserved bits set in ", in->name);
213
214 /* skip modification time, extra flags, and os */
215 bskip(in, 6);
216
217 /* skip extra field if present */
218 if (flags & 4) {
219 unsigned len;
220
221 len = bget(in);
222 len += (unsigned)(bget(in)) << 8;
223 bskip(in, len);
224 }
225
226 /* skip file name if present */
227 if (flags & 8)
228 while (bget(in) != 0)
229 ;
230
231 /* skip comment if present */
232 if (flags & 16)
233 while (bget(in) != 0)
234 ;
235
236 /* skip header crc if present */
237 if (flags & 2)
238 bskip(in, 2);
239 }
240
241 /* write a four-byte little-endian unsigned integer to out */
242 local void put4(unsigned long val, FILE *out)
243 {
244 putc(val & 0xff, out);
245 putc((val >> 8) & 0xff, out);
246 putc((val >> 16) & 0xff, out);
247 putc((val >> 24) & 0xff, out);
248 }
249
250 /* Load up zlib stream from buffered input, bail if end of file */
251 local void zpull(z_streamp strm, bin *in)
252 {
253 if (in->left == 0)
254 bload(in);
255 if (in->left == 0)
256 bail("unexpected end of file on ", in->name);
257 strm->avail_in = in->left;
258 strm->next_in = in->next;
259 }
260
261 /* Write header for gzip file to out and initialize trailer. */
262 local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
263 {
264 fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
265 *crc = crc32(0L, Z_NULL, 0);
266 *tot = 0;
267 }
268
269 /* Copy the compressed data from name, zeroing the last block bit of the last
270 block if clr is true, and adding empty blocks as needed to get to a byte
271 boundary. If clr is false, then the last block becomes the last block of
272 the output, and the gzip trailer is written. crc and tot maintains the
273 crc and length (modulo 2^32) of the output for the trailer. The resulting
274 gzip file is written to out. gzinit() must be called before the first call
275 of gzcopy() to write the gzip header and to initialize crc and tot. */
276 local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
277 FILE *out)
278 {
279 int ret; /* return value from zlib functions */
280 int pos; /* where the "last block" bit is in byte */
281 int last; /* true if processing the last block */
282 bin *in; /* buffered input file */
283 unsigned char *start; /* start of compressed data in buffer */
284 unsigned char *junk; /* buffer for uncompressed data -- discarded */
285 z_off_t len; /* length of uncompressed data (support > 4 GB) */
286 z_stream strm; /* zlib inflate stream */
287
288 /* open gzip file and skip header */
289 in = bopen(name);
290 if (in == NULL)
291 bail("could not open ", name);
292 gzhead(in);
293
294 /* allocate buffer for uncompressed data and initialize raw inflate
295 stream */
296 junk = malloc(CHUNK);
297 strm.zalloc = Z_NULL;
298 strm.zfree = Z_NULL;
299 strm.opaque = Z_NULL;
300 strm.avail_in = 0;
301 strm.next_in = Z_NULL;
302 ret = inflateInit2(&strm, -15);
303 if (junk == NULL || ret != Z_OK)
304 bail("out of memory", "");
305
306 /* inflate and copy compressed data, clear last-block bit if requested */
307 len = 0;
308 zpull(&strm, in);
309 start = strm.next_in;
310 last = start[0] & 1;
311 if (last && clr)
312 start[0] &= ~1;
313 strm.avail_out = 0;
314 for (;;) {
315 /* if input used and output done, write used input and get more */
316 if (strm.avail_in == 0 && strm.avail_out != 0) {
317 fwrite(start, 1, strm.next_in - start, out);
318 start = in->buf;
319 in->left = 0;
320 zpull(&strm, in);
321 }
322
323 /* decompress -- return early when end-of-block reached */
324 strm.avail_out = CHUNK;
325 strm.next_out = junk;
326 ret = inflate(&strm, Z_BLOCK);
327 switch (ret) {
328 case Z_MEM_ERROR:
329 bail("out of memory", "");
330 case Z_DATA_ERROR:
331 bail("invalid compressed data in ", in->name);
332 }
333
334 /* update length of uncompressed data */
335 len += CHUNK - strm.avail_out;
336
337 /* check for block boundary (only get this when block copied out) */
338 if (strm.data_type & 128) {
339 /* if that was the last block, then done */
340 if (last)
341 break;
342
343 /* number of unused bits in last byte */
344 pos = strm.data_type & 7;
345
346 /* find the next last-block bit */
347 if (pos != 0) {
348 /* next last-block bit is in last used byte */
349 pos = 0x100 >> pos;
350 last = strm.next_in[-1] & pos;
351 if (last && clr)
352 strm.next_in[-1] &= ~pos;
353 }
354 else {
355 /* next last-block bit is in next unused byte */
356 if (strm.avail_in == 0) {
357 /* don't have that byte yet -- get it */
358 fwrite(start, 1, strm.next_in - start, out);
359 start = in->buf;
360 in->left = 0;
361 zpull(&strm, in);
362 }
363 last = strm.next_in[0] & 1;
364 if (last && clr)
365 strm.next_in[0] &= ~1;
366 }
367 }
368 }
369
370 /* update buffer with unused input */
371 in->left = strm.avail_in;
372 in->next = strm.next_in;
373
374 /* copy used input, write empty blocks to get to byte boundary */
375 pos = strm.data_type & 7;
376 fwrite(start, 1, in->next - start - 1, out);
377 last = in->next[-1];
378 if (pos == 0 || !clr)
379 /* already at byte boundary, or last file: write last byte */
380 putc(last, out);
381 else {
382 /* append empty blocks to last byte */
383 last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
384 if (pos & 1) {
385 /* odd -- append an empty stored block */
386 putc(last, out);
387 if (pos == 1)
388 putc(0, out); /* two more bits in block header */
389 fwrite("\0\0\xff\xff", 1, 4, out);
390 }
391 else {
392 /* even -- append 1, 2, or 3 empty fixed blocks */
393 switch (pos) {
394 case 6:
395 putc(last | 8, out);
396 last = 0;
397 case 4:
398 putc(last | 0x20, out);
399 last = 0;
400 case 2:
401 putc(last | 0x80, out);
402 putc(0, out);
403 }
404 }
405 }
406
407 /* update crc and tot */
408 *crc = crc32_combine(*crc, bget4(in), len);
409 *tot += (unsigned long)len;
410
411 /* clean up */
412 inflateEnd(&strm);
413 free(junk);
414 bclose(in);
415
416 /* write trailer if this is the last gzip file */
417 if (!clr) {
418 put4(*crc, out);
419 put4(*tot, out);
420 }
421 }
422
423 /* join the gzip files on the command line, write result to stdout */
424 int main(int argc, char **argv)
425 {
426 unsigned long crc, tot; /* running crc and total uncompressed length */
427
428 /* skip command name */
429 argc--;
430 argv++;
431
432 /* show usage if no arguments */
433 if (argc == 0) {
434 fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
435 stderr);
436 return 0;
437 }
438
439 /* join gzip files on command line and write to stdout */
440 gzinit(&crc, &tot, stdout);
441 while (argc--)
442 gzcopy(*argv++, argc, &crc, &tot, stdout);
443
444 /* done */
445 return 0;
446 }
0 /*
1 * gzlog.c
2 * Copyright (C) 2004 Mark Adler
3 * For conditions of distribution and use, see copyright notice in gzlog.h
4 * version 1.0, 26 Nov 2004
5 *
6 */
7
8 #include <string.h> /* memcmp() */
9 #include <stdlib.h> /* malloc(), free(), NULL */
10 #include <sys/types.h> /* size_t, off_t */
11 #include <unistd.h> /* read(), close(), sleep(), ftruncate(), */
12 /* lseek() */
13 #include <fcntl.h> /* open() */
14 #include <sys/file.h> /* flock() */
15 #include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */
16
17 #include "gzlog.h" /* interface */
18 #define local static
19
20 /* log object structure */
21 typedef struct {
22 int id; /* object identifier */
23 int fd; /* log file descriptor */
24 off_t extra; /* offset of extra "ap" subfield */
25 off_t mark_off; /* offset of marked data */
26 off_t last_off; /* offset of last block */
27 unsigned long crc; /* uncompressed crc */
28 unsigned long len; /* uncompressed length (modulo 2^32) */
29 unsigned stored; /* length of current stored block */
30 } gz_log;
31
32 #define GZLOGID 19334 /* gz_log object identifier */
33
34 #define LOCK_RETRY 1 /* retry lock once a second */
35 #define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */
36
37 /* acquire a lock on a file */
38 local int lock(int fd)
39 {
40 int patience;
41
42 /* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */
43 patience = LOCK_PATIENCE;
44 do {
45 if (flock(fd, LOCK_EX + LOCK_NB) == 0)
46 return 0;
47 (void)sleep(LOCK_RETRY);
48 patience -= LOCK_RETRY;
49 } while (patience > 0);
50
51 /* we've run out of patience -- give up */
52 return -1;
53 }
54
55 /* release lock */
56 local void unlock(int fd)
57 {
58 (void)flock(fd, LOCK_UN);
59 }
60
61 /* release a log object */
62 local void log_clean(gz_log *log)
63 {
64 unlock(log->fd);
65 (void)close(log->fd);
66 free(log);
67 }
68
69 /* read an unsigned long from a byte buffer little-endian */
70 local unsigned long make_ulg(unsigned char *buf)
71 {
72 int n;
73 unsigned long val;
74
75 val = (unsigned long)(*buf++);
76 for (n = 8; n < 32; n += 8)
77 val += (unsigned long)(*buf++) << n;
78 return val;
79 }
80
81 /* read an off_t from a byte buffer little-endian */
82 local off_t make_off(unsigned char *buf)
83 {
84 int n;
85 off_t val;
86
87 val = (off_t)(*buf++);
88 for (n = 8; n < 64; n += 8)
89 val += (off_t)(*buf++) << n;
90 return val;
91 }
92
93 /* write an unsigned long little-endian to byte buffer */
94 local void dice_ulg(unsigned long val, unsigned char *buf)
95 {
96 int n;
97
98 for (n = 0; n < 4; n++) {
99 *buf++ = val & 0xff;
100 val >>= 8;
101 }
102 }
103
104 /* write an off_t little-endian to byte buffer */
105 local void dice_off(off_t val, unsigned char *buf)
106 {
107 int n;
108
109 for (n = 0; n < 8; n++) {
110 *buf++ = val & 0xff;
111 val >>= 8;
112 }
113 }
114
115 /* initial, empty gzip file for appending */
116 local char empty_gz[] = {
117 0x1f, 0x8b, /* magic gzip id */
118 8, /* compression method is deflate */
119 4, /* there is an extra field */
120 0, 0, 0, 0, /* no modification time provided */
121 0, 0xff, /* no extra flags, no OS */
122 20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */
123 32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */
124 32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */
125 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
126 0, 0, 0, 0, /* crc */
127 0, 0, 0, 0 /* uncompressed length */
128 };
129
130 /* initialize a log object with locking */
131 void *gzlog_open(char *path)
132 {
133 unsigned xlen;
134 unsigned char temp[20];
135 unsigned sub_len;
136 int good;
137 gz_log *log;
138
139 /* allocate log structure */
140 log = malloc(sizeof(gz_log));
141 if (log == NULL)
142 return NULL;
143 log->id = GZLOGID;
144
145 /* open file, creating it if necessary, and locking it */
146 log->fd = open(path, O_RDWR | O_CREAT, 0600);
147 if (log->fd < 0) {
148 free(log);
149 return NULL;
150 }
151 if (lock(log->fd)) {
152 close(log->fd);
153 free(log);
154 return NULL;
155 }
156
157 /* if file is empty, write new gzip stream */
158 if (lseek(log->fd, 0, SEEK_END) == 0) {
159 if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) {
160 log_clean(log);
161 return NULL;
162 }
163 }
164
165 /* check gzip header */
166 (void)lseek(log->fd, 0, SEEK_SET);
167 if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f ||
168 temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) {
169 log_clean(log);
170 return NULL;
171 }
172
173 /* process extra field to find "ap" sub-field */
174 xlen = temp[10] + (temp[11] << 8);
175 good = 0;
176 while (xlen) {
177 if (xlen < 4 || read(log->fd, temp, 4) != 4)
178 break;
179 sub_len = temp[2];
180 sub_len += temp[3] << 8;
181 xlen -= 4;
182 if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) {
183 good = 1;
184 break;
185 }
186 if (xlen < sub_len)
187 break;
188 (void)lseek(log->fd, sub_len, SEEK_CUR);
189 xlen -= sub_len;
190 }
191 if (!good) {
192 log_clean(log);
193 return NULL;
194 }
195
196 /* read in "ap" sub-field */
197 log->extra = lseek(log->fd, 0, SEEK_CUR);
198 if (read(log->fd, temp, 16) != 16) {
199 log_clean(log);
200 return NULL;
201 }
202 log->mark_off = make_off(temp);
203 log->last_off = make_off(temp + 8);
204
205 /* get crc, length of gzip file */
206 (void)lseek(log->fd, log->last_off, SEEK_SET);
207 if (read(log->fd, temp, 13) != 13 ||
208 memcmp(temp, "\001\000\000\377\377", 5) != 0) {
209 log_clean(log);
210 return NULL;
211 }
212 log->crc = make_ulg(temp + 5);
213 log->len = make_ulg(temp + 9);
214
215 /* set up to write over empty last block */
216 (void)lseek(log->fd, log->last_off + 5, SEEK_SET);
217 log->stored = 0;
218 return (void *)log;
219 }
220
221 /* maximum amount to put in a stored block before starting a new one */
222 #define MAX_BLOCK 16384
223
224 /* write a block to a log object */
225 int gzlog_write(void *obj, char *data, size_t len)
226 {
227 size_t some;
228 unsigned char temp[5];
229 gz_log *log;
230
231 /* check object */
232 log = (gz_log *)obj;
233 if (log == NULL || log->id != GZLOGID)
234 return 1;
235
236 /* write stored blocks until all of the input is written */
237 do {
238 some = MAX_BLOCK - log->stored;
239 if (some > len)
240 some = len;
241 if (write(log->fd, data, some) != some)
242 return 1;
243 log->crc = crc32(log->crc, data, some);
244 log->len += some;
245 len -= some;
246 data += some;
247 log->stored += some;
248
249 /* if the stored block is full, end it and start another */
250 if (log->stored == MAX_BLOCK) {
251 (void)lseek(log->fd, log->last_off, SEEK_SET);
252 temp[0] = 0;
253 dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
254 temp + 1);
255 if (write(log->fd, temp, 5) != 5)
256 return 1;
257 log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
258 (void)lseek(log->fd, 5, SEEK_CUR);
259 log->stored = 0;
260 }
261 } while (len);
262 return 0;
263 }
264
265 /* recompress the remaining stored deflate data in place */
266 local int recomp(gz_log *log)
267 {
268 z_stream strm;
269 size_t len, max;
270 unsigned char *in;
271 unsigned char *out;
272 unsigned char temp[16];
273
274 /* allocate space and read it all in (it's around 1 MB) */
275 len = log->last_off - log->mark_off;
276 max = len + (len >> 12) + (len >> 14) + 11;
277 out = malloc(max);
278 if (out == NULL)
279 return 1;
280 in = malloc(len);
281 if (in == NULL) {
282 free(out);
283 return 1;
284 }
285 (void)lseek(log->fd, log->mark_off, SEEK_SET);
286 if (read(log->fd, in, len) != len) {
287 free(in);
288 free(out);
289 return 1;
290 }
291
292 /* recompress in memory, decoding stored data as we go */
293 /* note: this assumes that unsigned is four bytes or more */
294 /* consider not making that assumption */
295 strm.zalloc = Z_NULL;
296 strm.zfree = Z_NULL;
297 strm.opaque = Z_NULL;
298 if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8,
299 Z_DEFAULT_STRATEGY) != Z_OK) {
300 free(in);
301 free(out);
302 return 1;
303 }
304 strm.next_in = in;
305 strm.avail_out = max;
306 strm.next_out = out;
307 while (len >= 5) {
308 if (strm.next_in[0] != 0)
309 break;
310 strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8);
311 strm.next_in += 5;
312 len -= 5;
313 if (strm.avail_in != 0) {
314 if (len < strm.avail_in)
315 break;
316 len -= strm.avail_in;
317 (void)deflate(&strm, Z_NO_FLUSH);
318 if (strm.avail_in != 0 || strm.avail_out == 0)
319 break;
320 }
321 }
322 (void)deflate(&strm, Z_SYNC_FLUSH);
323 (void)deflateEnd(&strm);
324 free(in);
325 if (len != 0 || strm.avail_out == 0) {
326 free(out);
327 return 1;
328 }
329
330 /* overwrite stored data with compressed data */
331 (void)lseek(log->fd, log->mark_off, SEEK_SET);
332 len = max - strm.avail_out;
333 if (write(log->fd, out, len) != len) {
334 free(out);
335 return 1;
336 }
337 free(out);
338
339 /* write last empty block, crc, and length */
340 log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR);
341 temp[0] = 1;
342 dice_ulg(0xffffL << 16, temp + 1);
343 dice_ulg(log->crc, temp + 5);
344 dice_ulg(log->len, temp + 9);
345 if (write(log->fd, temp, 13) != 13)
346 return 1;
347
348 /* truncate file to discard remaining stored data and old trailer */
349 ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR));
350
351 /* update extra field to point to new last empty block */
352 (void)lseek(log->fd, log->extra, SEEK_SET);
353 dice_off(log->mark_off, temp);
354 dice_off(log->last_off, temp + 8);
355 if (write(log->fd, temp, 16) != 16)
356 return 1;
357 return 0;
358 }
359
360 /* maximum accumulation of stored blocks before compressing */
361 #define MAX_STORED 1048576
362
363 /* close log object */
364 int gzlog_close(void *obj)
365 {
366 unsigned char temp[8];
367 gz_log *log;
368
369 /* check object */
370 log = (gz_log *)obj;
371 if (log == NULL || log->id != GZLOGID)
372 return 1;
373
374 /* go to start of most recent block being written */
375 (void)lseek(log->fd, log->last_off, SEEK_SET);
376
377 /* if some stuff was put there, update block */
378 if (log->stored) {
379 temp[0] = 0;
380 dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
381 temp + 1);
382 if (write(log->fd, temp, 5) != 5)
383 return 1;
384 log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
385 }
386
387 /* write last block (empty) */
388 if (write(log->fd, "\001\000\000\377\377", 5) != 5)
389 return 1;
390
391 /* write updated crc and uncompressed length */
392 dice_ulg(log->crc, temp);
393 dice_ulg(log->len, temp + 4);
394 if (write(log->fd, temp, 8) != 8)
395 return 1;
396
397 /* put offset of that last block in gzip extra block */
398 (void)lseek(log->fd, log->extra + 8, SEEK_SET);
399 dice_off(log->last_off, temp);
400 if (write(log->fd, temp, 8) != 8)
401 return 1;
402
403 /* if more than 1 MB stored, then time to compress it */
404 if (log->last_off - log->mark_off > MAX_STORED) {
405 if (recomp(log))
406 return 1;
407 }
408
409 /* unlock and close file */
410 log_clean(log);
411 return 0;
412 }
0 /* gzlog.h
1 Copyright (C) 2004 Mark Adler, all rights reserved
2 version 1.0, 26 Nov 2004
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the author be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Mark Adler madler@alumni.caltech.edu
21 */
22
23 /*
24 The gzlog object allows writing short messages to a gzipped log file,
25 opening the log file locked for small bursts, and then closing it. The log
26 object works by appending stored data to the gzip file until 1 MB has been
27 accumulated. At that time, the stored data is compressed, and replaces the
28 uncompressed data in the file. The log file is truncated to its new size at
29 that time. After closing, the log file is always valid gzip file that can
30 decompressed to recover what was written.
31
32 A gzip header "extra" field contains two file offsets for appending. The
33 first points to just after the last compressed data. The second points to
34 the last stored block in the deflate stream, which is empty. All of the
35 data between those pointers is uncompressed.
36 */
37
38 /* Open a gzlog object, creating the log file if it does not exist. Return
39 NULL on error. Note that gzlog_open() could take a long time to return if
40 there is difficulty in locking the file. */
41 void *gzlog_open(char *path);
42
43 /* Write to a gzlog object. Return non-zero on error. This function will
44 simply write data to the file uncompressed. Compression of the data
45 will not occur until gzlog_close() is called. It is expected that
46 gzlog_write() is used for a short message, and then gzlog_close() is
47 called. If a large amount of data is to be written, then the application
48 should write no more than 1 MB at a time with gzlog_write() before
49 calling gzlog_close() and then gzlog_open() again. */
50 int gzlog_write(void *log, char *data, size_t len);
51
52 /* Close a gzlog object. Return non-zero on error. The log file is locked
53 until this function is called. This function will compress stored data
54 at the end of the gzip file if at least 1 MB has been accumulated. Note
55 that the file will not be a valid gzip file until this function completes.
56 */
57 int gzlog_close(void *log);
0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
1 "http://www.w3.org/TR/REC-html40/loose.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
5 <title>zlib Usage Example</title>
6 <!-- Copyright (c) 2004 Mark Adler. -->
7 </head>
8 <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
9 <h2 align="center"> zlib Usage Example </h2>
10 We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
11 Users wonder when they should provide more input, when they should use more output,
12 what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
13 so on. So for those who have read <tt>zlib.h</tt> (a few times), and
14 would like further edification, below is an annotated example in C of simple routines to compress and decompress
15 from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively. The
16 annotations are interspersed between lines of the code. So please read between the lines.
17 We hope this helps explain some of the intricacies of <em>zlib</em>.
18 <p>
19 Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
20 <pre><b>
21 /* zpipe.c: example of proper use of zlib's inflate() and deflate()
22 Not copyrighted -- provided to the public domain
23 Version 1.2 9 November 2004 Mark Adler */
24
25 /* Version history:
26 1.0 30 Oct 2004 First version
27 1.1 8 Nov 2004 Add void casting for unused return values
28 Use switch statement for inflate() return values
29 1.2 9 Nov 2004 Add assertions to document zlib guarantees
30 */
31 </b></pre><!-- -->
32 We now include the header files for the required definitions. From
33 <tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
34 <tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
35 <tt>fputs()</tt> for error messages. From <tt>string.h</tt> we use
36 <tt>strcmp()</tt> for command line argument processing.
37 From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
38 From <tt>zlib.h</tt>
39 we use the basic compression functions <tt>deflateInit()</tt>,
40 <tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
41 functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
42 <tt>inflateEnd()</tt>.
43 <pre><b>
44 #include &lt;stdio.h&gt;
45 #include &lt;string.h&gt;
46 #include &lt;assert.h&gt;
47 #include "zlib.h"
48 </b></pre><!-- -->
49 <tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
50 from the <em>zlib</em> routines. Larger buffer sizes would be more efficient,
51 especially for <tt>inflate()</tt>. If the memory is available, buffers sizes
52 on the order of 128K or 256K bytes should be used.
53 <pre><b>
54 #define CHUNK 16384
55 </b></pre><!-- -->
56 The <tt>def()</tt> routine compresses data from an input file to an output file. The output data
57 will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
58 formats. The <em>zlib</em> format has a very small header of only two bytes to identify it as
59 a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
60 check value to verify the integrity of the uncompressed data after decoding.
61 <pre><b>
62 /* Compress from file source to file dest until EOF on source.
63 def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
64 allocated for processing, Z_STREAM_ERROR if an invalid compression
65 level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
66 version of the library linked do not match, or Z_ERRNO if there is
67 an error reading or writing the files. */
68 int def(FILE *source, FILE *dest, int level)
69 {
70 </b></pre>
71 Here are the local variables for <tt>def()</tt>. <tt>ret</tt> will be used for <em>zlib</em>
72 return codes. <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
73 which is either no flushing, or flush to completion after the end of the input file is reached.
74 <tt>have</tt> is the amount of data returned from <tt>deflate()</tt>. The <tt>strm</tt> structure
75 is used to pass information to and from the <em>zlib</em> routines, and to maintain the
76 <tt>deflate()</tt> state. <tt>in</tt> and <tt>out</tt> are the input and output buffers for
77 <tt>deflate()</tt>.
78 <pre><b>
79 int ret, flush;
80 unsigned have;
81 z_stream strm;
82 char in[CHUNK];
83 char out[CHUNK];
84 </b></pre><!-- -->
85 The first thing we do is to initialize the <em>zlib</em> state for compression using
86 <tt>deflateInit()</tt>. This must be done before the first use of <tt>deflate()</tt>.
87 The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
88 structure must be initialized before calling <tt>deflateInit()</tt>. Here they are
89 set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
90 the default memory allocation routines. An application may also choose to provide
91 custom memory allocation routines here. <tt>deflateInit()</tt> will allocate on the
92 order of 256K bytes for the internal state.
93 (See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
94 <p>
95 <tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
96 the compression level, which is an integer in the range of -1 to 9. Lower compression
97 levels result in faster execution, but less compression. Higher levels result in
98 greater compression, but slower execution. The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
99 equal to -1,
100 provides a good compromise between compression and speed and is equivalent to level 6.
101 Level 0 actually does no compression at all, and in fact expands the data slightly to produce
102 the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
103 More advanced applications of <em>zlib</em>
104 may use <tt>deflateInit2()</tt> here instead. Such an application may want to reduce how
105 much memory will be used, at some price in compression. Or it may need to request a
106 <em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
107 encoding with no header or trailer at all.
108 <p>
109 We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
110 <tt>Z_OK</tt> to make sure that it was able to
111 allocate memory for the internal state, and that the provided arguments were valid.
112 <tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
113 file came from matches the version of <em>zlib</em> actually linked with the program. This
114 is especially important for environments in which <em>zlib</em> is a shared library.
115 <p>
116 Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
117 operate in parallel. The state information maintained in the structure allows the <em>zlib</em>
118 routines to be reentrant.
119 <pre><b>
120 /* allocate deflate state */
121 strm.zalloc = Z_NULL;
122 strm.zfree = Z_NULL;
123 strm.opaque = Z_NULL;
124 ret = deflateInit(&amp;strm, level);
125 if (ret != Z_OK)
126 return ret;
127 </b></pre><!-- -->
128 With the pleasantries out of the way, now we can get down to business. The outer <tt>do</tt>-loop
129 reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
130 This loop contains the only call of <tt>deflate()</tt>. So we must make sure that all of the
131 input data has been processed and that all of the output data has been generated and consumed
132 before we fall out of the loop at the bottom.
133 <pre><b>
134 /* compress until end of file */
135 do {
136 </b></pre>
137 We start off by reading data from the input file. The number of bytes read is put directly
138 into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>. We also
139 check to see if end-of-file on the input has been reached. If we are at the end of file, then <tt>flush</tt> is set to the
140 <em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
141 indicate that this is the last chunk of input data to compress. We need to use <tt>feof()</tt>
142 to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read. The
143 reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
144 the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
145 up the compressed stream. If we are not yet at the end of the input, then the <em>zlib</em>
146 constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
147 in the middle of the uncompressed data.
148 <p>
149 If there is an error in reading from the input file, the process is aborted with
150 <tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
151 the error. We wouldn't want a memory leak, now would we? <tt>deflateEnd()</tt> can be called
152 at any time after the state has been initialized. Once that's done, <tt>deflateInit()</tt> (or
153 <tt>deflateInit2()</tt>) would have to be called to start a new compression process. There is
154 no point here in checking the <tt>deflateEnd()</tt> return code. The deallocation can't fail.
155 <pre><b>
156 strm.avail_in = fread(in, 1, CHUNK, source);
157 if (ferror(source)) {
158 (void)deflateEnd(&amp;strm);
159 return Z_ERRNO;
160 }
161 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
162 strm.next_in = in;
163 </b></pre><!-- -->
164 The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
165 keeps calling <tt>deflate()</tt> until it is done producing output. Once there is no more
166 new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
167 <tt>avail_in</tt> will be zero.
168 <pre><b>
169 /* run deflate() on input until output buffer not full, finish
170 compression if all of source has been read in */
171 do {
172 </b></pre>
173 Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
174 of available output bytes and <tt>next_out</tt> to a pointer to that space.
175 <pre><b>
176 strm.avail_out = CHUNK;
177 strm.next_out = out;
178 </b></pre>
179 Now we call the compression engine itself, <tt>deflate()</tt>. It takes as many of the
180 <tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
181 <tt>avail_out</tt> bytes to <tt>next_out</tt>. Those counters and pointers are then
182 updated past the input data consumed and the output data written. It is the amount of
183 output space available that may limit how much input is consumed.
184 Hence the inner loop to make sure that
185 all of the input is consumed by providing more output space each time. Since <tt>avail_in</tt>
186 and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
187 between <tt>deflate()</tt> calls until it's all used up.
188 <p>
189 The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
190 the input and output information and the internal compression engine state, and a parameter
191 indicating whether and how to flush data to the output. Normally <tt>deflate</tt> will consume
192 several K bytes of input data before producing any output (except for the header), in order
193 to accumulate statistics on the data for optimum compression. It will then put out a burst of
194 compressed data, and proceed to consume more input before the next burst. Eventually,
195 <tt>deflate()</tt>
196 must be told to terminate the stream, complete the compression with provided input data, and
197 write out the trailer check value. <tt>deflate()</tt> will continue to compress normally as long
198 as the flush parameter is <tt>Z_NO_FLUSH</tt>. Once the <tt>Z_FINISH</tt> parameter is provided,
199 <tt>deflate()</tt> will begin to complete the compressed output stream. However depending on how
200 much output space is provided, <tt>deflate()</tt> may have to be called several times until it
201 has provided the complete compressed stream, even after it has consumed all of the input. The flush
202 parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
203 <p>
204 There are other values of the flush parameter that are used in more advanced applications. You can
205 force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
206 so far, even if it wouldn't have otherwise, for example to control data latency on a link with
207 compressed data. You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
208 that point so that what follows can be decompressed independently, for example for random access
209 applications. Both requests will degrade compression by an amount depending on how often such
210 requests are made.
211 <p>
212 <tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here. Why
213 not? Well, it turns out that <tt>deflate()</tt> can do no wrong here. Let's go through
214 <tt>deflate()</tt>'s return values and dispense with them one by one. The possible values are
215 <tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>. <tt>Z_OK</tt>
216 is, well, ok. <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
217 <tt>deflate()</tt>. This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
218 until it has no more output. <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
219 initialized properly, but we did initialize it properly. There is no harm in checking for
220 <tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
221 other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
222 <tt>Z_BUF_ERROR</tt> will be explained further below, but
223 suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
224 more input or produce more output. <tt>deflate()</tt> can be called again with more output space
225 or more available input, which it will be in this code.
226 <pre><b>
227 ret = deflate(&amp;strm, flush); /* no bad return value */
228 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
229 </b></pre>
230 Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
231 difference between how much space was provided before the call, and how much output space
232 is still available after the call. Then that data, if any, is written to the output file.
233 We can then reuse the output buffer for the next call of <tt>deflate()</tt>. Again if there
234 is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
235 <pre><b>
236 have = CHUNK - strm.avail_out;
237 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
238 (void)deflateEnd(&amp;strm);
239 return Z_ERRNO;
240 }
241 </b></pre>
242 The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
243 provided output buffer. Then we know that <tt>deflate()</tt> has done as much as it can with
244 the provided input, and that all of that input has been consumed. We can then fall out of this
245 loop and reuse the input buffer.
246 <p>
247 The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
248 the output buffer, leaving <tt>avail_out</tt> greater than zero. However suppose that
249 <tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
250 <tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
251 As far as we know, <tt>deflate()</tt>
252 has more output for us. So we call it again. But now <tt>deflate()</tt> produces no output
253 at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>. That <tt>deflate()</tt> call
254 wasn't able to do anything, either consume input or produce output, and so it returns
255 <tt>Z_BUF_ERROR</tt>. (See, I told you I'd cover this later.) However this is not a problem at
256 all. Now we finally have the desired indication that <tt>deflate()</tt> is really done,
257 and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
258 <p>
259 With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
260 complete the output stream. Once that is done, subsequent calls of <tt>deflate()</tt> would return
261 <tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
262 until the state is reinitialized.
263 <p>
264 Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
265 instead of the single inner loop we have here. The first loop would call
266 without flushing and feed all of the data to <tt>deflate()</tt>. The second loop would call
267 <tt>deflate()</tt> with no more
268 data and the <tt>Z_FINISH</tt> parameter to complete the process. As you can see from this
269 example, that can be avoided by simply keeping track of the current flush state.
270 <pre><b>
271 } while (strm.avail_out == 0);
272 assert(strm.avail_in == 0); /* all input will be used */
273 </b></pre><!-- -->
274 Now we check to see if we have already processed all of the input file. That information was
275 saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>. If so,
276 then we're done and we fall out of the outer loop. We're guaranteed to get <tt>Z_STREAM_END</tt>
277 from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
278 consumed and all of the output was generated.
279 <pre><b>
280 /* done when last data in file processed */
281 } while (flush != Z_FINISH);
282 assert(ret == Z_STREAM_END); /* stream will be complete */
283 </b></pre><!-- -->
284 The process is complete, but we still need to deallocate the state to avoid a memory leak
285 (or rather more like a memory hemorrhage if you didn't do this). Then
286 finally we can return with a happy return value.
287 <pre><b>
288 /* clean up and return */
289 (void)deflateEnd(&amp;strm);
290 return Z_OK;
291 }
292 </b></pre><!-- -->
293 Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
294 decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
295 uncompressed data to the output file. Much of the discussion above for <tt>def()</tt>
296 applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
297 the two.
298 <pre><b>
299 /* Decompress from file source to file dest until stream ends or EOF.
300 inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
301 allocated for processing, Z_DATA_ERROR if the deflate data is
302 invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
303 the version of the library linked do not match, or Z_ERRNO if there
304 is an error reading or writing the files. */
305 int inf(FILE *source, FILE *dest)
306 {
307 </b></pre>
308 The local variables have the same functionality as they do for <tt>def()</tt>. The
309 only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
310 can tell from the <em>zlib</em> stream itself when the stream is complete.
311 <pre><b>
312 int ret;
313 unsigned have;
314 z_stream strm;
315 char in[CHUNK];
316 char out[CHUNK];
317 </b></pre><!-- -->
318 The initialization of the state is the same, except that there is no compression level,
319 of course, and two more elements of the structure are initialized. <tt>avail_in</tt>
320 and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>. This
321 is because the application has the option to provide the start of the zlib stream in
322 order for <tt>inflateInit()</tt> to have access to information about the compression
323 method to aid in memory allocation. In the current implementation of <em>zlib</em>
324 (up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
325 <tt>inflate()</tt> anyway. However those fields must be initialized since later versions
326 of <em>zlib</em> that provide more compression methods may take advantage of this interface.
327 In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
328 <tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
329 <p>
330 Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
331 indicate that no input data is being provided.
332 <pre><b>
333 /* allocate inflate state */
334 strm.zalloc = Z_NULL;
335 strm.zfree = Z_NULL;
336 strm.opaque = Z_NULL;
337 strm.avail_in = 0;
338 strm.next_in = Z_NULL;
339 ret = inflateInit(&amp;strm);
340 if (ret != Z_OK)
341 return ret;
342 </b></pre><!-- -->
343 The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
344 that it has reached the end of the compressed data and has produced all of the uncompressed
345 output. This is in contrast to <tt>def()</tt> which processes all of the input file.
346 If end-of-file is reached before the compressed data self-terminates, then the compressed
347 data is incomplete and an error is returned.
348 <pre><b>
349 /* decompress until deflate stream ends or end of file */
350 do {
351 </b></pre>
352 We read input data and set the <tt>strm</tt> structure accordingly. If we've reached the
353 end of the input file, then we leave the outer loop and report an error, since the
354 compressed data is incomplete. Note that we may read more data than is eventually consumed
355 by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
356 For applications where <em>zlib</em> streams are embedded in other data, this routine would
357 need to be modified to return the unused data, or at least indicate how much of the input
358 data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
359 <pre><b>
360 strm.avail_in = fread(in, 1, CHUNK, source);
361 if (ferror(source)) {
362 (void)inflateEnd(&amp;strm);
363 return Z_ERRNO;
364 }
365 if (strm.avail_in == 0)
366 break;
367 strm.next_in = in;
368 </b></pre><!-- -->
369 The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
370 keep calling <tt>inflate()</tt> until has generated all of the output it can with the
371 provided input.
372 <pre><b>
373 /* run inflate() on input until output buffer not full */
374 do {
375 </b></pre>
376 Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
377 <pre><b>
378 strm.avail_out = CHUNK;
379 strm.next_out = out;
380 </b></pre>
381 Now we run the decompression engine itself. There is no need to adjust the flush parameter, since
382 the <em>zlib</em> format is self-terminating. The main difference here is that there are
383 return values that we need to pay attention to. <tt>Z_DATA_ERROR</tt>
384 indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
385 which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
386 corrupted somewhere along the way since it was compressed. The other error to be processed is
387 <tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
388 needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
389 <p>
390 Advanced applications may use
391 <tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
392 first 32K or so of compression. This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
393 requests that that dictionary be provided before it can start to decompress. Without the dictionary,
394 correct decompression is not possible. For this routine, we have no idea what the dictionary is,
395 so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
396 <p>
397 <tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
398 but could be checked for as noted above for <tt>def()</tt>. <tt>Z_BUF_ERROR</tt> does not need to be
399 checked for here, for the same reasons noted for <tt>def()</tt>. <tt>Z_STREAM_END</tt> will be
400 checked for later.
401 <pre><b>
402 ret = inflate(&amp;strm, Z_NO_FLUSH);
403 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
404 switch (ret) {
405 case Z_NEED_DICT:
406 ret = Z_DATA_ERROR; /* and fall through */
407 case Z_DATA_ERROR:
408 case Z_MEM_ERROR:
409 (void)inflateEnd(&amp;strm);
410 return ret;
411 }
412 </b></pre>
413 The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
414 <pre><b>
415 have = CHUNK - strm.avail_out;
416 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
417 (void)inflateEnd(&amp;strm);
418 return Z_ERRNO;
419 }
420 </b></pre>
421 The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
422 by not filling the output buffer, just as for <tt>deflate()</tt>.
423 <pre><b>
424 } while (strm.avail_out == 0);
425 assert(strm.avail_in == 0); /* all input will be used */
426 </b></pre><!-- -->
427 The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
428 end of the input <em>zlib</em> stream, has completed the decompression and integrity
429 check, and has provided all of the output. This is indicated by the <tt>inflate()</tt>
430 return value <tt>Z_STREAM_END</tt>. The inner loop is guaranteed to leave <tt>ret</tt>
431 equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
432 of the <em>zlib</em> stream. So if the return value is not <tt>Z_STREAM_END</tt>, the
433 loop continues to read more input.
434 <pre><b>
435 /* done when inflate() says it's done */
436 } while (ret != Z_STREAM_END);
437 </b></pre><!-- -->
438 At this point, decompression successfully completed, or we broke out of the loop due to no
439 more data being available from the input file. If the last <tt>inflate()</tt> return value
440 is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
441 is returned. Otherwise, we return with a happy return value. Of course, <tt>inflateEnd()</tt>
442 is called first to avoid a memory leak.
443 <pre><b>
444 /* clean up and return */
445 (void)inflateEnd(&amp;strm);
446 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
447 }
448 </b></pre><!-- -->
449 That ends the routines that directly use <em>zlib</em>. The following routines make this
450 a command-line program by running data through the above routines from <tt>stdin</tt> to
451 <tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
452 <p>
453 <tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
454 and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
455 Note that these are only a subset of the possible return values from <tt>deflate()</tt>
456 and <tt>inflate()</tt>.
457 <pre><b>
458 /* report a zlib or i/o error */
459 void zerr(int ret)
460 {
461 fputs("zpipe: ", stderr);
462 switch (ret) {
463 case Z_ERRNO:
464 if (ferror(stdin))
465 fputs("error reading stdin\n", stderr);
466 if (ferror(stdout))
467 fputs("error writing stdout\n", stderr);
468 break;
469 case Z_STREAM_ERROR:
470 fputs("invalid compression level\n", stderr);
471 break;
472 case Z_DATA_ERROR:
473 fputs("invalid or incomplete deflate data\n", stderr);
474 break;
475 case Z_MEM_ERROR:
476 fputs("out of memory\n", stderr);
477 break;
478 case Z_VERSION_ERROR:
479 fputs("zlib version mismatch!\n", stderr);
480 }
481 }
482 </b></pre><!-- -->
483 Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>. The
484 <tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
485 no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used. If any other
486 arguments are provided, no compression or decompression is performed. Instead a usage
487 message is displayed. Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
488 <tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
489 <pre><b>
490 /* compress or decompress from stdin to stdout */
491 int main(int argc, char **argv)
492 {
493 int ret;
494
495 /* do compression if no arguments */
496 if (argc == 1) {
497 ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
498 if (ret != Z_OK)
499 zerr(ret);
500 return ret;
501 }
502
503 /* do decompression if -d specified */
504 else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
505 ret = inf(stdin, stdout);
506 if (ret != Z_OK)
507 zerr(ret);
508 return ret;
509 }
510
511 /* otherwise, report usage */
512 else {
513 fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
514 return 1;
515 }
516 }
517 </b></pre>
518 <hr>
519 <i>Copyright (c) 2004 by Mark Adler<br>Last modified 13 November 2004</i>
520 </body>
521 </html>
0 /* zpipe.c: example of proper use of zlib's inflate() and deflate()
1 Not copyrighted -- provided to the public domain
2 Version 1.2 9 November 2004 Mark Adler */
3
4 /* Version history:
5 1.0 30 Oct 2004 First version
6 1.1 8 Nov 2004 Add void casting for unused return values
7 Use switch statement for inflate() return values
8 1.2 9 Nov 2004 Add assertions to document zlib guarantees
9 */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <assert.h>
14 #include "zlib.h"
15
16 #define CHUNK 16384
17
18 /* Compress from file source to file dest until EOF on source.
19 def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
20 allocated for processing, Z_STREAM_ERROR if an invalid compression
21 level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
22 version of the library linked do not match, or Z_ERRNO if there is
23 an error reading or writing the files. */
24 int def(FILE *source, FILE *dest, int level)
25 {
26 int ret, flush;
27 unsigned have;
28 z_stream strm;
29 char in[CHUNK];
30 char out[CHUNK];
31
32 /* allocate deflate state */
33 strm.zalloc = Z_NULL;
34 strm.zfree = Z_NULL;
35 strm.opaque = Z_NULL;
36 ret = deflateInit(&strm, level);
37 if (ret != Z_OK)
38 return ret;
39
40 /* compress until end of file */
41 do {
42 strm.avail_in = fread(in, 1, CHUNK, source);
43 if (ferror(source)) {
44 (void)deflateEnd(&strm);
45 return Z_ERRNO;
46 }
47 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
48 strm.next_in = in;
49
50 /* run deflate() on input until output buffer not full, finish
51 compression if all of source has been read in */
52 do {
53 strm.avail_out = CHUNK;
54 strm.next_out = out;
55 ret = deflate(&strm, flush); /* no bad return value */
56 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
57 have = CHUNK - strm.avail_out;
58 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
59 (void)deflateEnd(&strm);
60 return Z_ERRNO;
61 }
62 } while (strm.avail_out == 0);
63 assert(strm.avail_in == 0); /* all input will be used */
64
65 /* done when last data in file processed */
66 } while (flush != Z_FINISH);
67 assert(ret == Z_STREAM_END); /* stream will be complete */
68
69 /* clean up and return */
70 (void)deflateEnd(&strm);
71 return Z_OK;
72 }
73
74 /* Decompress from file source to file dest until stream ends or EOF.
75 inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
76 allocated for processing, Z_DATA_ERROR if the deflate data is
77 invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
78 the version of the library linked do not match, or Z_ERRNO if there
79 is an error reading or writing the files. */
80 int inf(FILE *source, FILE *dest)
81 {
82 int ret;
83 unsigned have;
84 z_stream strm;
85 char in[CHUNK];
86 char out[CHUNK];
87
88 /* allocate inflate state */
89 strm.zalloc = Z_NULL;
90 strm.zfree = Z_NULL;
91 strm.opaque = Z_NULL;
92 strm.avail_in = 0;
93 strm.next_in = Z_NULL;
94 ret = inflateInit(&strm);
95 if (ret != Z_OK)
96 return ret;
97
98 /* decompress until deflate stream ends or end of file */
99 do {
100 strm.avail_in = fread(in, 1, CHUNK, source);
101 if (ferror(source)) {
102 (void)inflateEnd(&strm);
103 return Z_ERRNO;
104 }
105 if (strm.avail_in == 0)
106 break;
107 strm.next_in = in;
108
109 /* run inflate() on input until output buffer not full */
110 do {
111 strm.avail_out = CHUNK;
112 strm.next_out = out;
113 ret = inflate(&strm, Z_NO_FLUSH);
114 assert(ret != Z_STREAM_ERROR); /* state not clobbered */
115 switch (ret) {
116 case Z_NEED_DICT:
117 ret = Z_DATA_ERROR; /* and fall through */
118 case Z_DATA_ERROR:
119 case Z_MEM_ERROR:
120 (void)inflateEnd(&strm);
121 return ret;
122 }
123 have = CHUNK - strm.avail_out;
124 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
125 (void)inflateEnd(&strm);
126 return Z_ERRNO;
127 }
128 } while (strm.avail_out == 0);
129 assert(strm.avail_in == 0); /* all input will be used */
130
131 /* done when inflate() says it's done */
132 } while (ret != Z_STREAM_END);
133
134 /* clean up and return */
135 (void)inflateEnd(&strm);
136 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
137 }
138
139 /* report a zlib or i/o error */
140 void zerr(int ret)
141 {
142 fputs("zpipe: ", stderr);
143 switch (ret) {
144 case Z_ERRNO:
145 if (ferror(stdin))
146 fputs("error reading stdin\n", stderr);
147 if (ferror(stdout))
148 fputs("error writing stdout\n", stderr);
149 break;
150 case Z_STREAM_ERROR:
151 fputs("invalid compression level\n", stderr);
152 break;
153 case Z_DATA_ERROR:
154 fputs("invalid or incomplete deflate data\n", stderr);
155 break;
156 case Z_MEM_ERROR:
157 fputs("out of memory\n", stderr);
158 break;
159 case Z_VERSION_ERROR:
160 fputs("zlib version mismatch!\n", stderr);
161 }
162 }
163
164 /* compress or decompress from stdin to stdout */
165 int main(int argc, char **argv)
166 {
167 int ret;
168
169 /* do compression if no arguments */
170 if (argc == 1) {
171 ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
172 if (ret != Z_OK)
173 zerr(ret);
174 return ret;
175 }
176
177 /* do decompression if -d specified */
178 else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
179 ret = inf(stdin, stdout);
180 if (ret != Z_OK)
181 zerr(ret);
182 return ret;
183 }
184
185 /* otherwise, report usage */
186 else {
187 fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
188 return 1;
189 }
190 }
0 /* gzio.c -- IO on .gz files
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 *
4 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
5 */
6
7 /* @(#) $Id$ */
8
9 #include <stdio.h>
10
11 #include "zutil.h"
12
13 #ifdef NO_DEFLATE /* for compatibility with old definition */
14 # define NO_GZCOMPRESS
15 #endif
16
17 #ifndef NO_DUMMY_DECL
18 struct internal_state {int dummy;}; /* for buggy compilers */
19 #endif
20
21 #ifndef Z_BUFSIZE
22 # ifdef MAXSEG_64K
23 # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
24 # else
25 # define Z_BUFSIZE 16384
26 # endif
27 #endif
28 #ifndef Z_PRINTF_BUFSIZE
29 # define Z_PRINTF_BUFSIZE 4096
30 #endif
31
32 #ifdef __MVS__
33 # pragma map (fdopen , "\174\174FDOPEN")
34 FILE *fdopen(int, const char *);
35 #endif
36
37 #ifndef STDC
38 extern voidp malloc OF((uInt size));
39 extern void free OF((voidpf ptr));
40 #endif
41
42 #define ALLOC(size) malloc(size)
43 #define TRYFREE(p) {if (p) free(p);}
44
45 static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
46
47 /* gzip flag byte */
48 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
49 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
50 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
51 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
52 #define COMMENT 0x10 /* bit 4 set: file comment present */
53 #define RESERVED 0xE0 /* bits 5..7: reserved */
54
55 typedef struct gz_stream {
56 z_stream stream;
57 int z_err; /* error code for last stream operation */
58 int z_eof; /* set if end of input file */
59 FILE *file; /* .gz file */
60 Byte *inbuf; /* input buffer */
61 Byte *outbuf; /* output buffer */
62 uLong crc; /* crc32 of uncompressed data */
63 char *msg; /* error message */
64 char *path; /* path name for debugging only */
65 int transparent; /* 1 if input file is not a .gz file */
66 char mode; /* 'w' or 'r' */
67 z_off_t start; /* start of compressed data in file (header skipped) */
68 z_off_t in; /* bytes into deflate or inflate */
69 z_off_t out; /* bytes out of deflate or inflate */
70 int back; /* one character push-back */
71 int last; /* true if push-back is last character */
72 } gz_stream;
73
74
75 local gzFile gz_open OF((const char *path, const char *mode, int fd));
76 local int do_flush OF((gzFile file, int flush));
77 local int get_byte OF((gz_stream *s));
78 local void check_header OF((gz_stream *s));
79 local int destroy OF((gz_stream *s));
80 local void putLong OF((FILE *file, uLong x));
81 local uLong getLong OF((gz_stream *s));
82
83 /* ===========================================================================
84 Opens a gzip (.gz) file for reading or writing. The mode parameter
85 is as in fopen ("rb" or "wb"). The file is given either by file descriptor
86 or path name (if fd == -1).
87 gz_open returns NULL if the file could not be opened or if there was
88 insufficient memory to allocate the (de)compression state; errno
89 can be checked to distinguish the two cases (if errno is zero, the
90 zlib error is Z_MEM_ERROR).
91 */
92 local gzFile gz_open (path, mode, fd)
93 const char *path;
94 const char *mode;
95 int fd;
96 {
97 int err;
98 int level = Z_DEFAULT_COMPRESSION; /* compression level */
99 int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
100 char *p = (char*)mode;
101 gz_stream *s;
102 char fmode[80]; /* copy of mode, without the compression level */
103 char *m = fmode;
104
105 if (!path || !mode) return Z_NULL;
106
107 s = (gz_stream *)ALLOC(sizeof(gz_stream));
108 if (!s) return Z_NULL;
109
110 s->stream.zalloc = (alloc_func)0;
111 s->stream.zfree = (free_func)0;
112 s->stream.opaque = (voidpf)0;
113 s->stream.next_in = s->inbuf = Z_NULL;
114 s->stream.next_out = s->outbuf = Z_NULL;
115 s->stream.avail_in = s->stream.avail_out = 0;
116 s->file = NULL;
117 s->z_err = Z_OK;
118 s->z_eof = 0;
119 s->in = 0;
120 s->out = 0;
121 s->back = EOF;
122 s->crc = crc32(0L, Z_NULL, 0);
123 s->msg = NULL;
124 s->transparent = 0;
125
126 s->path = (char*)ALLOC(strlen(path)+1);
127 if (s->path == NULL) {
128 return destroy(s), (gzFile)Z_NULL;
129 }
130 strcpy(s->path, path); /* do this early for debugging */
131
132 s->mode = '\0';
133 do {
134 if (*p == 'r') s->mode = 'r';
135 if (*p == 'w' || *p == 'a') s->mode = 'w';
136 if (*p >= '0' && *p <= '9') {
137 level = *p - '0';
138 } else if (*p == 's') {
139 strategy |= Z_RSYNCABLE;
140 } else if (*p == 'f') {
141 strategy = (strategy & Z_RSYNCABLE) | Z_FILTERED;
142 } else if (*p == 'h') {
143 strategy = (strategy & Z_RSYNCABLE) | Z_HUFFMAN_ONLY;
144 } else if (*p == 'R') {
145 strategy = (strategy & Z_RSYNCABLE) | Z_RLE;
146 } else {
147 *m++ = *p; /* copy the mode */
148 }
149 } while (*p++ && m != fmode + sizeof(fmode));
150 if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
151
152 if (s->mode == 'w') {
153 #ifdef NO_GZCOMPRESS
154 err = Z_STREAM_ERROR;
155 #else
156 err = deflateInit2(&(s->stream), level,
157 Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
158 /* windowBits is passed < 0 to suppress zlib header */
159
160 s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
161 #endif
162 if (err != Z_OK || s->outbuf == Z_NULL) {
163 return destroy(s), (gzFile)Z_NULL;
164 }
165 } else {
166 s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
167
168 err = inflateInit2(&(s->stream), -MAX_WBITS);
169 /* windowBits is passed < 0 to tell that there is no zlib header.
170 * Note that in this case inflate *requires* an extra "dummy" byte
171 * after the compressed stream in order to complete decompression and
172 * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
173 * present after the compressed stream.
174 */
175 if (err != Z_OK || s->inbuf == Z_NULL) {
176 return destroy(s), (gzFile)Z_NULL;
177 }
178 }
179 s->stream.avail_out = Z_BUFSIZE;
180
181 errno = 0;
182 s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
183
184 if (s->file == NULL) {
185 return destroy(s), (gzFile)Z_NULL;
186 }
187 if (s->mode == 'w') {
188 /* Write a very simple .gz header:
189 */
190 fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
191 Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
192 s->start = 10L;
193 /* We use 10L instead of ftell(s->file) to because ftell causes an
194 * fflush on some systems. This version of the library doesn't use
195 * start anyway in write mode, so this initialization is not
196 * necessary.
197 */
198 } else {
199 check_header(s); /* skip the .gz header */
200 s->start = ftell(s->file) - s->stream.avail_in;
201 }
202
203 return (gzFile)s;
204 }
205
206 /* ===========================================================================
207 Opens a gzip (.gz) file for reading or writing.
208 */
209 gzFile ZEXPORT gzopen (path, mode)
210 const char *path;
211 const char *mode;
212 {
213 return gz_open (path, mode, -1);
214 }
215
216 /* ===========================================================================
217 Associate a gzFile with the file descriptor fd. fd is not dup'ed here
218 to mimic the behavio(u)r of fdopen.
219 */
220 gzFile ZEXPORT gzdopen (fd, mode)
221 int fd;
222 const char *mode;
223 {
224 char name[46]; /* allow for up to 128-bit integers */
225
226 if (fd < 0) return (gzFile)Z_NULL;
227 sprintf(name, "<fd:%d>", fd); /* for debugging */
228
229 return gz_open (name, mode, fd);
230 }
231
232 /* ===========================================================================
233 * Update the compression level and strategy
234 */
235 int ZEXPORT gzsetparams (file, level, strategy)
236 gzFile file;
237 int level;
238 int strategy;
239 {
240 gz_stream *s = (gz_stream*)file;
241
242 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
243
244 /* Make room to allow flushing */
245 if (s->stream.avail_out == 0) {
246
247 s->stream.next_out = s->outbuf;
248 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
249 s->z_err = Z_ERRNO;
250 }
251 s->stream.avail_out = Z_BUFSIZE;
252 }
253
254 return deflateParams (&(s->stream), level, strategy);
255 }
256
257 /* ===========================================================================
258 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
259 for end of file.
260 IN assertion: the stream s has been sucessfully opened for reading.
261 */
262 local int get_byte(s)
263 gz_stream *s;
264 {
265 if (s->z_eof) return EOF;
266 if (s->stream.avail_in == 0) {
267 errno = 0;
268 s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
269 if (s->stream.avail_in == 0) {
270 s->z_eof = 1;
271 if (ferror(s->file)) s->z_err = Z_ERRNO;
272 return EOF;
273 }
274 s->stream.next_in = s->inbuf;
275 }
276 s->stream.avail_in--;
277 return *(s->stream.next_in)++;
278 }
279
280 /* ===========================================================================
281 Check the gzip header of a gz_stream opened for reading. Set the stream
282 mode to transparent if the gzip magic header is not present; set s->err
283 to Z_DATA_ERROR if the magic header is present but the rest of the header
284 is incorrect.
285 IN assertion: the stream s has already been created sucessfully;
286 s->stream.avail_in is zero for the first time, but may be non-zero
287 for concatenated .gz files.
288 */
289 local void check_header(s)
290 gz_stream *s;
291 {
292 int method; /* method byte */
293 int flags; /* flags byte */
294 uInt len;
295 int c;
296
297 /* Assure two bytes in the buffer so we can peek ahead -- handle case
298 where first byte of header is at the end of the buffer after the last
299 gzip segment */
300 len = s->stream.avail_in;
301 if (len < 2) {
302 if (len) s->inbuf[0] = s->stream.next_in[0];
303 errno = 0;
304 len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
305 if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
306 s->stream.avail_in += len;
307 s->stream.next_in = s->inbuf;
308 if (s->stream.avail_in < 2) {
309 s->transparent = s->stream.avail_in;
310 return;
311 }
312 }
313
314 /* Peek ahead to check the gzip magic header */
315 if (s->stream.next_in[0] != gz_magic[0] ||
316 s->stream.next_in[1] != gz_magic[1]) {
317 s->transparent = 1;
318 return;
319 }
320 s->stream.avail_in -= 2;
321 s->stream.next_in += 2;
322
323 /* Check the rest of the gzip header */
324 method = get_byte(s);
325 flags = get_byte(s);
326 if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
327 s->z_err = Z_DATA_ERROR;
328 return;
329 }
330
331 /* Discard time, xflags and OS code: */
332 for (len = 0; len < 6; len++) (void)get_byte(s);
333
334 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
335 len = (uInt)get_byte(s);
336 len += ((uInt)get_byte(s))<<8;
337 /* len is garbage if EOF but the loop below will quit anyway */
338 while (len-- != 0 && get_byte(s) != EOF) ;
339 }
340 if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
341 while ((c = get_byte(s)) != 0 && c != EOF) ;
342 }
343 if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
344 while ((c = get_byte(s)) != 0 && c != EOF) ;
345 }
346 if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
347 for (len = 0; len < 2; len++) (void)get_byte(s);
348 }
349 s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
350 }
351
352 /* ===========================================================================
353 * Cleanup then free the given gz_stream. Return a zlib error code.
354 Try freeing in the reverse order of allocations.
355 */
356 local int destroy (s)
357 gz_stream *s;
358 {
359 int err = Z_OK;
360
361 if (!s) return Z_STREAM_ERROR;
362
363 TRYFREE(s->msg);
364
365 if (s->stream.state != NULL) {
366 if (s->mode == 'w') {
367 #ifdef NO_GZCOMPRESS
368 err = Z_STREAM_ERROR;
369 #else
370 err = deflateEnd(&(s->stream));
371 #endif
372 } else if (s->mode == 'r') {
373 err = inflateEnd(&(s->stream));
374 }
375 }
376 if (s->file != NULL && fclose(s->file)) {
377 #ifdef ESPIPE
378 if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
379 #endif
380 err = Z_ERRNO;
381 }
382 if (s->z_err < 0) err = s->z_err;
383
384 TRYFREE(s->inbuf);
385 TRYFREE(s->outbuf);
386 TRYFREE(s->path);
387 TRYFREE(s);
388 return err;
389 }
390
391 /* ===========================================================================
392 Reads the given number of uncompressed bytes from the compressed file.
393 gzread returns the number of bytes actually read (0 for end of file).
394 */
395 int ZEXPORT gzread (file, buf, len)
396 gzFile file;
397 voidp buf;
398 unsigned len;
399 {
400 gz_stream *s = (gz_stream*)file;
401 Bytef *start = (Bytef*)buf; /* starting point for crc computation */
402 Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
403
404 if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
405
406 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
407 if (s->z_err == Z_STREAM_END) return 0; /* EOF */
408
409 next_out = (Byte*)buf;
410 s->stream.next_out = (Bytef*)buf;
411 s->stream.avail_out = len;
412
413 if (s->stream.avail_out && s->back != EOF) {
414 *next_out++ = s->back;
415 s->stream.next_out++;
416 s->stream.avail_out--;
417 s->back = EOF;
418 s->out++;
419 if (s->last) {
420 s->z_err = Z_STREAM_END;
421 return 1;
422 }
423 }
424
425 while (s->stream.avail_out != 0) {
426
427 if (s->transparent) {
428 /* Copy first the lookahead bytes: */
429 uInt n = s->stream.avail_in;
430 if (n > s->stream.avail_out) n = s->stream.avail_out;
431 if (n > 0) {
432 zmemcpy(s->stream.next_out, s->stream.next_in, n);
433 next_out += n;
434 s->stream.next_out = next_out;
435 s->stream.next_in += n;
436 s->stream.avail_out -= n;
437 s->stream.avail_in -= n;
438 }
439 if (s->stream.avail_out > 0) {
440 s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
441 s->file);
442 }
443 len -= s->stream.avail_out;
444 s->in += len;
445 s->out += len;
446 if (len == 0) s->z_eof = 1;
447 return (int)len;
448 }
449 if (s->stream.avail_in == 0 && !s->z_eof) {
450
451 errno = 0;
452 s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
453 if (s->stream.avail_in == 0) {
454 s->z_eof = 1;
455 if (ferror(s->file)) {
456 s->z_err = Z_ERRNO;
457 break;
458 }
459 if (feof(s->file)) { /* avoid error for empty file */
460 s->z_err = Z_STREAM_END;
461 break;
462 }
463 }
464 s->stream.next_in = s->inbuf;
465 }
466 s->in += s->stream.avail_in;
467 s->out += s->stream.avail_out;
468 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
469 s->in -= s->stream.avail_in;
470 s->out -= s->stream.avail_out;
471
472 if (s->z_err == Z_STREAM_END) {
473 /* Check CRC and original size */
474 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
475 start = s->stream.next_out;
476
477 if (getLong(s) != s->crc) {
478 s->z_err = Z_DATA_ERROR;
479 } else {
480 (void)getLong(s);
481 /* The uncompressed length returned by above getlong() may be
482 * different from s->out in case of concatenated .gz files.
483 * Check for such files:
484 */
485 check_header(s);
486 if (s->z_err == Z_OK) {
487 inflateReset(&(s->stream));
488 s->crc = crc32(0L, Z_NULL, 0);
489 }
490 }
491 }
492 if (s->z_err != Z_OK || s->z_eof) break;
493 }
494 s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
495
496 return (int)(len - s->stream.avail_out);
497 }
498
499
500 /* ===========================================================================
501 Reads one byte from the compressed file. gzgetc returns this byte
502 or -1 in case of end of file or error.
503 */
504 int ZEXPORT gzgetc(file)
505 gzFile file;
506 {
507 unsigned char c;
508
509 return gzread(file, &c, 1) == 1 ? c : -1;
510 }
511
512
513 /* ===========================================================================
514 Push one byte back onto the stream.
515 */
516 int ZEXPORT gzungetc(c, file)
517 int c;
518 gzFile file;
519 {
520 gz_stream *s = (gz_stream*)file;
521
522 if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
523 s->back = c;
524 s->out--;
525 s->last = (s->z_err == Z_STREAM_END);
526 if (s->last) s->z_err = Z_OK;
527 s->z_eof = 0;
528 return c;
529 }
530
531
532 /* ===========================================================================
533 Reads bytes from the compressed file until len-1 characters are
534 read, or a newline character is read and transferred to buf, or an
535 end-of-file condition is encountered. The string is then terminated
536 with a null character.
537 gzgets returns buf, or Z_NULL in case of error.
538
539 The current implementation is not optimized at all.
540 */
541 char * ZEXPORT gzgets(file, buf, len)
542 gzFile file;
543 char *buf;
544 int len;
545 {
546 char *b = buf;
547 if (buf == Z_NULL || len <= 0) return Z_NULL;
548
549 while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
550 *buf = '\0';
551 return b == buf && len > 0 ? Z_NULL : b;
552 }
553
554
555 #ifndef NO_GZCOMPRESS
556 /* ===========================================================================
557 Writes the given number of uncompressed bytes into the compressed file.
558 gzwrite returns the number of bytes actually written (0 in case of error).
559 */
560 int ZEXPORT gzwrite (file, buf, len)
561 gzFile file;
562 voidpc buf;
563 unsigned len;
564 {
565 gz_stream *s = (gz_stream*)file;
566
567 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
568
569 s->stream.next_in = (Bytef*)buf;
570 s->stream.avail_in = len;
571
572 while (s->stream.avail_in != 0) {
573
574 if (s->stream.avail_out == 0) {
575
576 s->stream.next_out = s->outbuf;
577 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
578 s->z_err = Z_ERRNO;
579 break;
580 }
581 s->stream.avail_out = Z_BUFSIZE;
582 }
583 s->in += s->stream.avail_in;
584 s->out += s->stream.avail_out;
585 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
586 s->in -= s->stream.avail_in;
587 s->out -= s->stream.avail_out;
588 if (s->z_err != Z_OK) break;
589 }
590 s->crc = crc32(s->crc, (const Bytef *)buf, len);
591
592 return (int)(len - s->stream.avail_in);
593 }
594
595
596 /* ===========================================================================
597 Converts, formats, and writes the args to the compressed file under
598 control of the format string, as in fprintf. gzprintf returns the number of
599 uncompressed bytes actually written (0 in case of error).
600 */
601 #ifdef STDC
602 #include <stdarg.h>
603
604 int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
605 {
606 char buf[Z_PRINTF_BUFSIZE];
607 va_list va;
608 int len;
609
610 buf[sizeof(buf) - 1] = 0;
611 va_start(va, format);
612 #ifdef NO_vsnprintf
613 # ifdef HAS_vsprintf_void
614 (void)vsprintf(buf, format, va);
615 va_end(va);
616 for (len = 0; len < sizeof(buf); len++)
617 if (buf[len] == 0) break;
618 # else
619 len = vsprintf(buf, format, va);
620 va_end(va);
621 # endif
622 #else
623 # ifdef HAS_vsnprintf_void
624 (void)vsnprintf(buf, sizeof(buf), format, va);
625 va_end(va);
626 len = strlen(buf);
627 # else
628 len = vsnprintf(buf, sizeof(buf), format, va);
629 va_end(va);
630 # endif
631 #endif
632 if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
633 return 0;
634 return gzwrite(file, buf, (unsigned)len);
635 }
636 #else /* not ANSI C */
637
638 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
639 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
640 gzFile file;
641 const char *format;
642 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
643 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
644 {
645 char buf[Z_PRINTF_BUFSIZE];
646 int len;
647
648 buf[sizeof(buf) - 1] = 0;
649 #ifdef NO_snprintf
650 # ifdef HAS_sprintf_void
651 sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
652 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
653 for (len = 0; len < sizeof(buf); len++)
654 if (buf[len] == 0) break;
655 # else
656 len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
657 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
658 # endif
659 #else
660 # ifdef HAS_snprintf_void
661 snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
662 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
663 len = strlen(buf);
664 # else
665 len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
666 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
667 # endif
668 #endif
669 if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
670 return 0;
671 return gzwrite(file, buf, len);
672 }
673 #endif
674
675 /* ===========================================================================
676 Writes c, converted to an unsigned char, into the compressed file.
677 gzputc returns the value that was written, or -1 in case of error.
678 */
679 int ZEXPORT gzputc(file, c)
680 gzFile file;
681 int c;
682 {
683 unsigned char cc = (unsigned char) c; /* required for big endian systems */
684
685 return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
686 }
687
688
689 /* ===========================================================================
690 Writes the given null-terminated string to the compressed file, excluding
691 the terminating null character.
692 gzputs returns the number of characters written, or -1 in case of error.
693 */
694 int ZEXPORT gzputs(file, s)
695 gzFile file;
696 const char *s;
697 {
698 return gzwrite(file, (char*)s, (unsigned)strlen(s));
699 }
700
701
702 /* ===========================================================================
703 Flushes all pending output into the compressed file. The parameter
704 flush is as in the deflate() function.
705 */
706 local int do_flush (file, flush)
707 gzFile file;
708 int flush;
709 {
710 uInt len;
711 int done = 0;
712 gz_stream *s = (gz_stream*)file;
713
714 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
715
716 s->stream.avail_in = 0; /* should be zero already anyway */
717
718 for (;;) {
719 len = Z_BUFSIZE - s->stream.avail_out;
720
721 if (len != 0) {
722 if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
723 s->z_err = Z_ERRNO;
724 return Z_ERRNO;
725 }
726 s->stream.next_out = s->outbuf;
727 s->stream.avail_out = Z_BUFSIZE;
728 }
729 if (done) break;
730 s->out += s->stream.avail_out;
731 s->z_err = deflate(&(s->stream), flush);
732 s->out -= s->stream.avail_out;
733
734 /* Ignore the second of two consecutive flushes: */
735 if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
736
737 /* deflate has finished flushing only when it hasn't used up
738 * all the available space in the output buffer:
739 */
740 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
741
742 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
743 }
744 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
745 }
746
747 int ZEXPORT gzflush (file, flush)
748 gzFile file;
749 int flush;
750 {
751 gz_stream *s = (gz_stream*)file;
752 int err = do_flush (file, flush);
753
754 if (err) return err;
755 fflush(s->file);
756 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
757 }
758 #endif /* NO_GZCOMPRESS */
759
760 /* ===========================================================================
761 Sets the starting position for the next gzread or gzwrite on the given
762 compressed file. The offset represents a number of bytes in the
763 gzseek returns the resulting offset location as measured in bytes from
764 the beginning of the uncompressed stream, or -1 in case of error.
765 SEEK_END is not implemented, returns error.
766 In this version of the library, gzseek can be extremely slow.
767 */
768 z_off_t ZEXPORT gzseek (file, offset, whence)
769 gzFile file;
770 z_off_t offset;
771 int whence;
772 {
773 gz_stream *s = (gz_stream*)file;
774
775 if (s == NULL || whence == SEEK_END ||
776 s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
777 return -1L;
778 }
779
780 if (s->mode == 'w') {
781 #ifdef NO_GZCOMPRESS
782 return -1L;
783 #else
784 if (whence == SEEK_SET) {
785 offset -= s->in;
786 }
787 if (offset < 0) return -1L;
788
789 /* At this point, offset is the number of zero bytes to write. */
790 if (s->inbuf == Z_NULL) {
791 s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
792 if (s->inbuf == Z_NULL) return -1L;
793 zmemzero(s->inbuf, Z_BUFSIZE);
794 }
795 while (offset > 0) {
796 uInt size = Z_BUFSIZE;
797 if (offset < Z_BUFSIZE) size = (uInt)offset;
798
799 size = gzwrite(file, s->inbuf, size);
800 if (size == 0) return -1L;
801
802 offset -= size;
803 }
804 return s->in;
805 #endif
806 }
807 /* Rest of function is for reading only */
808
809 /* compute absolute position */
810 if (whence == SEEK_CUR) {
811 offset += s->out;
812 }
813 if (offset < 0) return -1L;
814
815 if (s->transparent) {
816 /* map to fseek */
817 s->back = EOF;
818 s->stream.avail_in = 0;
819 s->stream.next_in = s->inbuf;
820 if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
821
822 s->in = s->out = offset;
823 return offset;
824 }
825
826 /* For a negative seek, rewind and use positive seek */
827 if (offset >= s->out) {
828 offset -= s->out;
829 } else if (gzrewind(file) < 0) {
830 return -1L;
831 }
832 /* offset is now the number of bytes to skip. */
833
834 if (offset != 0 && s->outbuf == Z_NULL) {
835 s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
836 if (s->outbuf == Z_NULL) return -1L;
837 }
838 if (offset && s->back != EOF) {
839 s->back = EOF;
840 s->out++;
841 offset--;
842 if (s->last) s->z_err = Z_STREAM_END;
843 }
844 while (offset > 0) {
845 int size = Z_BUFSIZE;
846 if (offset < Z_BUFSIZE) size = (int)offset;
847
848 size = gzread(file, s->outbuf, (uInt)size);
849 if (size <= 0) return -1L;
850 offset -= size;
851 }
852 return s->out;
853 }
854
855 /* ===========================================================================
856 Rewinds input file.
857 */
858 int ZEXPORT gzrewind (file)
859 gzFile file;
860 {
861 gz_stream *s = (gz_stream*)file;
862
863 if (s == NULL || s->mode != 'r') return -1;
864
865 s->z_err = Z_OK;
866 s->z_eof = 0;
867 s->back = EOF;
868 s->stream.avail_in = 0;
869 s->stream.next_in = s->inbuf;
870 s->crc = crc32(0L, Z_NULL, 0);
871 if (!s->transparent) (void)inflateReset(&s->stream);
872 s->in = 0;
873 s->out = 0;
874 return fseek(s->file, s->start, SEEK_SET);
875 }
876
877 /* ===========================================================================
878 Returns the starting position for the next gzread or gzwrite on the
879 given compressed file. This position represents a number of bytes in the
880 uncompressed data stream.
881 */
882 z_off_t ZEXPORT gztell (file)
883 gzFile file;
884 {
885 return gzseek(file, 0L, SEEK_CUR);
886 }
887
888 /* ===========================================================================
889 Returns 1 when EOF has previously been detected reading the given
890 input stream, otherwise zero.
891 */
892 int ZEXPORT gzeof (file)
893 gzFile file;
894 {
895 gz_stream *s = (gz_stream*)file;
896
897 /* With concatenated compressed files that can have embedded
898 * crc trailers, z_eof is no longer the only/best indicator of EOF
899 * on a gz_stream. Handle end-of-stream error explicitly here.
900 */
901 if (s == NULL || s->mode != 'r') return 0;
902 if (s->z_eof) return 1;
903 return s->z_err == Z_STREAM_END;
904 }
905
906 /* ===========================================================================
907 Outputs a long in LSB order to the given file
908 */
909 local void putLong (file, x)
910 FILE *file;
911 uLong x;
912 {
913 int n;
914 for (n = 0; n < 4; n++) {
915 fputc((int)(x & 0xff), file);
916 x >>= 8;
917 }
918 }
919
920 /* ===========================================================================
921 Reads a long in LSB order from the given gz_stream. Sets z_err in case
922 of error.
923 */
924 local uLong getLong (s)
925 gz_stream *s;
926 {
927 uLong x = (uLong)get_byte(s);
928 int c;
929
930 x += ((uLong)get_byte(s))<<8;
931 x += ((uLong)get_byte(s))<<16;
932 c = get_byte(s);
933 if (c == EOF) s->z_err = Z_DATA_ERROR;
934 x += ((uLong)c)<<24;
935 return x;
936 }
937
938 /* ===========================================================================
939 Flushes all pending output if necessary, closes the compressed file
940 and deallocates all the (de)compression state.
941 */
942 int ZEXPORT gzclose (file)
943 gzFile file;
944 {
945 gz_stream *s = (gz_stream*)file;
946
947 if (s == NULL) return Z_STREAM_ERROR;
948
949 if (s->mode == 'w') {
950 #ifdef NO_GZCOMPRESS
951 return Z_STREAM_ERROR;
952 #else
953 if (do_flush (file, Z_FINISH) != Z_OK)
954 return destroy((gz_stream*)file);
955
956 putLong (s->file, s->crc);
957 putLong (s->file, (uLong)(s->in & 0xffffffff));
958 #endif
959 }
960 return destroy((gz_stream*)file);
961 }
962
963 #ifdef STDC
964 # define zstrerror(errnum) strerror(errnum)
965 #else
966 # define zstrerror(errnum) ""
967 #endif
968
969 /* ===========================================================================
970 Returns the error message for the last error which occured on the
971 given compressed file. errnum is set to zlib error number. If an
972 error occured in the file system and not in the compression library,
973 errnum is set to Z_ERRNO and the application may consult errno
974 to get the exact error code.
975 */
976 const char * ZEXPORT gzerror (file, errnum)
977 gzFile file;
978 int *errnum;
979 {
980 char *m;
981 gz_stream *s = (gz_stream*)file;
982
983 if (s == NULL) {
984 *errnum = Z_STREAM_ERROR;
985 return (const char*)ERR_MSG(Z_STREAM_ERROR);
986 }
987 *errnum = s->z_err;
988 if (*errnum == Z_OK) return (const char*)"";
989
990 m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
991
992 if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
993
994 TRYFREE(s->msg);
995 s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
996 if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
997 strcpy(s->msg, s->path);
998 strcat(s->msg, ": ");
999 strcat(s->msg, m);
1000 return (const char*)s->msg;
1001 }
1002
1003 /* ===========================================================================
1004 Clear the error and end-of-file flags, and do the same for the real file.
1005 */
1006 void ZEXPORT gzclearerr (file)
1007 gzFile file;
1008 {
1009 gz_stream *s = (gz_stream*)file;
1010
1011 if (s == NULL) return;
1012 if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
1013 s->z_eof = 0;
1014 clearerr(s->file);
1015 }
0 /* infback.c -- inflate using a call-back interface
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 This code is largely copied from inflate.c. Normally either infback.o or
7 inflate.o would be linked into an application--not both. The interface
8 with inffast.c is retained so that optimized assembler-coded versions of
9 inflate_fast() can be used with either inflate.c or infback.c.
10 */
11
12 #include "zutil.h"
13 #include "inftrees.h"
14 #include "inflate.h"
15 #include "inffast.h"
16
17 /* function prototypes */
18 local void fixedtables OF((struct inflate_state FAR *state));
19
20 /*
21 strm provides memory allocation functions in zalloc and zfree, or
22 Z_NULL to use the library memory allocation functions.
23
24 windowBits is in the range 8..15, and window is a user-supplied
25 window and output buffer that is 2**windowBits bytes.
26 */
27 int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
28 z_streamp strm;
29 int windowBits;
30 unsigned char FAR *window;
31 const char *version;
32 int stream_size;
33 {
34 struct inflate_state FAR *state;
35
36 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
37 stream_size != (int)(sizeof(z_stream)))
38 return Z_VERSION_ERROR;
39 if (strm == Z_NULL || window == Z_NULL ||
40 windowBits < 8 || windowBits > 15)
41 return Z_STREAM_ERROR;
42 strm->msg = Z_NULL; /* in case we return an error */
43 if (strm->zalloc == (alloc_func)0) {
44 strm->zalloc = zcalloc;
45 strm->opaque = (voidpf)0;
46 }
47 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
48 state = (struct inflate_state FAR *)ZALLOC(strm, 1,
49 sizeof(struct inflate_state));
50 if (state == Z_NULL) return Z_MEM_ERROR;
51 Tracev((stderr, "inflate: allocated\n"));
52 strm->state = (voidpf)state;
53 state->dmax = 32768U;
54 state->wbits = windowBits;
55 state->wsize = 1U << windowBits;
56 state->window = window;
57 state->write = 0;
58 state->whave = 0;
59 return Z_OK;
60 }
61
62 /*
63 Return state with length and distance decoding tables and index sizes set to
64 fixed code decoding. Normally this returns fixed tables from inffixed.h.
65 If BUILDFIXED is defined, then instead this routine builds the tables the
66 first time it's called, and returns those tables the first time and
67 thereafter. This reduces the size of the code by about 2K bytes, in
68 exchange for a little execution time. However, BUILDFIXED should not be
69 used for threaded applications, since the rewriting of the tables and virgin
70 may not be thread-safe.
71 */
72 local void fixedtables(state)
73 struct inflate_state FAR *state;
74 {
75 #ifdef BUILDFIXED
76 static int virgin = 1;
77 static code *lenfix, *distfix;
78 static code fixed[544];
79
80 /* build fixed huffman tables if first call (may not be thread safe) */
81 if (virgin) {
82 unsigned sym, bits;
83 static code *next;
84
85 /* literal/length table */
86 sym = 0;
87 while (sym < 144) state->lens[sym++] = 8;
88 while (sym < 256) state->lens[sym++] = 9;
89 while (sym < 280) state->lens[sym++] = 7;
90 while (sym < 288) state->lens[sym++] = 8;
91 next = fixed;
92 lenfix = next;
93 bits = 9;
94 inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
95
96 /* distance table */
97 sym = 0;
98 while (sym < 32) state->lens[sym++] = 5;
99 distfix = next;
100 bits = 5;
101 inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
102
103 /* do this just once */
104 virgin = 0;
105 }
106 #else /* !BUILDFIXED */
107 # include "inffixed.h"
108 #endif /* BUILDFIXED */
109 state->lencode = lenfix;
110 state->lenbits = 9;
111 state->distcode = distfix;
112 state->distbits = 5;
113 }
114
115 /* Macros for inflateBack(): */
116
117 /* Load returned state from inflate_fast() */
118 #define LOAD() \
119 do { \
120 put = strm->next_out; \
121 left = strm->avail_out; \
122 next = strm->next_in; \
123 have = strm->avail_in; \
124 hold = state->hold; \
125 bits = state->bits; \
126 } while (0)
127
128 /* Set state from registers for inflate_fast() */
129 #define RESTORE() \
130 do { \
131 strm->next_out = put; \
132 strm->avail_out = left; \
133 strm->next_in = next; \
134 strm->avail_in = have; \
135 state->hold = hold; \
136 state->bits = bits; \
137 } while (0)
138
139 /* Clear the input bit accumulator */
140 #define INITBITS() \
141 do { \
142 hold = 0; \
143 bits = 0; \
144 } while (0)
145
146 /* Assure that some input is available. If input is requested, but denied,
147 then return a Z_BUF_ERROR from inflateBack(). */
148 #define PULL() \
149 do { \
150 if (have == 0) { \
151 have = in(in_desc, &next); \
152 if (have == 0) { \
153 next = Z_NULL; \
154 ret = Z_BUF_ERROR; \
155 goto inf_leave; \
156 } \
157 } \
158 } while (0)
159
160 /* Get a byte of input into the bit accumulator, or return from inflateBack()
161 with an error if there is no input available. */
162 #define PULLBYTE() \
163 do { \
164 PULL(); \
165 have--; \
166 hold += (unsigned long)(*next++) << bits; \
167 bits += 8; \
168 } while (0)
169
170 /* Assure that there are at least n bits in the bit accumulator. If there is
171 not enough available input to do that, then return from inflateBack() with
172 an error. */
173 #define NEEDBITS(n) \
174 do { \
175 while (bits < (unsigned)(n)) \
176 PULLBYTE(); \
177 } while (0)
178
179 /* Return the low n bits of the bit accumulator (n < 16) */
180 #define BITS(n) \
181 ((unsigned)hold & ((1U << (n)) - 1))
182
183 /* Remove n bits from the bit accumulator */
184 #define DROPBITS(n) \
185 do { \
186 hold >>= (n); \
187 bits -= (unsigned)(n); \
188 } while (0)
189
190 /* Remove zero to seven bits as needed to go to a byte boundary */
191 #define BYTEBITS() \
192 do { \
193 hold >>= bits & 7; \
194 bits -= bits & 7; \
195 } while (0)
196
197 /* Assure that some output space is available, by writing out the window
198 if it's full. If the write fails, return from inflateBack() with a
199 Z_BUF_ERROR. */
200 #define ROOM() \
201 do { \
202 if (left == 0) { \
203 put = state->window; \
204 left = state->wsize; \
205 state->whave = left; \
206 if (out(out_desc, put, left)) { \
207 ret = Z_BUF_ERROR; \
208 goto inf_leave; \
209 } \
210 } \
211 } while (0)
212
213 /*
214 strm provides the memory allocation functions and window buffer on input,
215 and provides information on the unused input on return. For Z_DATA_ERROR
216 returns, strm will also provide an error message.
217
218 in() and out() are the call-back input and output functions. When
219 inflateBack() needs more input, it calls in(). When inflateBack() has
220 filled the window with output, or when it completes with data in the
221 window, it calls out() to write out the data. The application must not
222 change the provided input until in() is called again or inflateBack()
223 returns. The application must not change the window/output buffer until
224 inflateBack() returns.
225
226 in() and out() are called with a descriptor parameter provided in the
227 inflateBack() call. This parameter can be a structure that provides the
228 information required to do the read or write, as well as accumulated
229 information on the input and output such as totals and check values.
230
231 in() should return zero on failure. out() should return non-zero on
232 failure. If either in() or out() fails, than inflateBack() returns a
233 Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
234 was in() or out() that caused in the error. Otherwise, inflateBack()
235 returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
236 error, or Z_MEM_ERROR if it could not allocate memory for the state.
237 inflateBack() can also return Z_STREAM_ERROR if the input parameters
238 are not correct, i.e. strm is Z_NULL or the state was not initialized.
239 */
240 int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
241 z_streamp strm;
242 in_func in;
243 void FAR *in_desc;
244 out_func out;
245 void FAR *out_desc;
246 {
247 struct inflate_state FAR *state;
248 unsigned char FAR *next; /* next input */
249 unsigned char FAR *put; /* next output */
250 unsigned have, left; /* available input and output */
251 unsigned long hold; /* bit buffer */
252 unsigned bits; /* bits in bit buffer */
253 unsigned copy; /* number of stored or match bytes to copy */
254 unsigned char FAR *from; /* where to copy match bytes from */
255 code this; /* current decoding table entry */
256 code last; /* parent table entry */
257 unsigned len; /* length to copy for repeats, bits to drop */
258 int ret; /* return code */
259 static const unsigned short order[19] = /* permutation of code lengths */
260 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
261
262 /* Check that the strm exists and that the state was initialized */
263 if (strm == Z_NULL || strm->state == Z_NULL)
264 return Z_STREAM_ERROR;
265 state = (struct inflate_state FAR *)strm->state;
266
267 /* Reset the state */
268 strm->msg = Z_NULL;
269 state->mode = TYPE;
270 state->last = 0;
271 state->whave = 0;
272 next = strm->next_in;
273 have = next != Z_NULL ? strm->avail_in : 0;
274 hold = 0;
275 bits = 0;
276 put = state->window;
277 left = state->wsize;
278
279 /* Inflate until end of block marked as last */
280 for (;;)
281 switch (state->mode) {
282 case TYPE:
283 /* determine and dispatch block type */
284 if (state->last) {
285 BYTEBITS();
286 state->mode = DONE;
287 break;
288 }
289 NEEDBITS(3);
290 state->last = BITS(1);
291 DROPBITS(1);
292 switch (BITS(2)) {
293 case 0: /* stored block */
294 Tracev((stderr, "inflate: stored block%s\n",
295 state->last ? " (last)" : ""));
296 state->mode = STORED;
297 break;
298 case 1: /* fixed block */
299 fixedtables(state);
300 Tracev((stderr, "inflate: fixed codes block%s\n",
301 state->last ? " (last)" : ""));
302 state->mode = LEN; /* decode codes */
303 break;
304 case 2: /* dynamic block */
305 Tracev((stderr, "inflate: dynamic codes block%s\n",
306 state->last ? " (last)" : ""));
307 state->mode = TABLE;
308 break;
309 case 3:
310 strm->msg = (char *)"invalid block type";
311 state->mode = BAD;
312 }
313 DROPBITS(2);
314 break;
315
316 case STORED:
317 /* get and verify stored block length */
318 BYTEBITS(); /* go to byte boundary */
319 NEEDBITS(32);
320 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
321 strm->msg = (char *)"invalid stored block lengths";
322 state->mode = BAD;
323 break;
324 }
325 state->length = (unsigned)hold & 0xffff;
326 Tracev((stderr, "inflate: stored length %u\n",
327 state->length));
328 INITBITS();
329
330 /* copy stored block from input to output */
331 while (state->length != 0) {
332 copy = state->length;
333 PULL();
334 ROOM();
335 if (copy > have) copy = have;
336 if (copy > left) copy = left;
337 zmemcpy(put, next, copy);
338 have -= copy;
339 next += copy;
340 left -= copy;
341 put += copy;
342 state->length -= copy;
343 }
344 Tracev((stderr, "inflate: stored end\n"));
345 state->mode = TYPE;
346 break;
347
348 case TABLE:
349 /* get dynamic table entries descriptor */
350 NEEDBITS(14);
351 state->nlen = BITS(5) + 257;
352 DROPBITS(5);
353 state->ndist = BITS(5) + 1;
354 DROPBITS(5);
355 state->ncode = BITS(4) + 4;
356 DROPBITS(4);
357 #ifndef PKZIP_BUG_WORKAROUND
358 if (state->nlen > 286 || state->ndist > 30) {
359 strm->msg = (char *)"too many length or distance symbols";
360 state->mode = BAD;
361 break;
362 }
363 #endif
364 Tracev((stderr, "inflate: table sizes ok\n"));
365
366 /* get code length code lengths (not a typo) */
367 state->have = 0;
368 while (state->have < state->ncode) {
369 NEEDBITS(3);
370 state->lens[order[state->have++]] = (unsigned short)BITS(3);
371 DROPBITS(3);
372 }
373 while (state->have < 19)
374 state->lens[order[state->have++]] = 0;
375 state->next = state->codes;
376 state->lencode = (code const FAR *)(state->next);
377 state->lenbits = 7;
378 ret = inflate_table(CODES, state->lens, 19, &(state->next),
379 &(state->lenbits), state->work);
380 if (ret) {
381 strm->msg = (char *)"invalid code lengths set";
382 state->mode = BAD;
383 break;
384 }
385 Tracev((stderr, "inflate: code lengths ok\n"));
386
387 /* get length and distance code code lengths */
388 state->have = 0;
389 while (state->have < state->nlen + state->ndist) {
390 for (;;) {
391 this = state->lencode[BITS(state->lenbits)];
392 if ((unsigned)(this.bits) <= bits) break;
393 PULLBYTE();
394 }
395 if (this.val < 16) {
396 NEEDBITS(this.bits);
397 DROPBITS(this.bits);
398 state->lens[state->have++] = this.val;
399 }
400 else {
401 if (this.val == 16) {
402 NEEDBITS(this.bits + 2);
403 DROPBITS(this.bits);
404 if (state->have == 0) {
405 strm->msg = (char *)"invalid bit length repeat";
406 state->mode = BAD;
407 break;
408 }
409 len = (unsigned)(state->lens[state->have - 1]);
410 copy = 3 + BITS(2);
411 DROPBITS(2);
412 }
413 else if (this.val == 17) {
414 NEEDBITS(this.bits + 3);
415 DROPBITS(this.bits);
416 len = 0;
417 copy = 3 + BITS(3);
418 DROPBITS(3);
419 }
420 else {
421 NEEDBITS(this.bits + 7);
422 DROPBITS(this.bits);
423 len = 0;
424 copy = 11 + BITS(7);
425 DROPBITS(7);
426 }
427 if (state->have + copy > state->nlen + state->ndist) {
428 strm->msg = (char *)"invalid bit length repeat";
429 state->mode = BAD;
430 break;
431 }
432 while (copy--)
433 state->lens[state->have++] = (unsigned short)len;
434 }
435 }
436
437 /* handle error breaks in while */
438 if (state->mode == BAD) break;
439
440 /* build code tables */
441 state->next = state->codes;
442 state->lencode = (code const FAR *)(state->next);
443 state->lenbits = 9;
444 ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
445 &(state->lenbits), state->work);
446 if (ret) {
447 strm->msg = (char *)"invalid literal/lengths set";
448 state->mode = BAD;
449 break;
450 }
451 state->distcode = (code const FAR *)(state->next);
452 state->distbits = 6;
453 ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
454 &(state->next), &(state->distbits), state->work);
455 if (ret) {
456 strm->msg = (char *)"invalid distances set";
457 state->mode = BAD;
458 break;
459 }
460 Tracev((stderr, "inflate: codes ok\n"));
461 state->mode = LEN;
462
463 case LEN:
464 /* use inflate_fast() if we have enough input and output */
465 if (have >= 6 && left >= 258) {
466 RESTORE();
467 if (state->whave < state->wsize)
468 state->whave = state->wsize - left;
469 inflate_fast(strm, state->wsize);
470 LOAD();
471 break;
472 }
473
474 /* get a literal, length, or end-of-block code */
475 for (;;) {
476 this = state->lencode[BITS(state->lenbits)];
477 if ((unsigned)(this.bits) <= bits) break;
478 PULLBYTE();
479 }
480 if (this.op && (this.op & 0xf0) == 0) {
481 last = this;
482 for (;;) {
483 this = state->lencode[last.val +
484 (BITS(last.bits + last.op) >> last.bits)];
485 if ((unsigned)(last.bits + this.bits) <= bits) break;
486 PULLBYTE();
487 }
488 DROPBITS(last.bits);
489 }
490 DROPBITS(this.bits);
491 state->length = (unsigned)this.val;
492
493 /* process literal */
494 if (this.op == 0) {
495 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
496 "inflate: literal '%c'\n" :
497 "inflate: literal 0x%02x\n", this.val));
498 ROOM();
499 *put++ = (unsigned char)(state->length);
500 left--;
501 state->mode = LEN;
502 break;
503 }
504
505 /* process end of block */
506 if (this.op & 32) {
507 Tracevv((stderr, "inflate: end of block\n"));
508 state->mode = TYPE;
509 break;
510 }
511
512 /* invalid code */
513 if (this.op & 64) {
514 strm->msg = (char *)"invalid literal/length code";
515 state->mode = BAD;
516 break;
517 }
518
519 /* length code -- get extra bits, if any */
520 state->extra = (unsigned)(this.op) & 15;
521 if (state->extra != 0) {
522 NEEDBITS(state->extra);
523 state->length += BITS(state->extra);
524 DROPBITS(state->extra);
525 }
526 Tracevv((stderr, "inflate: length %u\n", state->length));
527
528 /* get distance code */
529 for (;;) {
530 this = state->distcode[BITS(state->distbits)];
531 if ((unsigned)(this.bits) <= bits) break;
532 PULLBYTE();
533 }
534 if ((this.op & 0xf0) == 0) {
535 last = this;
536 for (;;) {
537 this = state->distcode[last.val +
538 (BITS(last.bits + last.op) >> last.bits)];
539 if ((unsigned)(last.bits + this.bits) <= bits) break;
540 PULLBYTE();
541 }
542 DROPBITS(last.bits);
543 }
544 DROPBITS(this.bits);
545 if (this.op & 64) {
546 strm->msg = (char *)"invalid distance code";
547 state->mode = BAD;
548 break;
549 }
550 state->offset = (unsigned)this.val;
551
552 /* get distance extra bits, if any */
553 state->extra = (unsigned)(this.op) & 15;
554 if (state->extra != 0) {
555 NEEDBITS(state->extra);
556 state->offset += BITS(state->extra);
557 DROPBITS(state->extra);
558 }
559 if (state->offset > state->wsize - (state->whave < state->wsize ?
560 left : 0)) {
561 strm->msg = (char *)"invalid distance too far back";
562 state->mode = BAD;
563 break;
564 }
565 Tracevv((stderr, "inflate: distance %u\n", state->offset));
566
567 /* copy match from window to output */
568 do {
569 ROOM();
570 copy = state->wsize - state->offset;
571 if (copy < left) {
572 from = put + copy;
573 copy = left - copy;
574 }
575 else {
576 from = put - state->offset;
577 copy = left;
578 }
579 if (copy > state->length) copy = state->length;
580 state->length -= copy;
581 left -= copy;
582 do {
583 *put++ = *from++;
584 } while (--copy);
585 } while (state->length != 0);
586 break;
587
588 case DONE:
589 /* inflate stream terminated properly -- write leftover output */
590 ret = Z_STREAM_END;
591 if (left < state->wsize) {
592 if (out(out_desc, state->window, state->wsize - left))
593 ret = Z_BUF_ERROR;
594 }
595 goto inf_leave;
596
597 case BAD:
598 ret = Z_DATA_ERROR;
599 goto inf_leave;
600
601 default: /* can't happen, but makes compilers happy */
602 ret = Z_STREAM_ERROR;
603 goto inf_leave;
604 }
605
606 /* Return unused input */
607 inf_leave:
608 strm->next_in = next;
609 strm->avail_in = have;
610 return ret;
611 }
612
613 int ZEXPORT inflateBackEnd(strm)
614 z_streamp strm;
615 {
616 if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
617 return Z_STREAM_ERROR;
618 ZFREE(strm, strm->state);
619 strm->state = Z_NULL;
620 Tracev((stderr, "inflate: end\n"));
621 return Z_OK;
622 }
0 /* inffast.c -- fast decoding
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 #include "zutil.h"
6 #include "inftrees.h"
7 #include "inflate.h"
8 #include "inffast.h"
9
10 #ifndef ASMINF
11
12 /* Allow machine dependent optimization for post-increment or pre-increment.
13 Based on testing to date,
14 Pre-increment preferred for:
15 - PowerPC G3 (Adler)
16 - MIPS R5000 (Randers-Pehrson)
17 Post-increment preferred for:
18 - none
19 No measurable difference:
20 - Pentium III (Anderson)
21 - M68060 (Nikl)
22 */
23 #ifdef POSTINC
24 # define OFF 0
25 # define PUP(a) *(a)++
26 #else
27 # define OFF 1
28 # define PUP(a) *++(a)
29 #endif
30
31 /*
32 Decode literal, length, and distance codes and write out the resulting
33 literal and match bytes until either not enough input or output is
34 available, an end-of-block is encountered, or a data error is encountered.
35 When large enough input and output buffers are supplied to inflate(), for
36 example, a 16K input buffer and a 64K output buffer, more than 95% of the
37 inflate execution time is spent in this routine.
38
39 Entry assumptions:
40
41 state->mode == LEN
42 strm->avail_in >= 6
43 strm->avail_out >= 258
44 start >= strm->avail_out
45 state->bits < 8
46
47 On return, state->mode is one of:
48
49 LEN -- ran out of enough output space or enough available input
50 TYPE -- reached end of block code, inflate() to interpret next block
51 BAD -- error in block data
52
53 Notes:
54
55 - The maximum input bits used by a length/distance pair is 15 bits for the
56 length code, 5 bits for the length extra, 15 bits for the distance code,
57 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
58 Therefore if strm->avail_in >= 6, then there is enough input to avoid
59 checking for available input while decoding.
60
61 - The maximum bytes that a single length/distance pair can output is 258
62 bytes, which is the maximum length that can be coded. inflate_fast()
63 requires strm->avail_out >= 258 for each loop to avoid checking for
64 output space.
65 */
66 void inflate_fast(strm, start)
67 z_streamp strm;
68 unsigned start; /* inflate()'s starting value for strm->avail_out */
69 {
70 struct inflate_state FAR *state;
71 unsigned char FAR *in; /* local strm->next_in */
72 unsigned char FAR *last; /* while in < last, enough input available */
73 unsigned char FAR *out; /* local strm->next_out */
74 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
75 unsigned char FAR *end; /* while out < end, enough space available */
76 #ifdef INFLATE_STRICT
77 unsigned dmax; /* maximum distance from zlib header */
78 #endif
79 unsigned wsize; /* window size or zero if not using window */
80 unsigned whave; /* valid bytes in the window */
81 unsigned write; /* window write index */
82 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
83 unsigned long hold; /* local strm->hold */
84 unsigned bits; /* local strm->bits */
85 code const FAR *lcode; /* local strm->lencode */
86 code const FAR *dcode; /* local strm->distcode */
87 unsigned lmask; /* mask for first level of length codes */
88 unsigned dmask; /* mask for first level of distance codes */
89 code this; /* retrieved table entry */
90 unsigned op; /* code bits, operation, extra bits, or */
91 /* window position, window bytes to copy */
92 unsigned len; /* match length, unused bytes */
93 unsigned dist; /* match distance */
94 unsigned char FAR *from; /* where to copy match from */
95
96 /* copy state to local variables */
97 state = (struct inflate_state FAR *)strm->state;
98 in = strm->next_in - OFF;
99 last = in + (strm->avail_in - 5);
100 out = strm->next_out - OFF;
101 beg = out - (start - strm->avail_out);
102 end = out + (strm->avail_out - 257);
103 #ifdef INFLATE_STRICT
104 dmax = state->dmax;
105 #endif
106 wsize = state->wsize;
107 whave = state->whave;
108 write = state->write;
109 window = state->window;
110 hold = state->hold;
111 bits = state->bits;
112 lcode = state->lencode;
113 dcode = state->distcode;
114 lmask = (1U << state->lenbits) - 1;
115 dmask = (1U << state->distbits) - 1;
116
117 /* decode literals and length/distances until end-of-block or not enough
118 input data or output space */
119 do {
120 if (bits < 15) {
121 hold += (unsigned long)(PUP(in)) << bits;
122 bits += 8;
123 hold += (unsigned long)(PUP(in)) << bits;
124 bits += 8;
125 }
126 this = lcode[hold & lmask];
127 dolen:
128 op = (unsigned)(this.bits);
129 hold >>= op;
130 bits -= op;
131 op = (unsigned)(this.op);
132 if (op == 0) { /* literal */
133 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
134 "inflate: literal '%c'\n" :
135 "inflate: literal 0x%02x\n", this.val));
136 PUP(out) = (unsigned char)(this.val);
137 }
138 else if (op & 16) { /* length base */
139 len = (unsigned)(this.val);
140 op &= 15; /* number of extra bits */
141 if (op) {
142 if (bits < op) {
143 hold += (unsigned long)(PUP(in)) << bits;
144 bits += 8;
145 }
146 len += (unsigned)hold & ((1U << op) - 1);
147 hold >>= op;
148 bits -= op;
149 }
150 Tracevv((stderr, "inflate: length %u\n", len));
151 if (bits < 15) {
152 hold += (unsigned long)(PUP(in)) << bits;
153 bits += 8;
154 hold += (unsigned long)(PUP(in)) << bits;
155 bits += 8;
156 }
157 this = dcode[hold & dmask];
158 dodist:
159 op = (unsigned)(this.bits);
160 hold >>= op;
161 bits -= op;
162 op = (unsigned)(this.op);
163 if (op & 16) { /* distance base */
164 dist = (unsigned)(this.val);
165 op &= 15; /* number of extra bits */
166 if (bits < op) {
167 hold += (unsigned long)(PUP(in)) << bits;
168 bits += 8;
169 if (bits < op) {
170 hold += (unsigned long)(PUP(in)) << bits;
171 bits += 8;
172 }
173 }
174 dist += (unsigned)hold & ((1U << op) - 1);
175 #ifdef INFLATE_STRICT
176 if (dist > dmax) {
177 strm->msg = (char *)"invalid distance too far back";
178 state->mode = BAD;
179 break;
180 }
181 #endif
182 hold >>= op;
183 bits -= op;
184 Tracevv((stderr, "inflate: distance %u\n", dist));
185 op = (unsigned)(out - beg); /* max distance in output */
186 if (dist > op) { /* see if copy from window */
187 op = dist - op; /* distance back in window */
188 if (op > whave) {
189 strm->msg = (char *)"invalid distance too far back";
190 state->mode = BAD;
191 break;
192 }
193 from = window - OFF;
194 if (write == 0) { /* very common case */
195 from += wsize - op;
196 if (op < len) { /* some from window */
197 len -= op;
198 do {
199 PUP(out) = PUP(from);
200 } while (--op);
201 from = out - dist; /* rest from output */
202 }
203 }
204 else if (write < op) { /* wrap around window */
205 from += wsize + write - op;
206 op -= write;
207 if (op < len) { /* some from end of window */
208 len -= op;
209 do {
210 PUP(out) = PUP(from);
211 } while (--op);
212 from = window - OFF;
213 if (write < len) { /* some from start of window */
214 op = write;
215 len -= op;
216 do {
217 PUP(out) = PUP(from);
218 } while (--op);
219 from = out - dist; /* rest from output */
220 }
221 }
222 }
223 else { /* contiguous in window */
224 from += write - op;
225 if (op < len) { /* some from window */
226 len -= op;
227 do {
228 PUP(out) = PUP(from);
229 } while (--op);
230 from = out - dist; /* rest from output */
231 }
232 }
233 while (len > 2) {
234 PUP(out) = PUP(from);
235 PUP(out) = PUP(from);
236 PUP(out) = PUP(from);
237 len -= 3;
238 }
239 if (len) {
240 PUP(out) = PUP(from);
241 if (len > 1)
242 PUP(out) = PUP(from);
243 }
244 }
245 else {
246 from = out - dist; /* copy direct from output */
247 do { /* minimum length is three */
248 PUP(out) = PUP(from);
249 PUP(out) = PUP(from);
250 PUP(out) = PUP(from);
251 len -= 3;
252 } while (len > 2);
253 if (len) {
254 PUP(out) = PUP(from);
255 if (len > 1)
256 PUP(out) = PUP(from);
257 }
258 }
259 }
260 else if ((op & 64) == 0) { /* 2nd level distance code */
261 this = dcode[this.val + (hold & ((1U << op) - 1))];
262 goto dodist;
263 }
264 else {
265 strm->msg = (char *)"invalid distance code";
266 state->mode = BAD;
267 break;
268 }
269 }
270 else if ((op & 64) == 0) { /* 2nd level length code */
271 this = lcode[this.val + (hold & ((1U << op) - 1))];
272 goto dolen;
273 }
274 else if (op & 32) { /* end-of-block */
275 Tracevv((stderr, "inflate: end of block\n"));
276 state->mode = TYPE;
277 break;
278 }
279 else {
280 strm->msg = (char *)"invalid literal/length code";
281 state->mode = BAD;
282 break;
283 }
284 } while (in < last && out < end);
285
286 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
287 len = bits >> 3;
288 in -= len;
289 bits -= len << 3;
290 hold &= (1U << bits) - 1;
291
292 /* update state and return */
293 strm->next_in = in + OFF;
294 strm->next_out = out + OFF;
295 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
296 strm->avail_out = (unsigned)(out < end ?
297 257 + (end - out) : 257 - (out - end));
298 state->hold = hold;
299 state->bits = bits;
300 return;
301 }
302
303 /*
304 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
305 - Using bit fields for code structure
306 - Different op definition to avoid & for extra bits (do & for table bits)
307 - Three separate decoding do-loops for direct, window, and write == 0
308 - Special case for distance > 1 copies to do overlapped load and store copy
309 - Explicit branch predictions (based on measured branch probabilities)
310 - Deferring match copy and interspersed it with decoding subsequent codes
311 - Swapping literal/length else
312 - Swapping window/direct else
313 - Larger unrolled copy loops (three is about right)
314 - Moving len -= 3 statement into middle of loop
315 */
316
317 #endif /* !ASMINF */
0 /* inffast.h -- header to use inffast.c
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 void inflate_fast OF((z_streamp strm, unsigned start));
0 /* inffixed.h -- table for decoding fixed codes
1 * Generated automatically by makefixed().
2 */
3
4 /* WARNING: this file should *not* be used by applications. It
5 is part of the implementation of the compression library and
6 is subject to change. Applications should only use zlib.h.
7 */
8
9 static const code lenfix[512] = {
10 {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
11 {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
12 {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
13 {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
14 {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
15 {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
16 {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
17 {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
18 {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
19 {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
20 {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
21 {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
22 {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
23 {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
24 {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
25 {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
26 {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
27 {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
28 {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
29 {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
30 {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
31 {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
32 {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
33 {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
34 {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
35 {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
36 {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
37 {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
38 {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
39 {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
40 {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
41 {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
42 {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
43 {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
44 {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
45 {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
46 {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
47 {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
48 {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
49 {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
50 {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
51 {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
52 {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
53 {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
54 {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
55 {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
56 {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
57 {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
58 {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
59 {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
60 {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
61 {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
62 {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
63 {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
64 {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
65 {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
66 {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
67 {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
68 {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
69 {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
70 {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
71 {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
72 {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
73 {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
74 {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
75 {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
76 {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
77 {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
78 {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
79 {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
80 {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
81 {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
82 {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
83 {0,9,255}
84 };
85
86 static const code distfix[32] = {
87 {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
88 {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
89 {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
90 {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
91 {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
92 {22,5,193},{64,5,0}
93 };
0 /* inflate.c -- zlib decompression
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 * Change history:
7 *
8 * 1.2.beta0 24 Nov 2002
9 * - First version -- complete rewrite of inflate to simplify code, avoid
10 * creation of window when not needed, minimize use of window when it is
11 * needed, make inffast.c even faster, implement gzip decoding, and to
12 * improve code readability and style over the previous zlib inflate code
13 *
14 * 1.2.beta1 25 Nov 2002
15 * - Use pointers for available input and output checking in inffast.c
16 * - Remove input and output counters in inffast.c
17 * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
18 * - Remove unnecessary second byte pull from length extra in inffast.c
19 * - Unroll direct copy to three copies per loop in inffast.c
20 *
21 * 1.2.beta2 4 Dec 2002
22 * - Change external routine names to reduce potential conflicts
23 * - Correct filename to inffixed.h for fixed tables in inflate.c
24 * - Make hbuf[] unsigned char to match parameter type in inflate.c
25 * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
26 * to avoid negation problem on Alphas (64 bit) in inflate.c
27 *
28 * 1.2.beta3 22 Dec 2002
29 * - Add comments on state->bits assertion in inffast.c
30 * - Add comments on op field in inftrees.h
31 * - Fix bug in reuse of allocated window after inflateReset()
32 * - Remove bit fields--back to byte structure for speed
33 * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
34 * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
35 * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
36 * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
37 * - Use local copies of stream next and avail values, as well as local bit
38 * buffer and bit count in inflate()--for speed when inflate_fast() not used
39 *
40 * 1.2.beta4 1 Jan 2003
41 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
42 * - Move a comment on output buffer sizes from inffast.c to inflate.c
43 * - Add comments in inffast.c to introduce the inflate_fast() routine
44 * - Rearrange window copies in inflate_fast() for speed and simplification
45 * - Unroll last copy for window match in inflate_fast()
46 * - Use local copies of window variables in inflate_fast() for speed
47 * - Pull out common write == 0 case for speed in inflate_fast()
48 * - Make op and len in inflate_fast() unsigned for consistency
49 * - Add FAR to lcode and dcode declarations in inflate_fast()
50 * - Simplified bad distance check in inflate_fast()
51 * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
52 * source file infback.c to provide a call-back interface to inflate for
53 * programs like gzip and unzip -- uses window as output buffer to avoid
54 * window copying
55 *
56 * 1.2.beta5 1 Jan 2003
57 * - Improved inflateBack() interface to allow the caller to provide initial
58 * input in strm.
59 * - Fixed stored blocks bug in inflateBack()
60 *
61 * 1.2.beta6 4 Jan 2003
62 * - Added comments in inffast.c on effectiveness of POSTINC
63 * - Typecasting all around to reduce compiler warnings
64 * - Changed loops from while (1) or do {} while (1) to for (;;), again to
65 * make compilers happy
66 * - Changed type of window in inflateBackInit() to unsigned char *
67 *
68 * 1.2.beta7 27 Jan 2003
69 * - Changed many types to unsigned or unsigned short to avoid warnings
70 * - Added inflateCopy() function
71 *
72 * 1.2.0 9 Mar 2003
73 * - Changed inflateBack() interface to provide separate opaque descriptors
74 * for the in() and out() functions
75 * - Changed inflateBack() argument and in_func typedef to swap the length
76 * and buffer address return values for the input function
77 * - Check next_in and next_out for Z_NULL on entry to inflate()
78 *
79 * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
80 */
81
82 #include "zutil.h"
83 #include "inftrees.h"
84 #include "inflate.h"
85 #include "inffast.h"
86
87 #ifdef MAKEFIXED
88 # ifndef BUILDFIXED
89 # define BUILDFIXED
90 # endif
91 #endif
92
93 /* function prototypes */
94 local void fixedtables OF((struct inflate_state FAR *state));
95 local int updatewindow OF((z_streamp strm, unsigned out));
96 #ifdef BUILDFIXED
97 void makefixed OF((void));
98 #endif
99 local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
100 unsigned len));
101
102 int ZEXPORT inflateReset(strm)
103 z_streamp strm;
104 {
105 struct inflate_state FAR *state;
106
107 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
108 state = (struct inflate_state FAR *)strm->state;
109 strm->total_in = strm->total_out = state->total = 0;
110 strm->msg = Z_NULL;
111 strm->adler = 1; /* to support ill-conceived Java test suite */
112 state->mode = HEAD;
113 state->last = 0;
114 state->havedict = 0;
115 state->dmax = 32768U;
116 state->head = Z_NULL;
117 state->wsize = 0;
118 state->whave = 0;
119 state->hold = 0;
120 state->bits = 0;
121 state->lencode = state->distcode = state->next = state->codes;
122 Tracev((stderr, "inflate: reset\n"));
123 return Z_OK;
124 }
125
126 int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
127 z_streamp strm;
128 int windowBits;
129 const char *version;
130 int stream_size;
131 {
132 struct inflate_state FAR *state;
133
134 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
135 stream_size != (int)(sizeof(z_stream)))
136 return Z_VERSION_ERROR;
137 if (strm == Z_NULL) return Z_STREAM_ERROR;
138 strm->msg = Z_NULL; /* in case we return an error */
139 if (strm->zalloc == (alloc_func)0) {
140 strm->zalloc = zcalloc;
141 strm->opaque = (voidpf)0;
142 }
143 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
144 state = (struct inflate_state FAR *)
145 ZALLOC(strm, 1, sizeof(struct inflate_state));
146 if (state == Z_NULL) return Z_MEM_ERROR;
147 Tracev((stderr, "inflate: allocated\n"));
148 strm->state = (voidpf)state;
149 if (windowBits < 0) {
150 state->wrap = 0;
151 windowBits = -windowBits;
152 }
153 else {
154 state->wrap = (windowBits >> 4) + 1;
155 #ifdef GUNZIP
156 if (windowBits < 48) windowBits &= 15;
157 #endif
158 }
159 if (windowBits < 8 || windowBits > 15) {
160 ZFREE(strm, state);
161 strm->state = Z_NULL;
162 return Z_STREAM_ERROR;
163 }
164 state->wbits = (unsigned)windowBits;
165 state->window = Z_NULL;
166 return inflateReset(strm);
167 }
168
169 int ZEXPORT inflateInit_(strm, version, stream_size)
170 z_streamp strm;
171 const char *version;
172 int stream_size;
173 {
174 return inflateInit2_(strm, DEF_WBITS, version, stream_size);
175 }
176
177 /*
178 Return state with length and distance decoding tables and index sizes set to
179 fixed code decoding. Normally this returns fixed tables from inffixed.h.
180 If BUILDFIXED is defined, then instead this routine builds the tables the
181 first time it's called, and returns those tables the first time and
182 thereafter. This reduces the size of the code by about 2K bytes, in
183 exchange for a little execution time. However, BUILDFIXED should not be
184 used for threaded applications, since the rewriting of the tables and virgin
185 may not be thread-safe.
186 */
187 local void fixedtables(state)
188 struct inflate_state FAR *state;
189 {
190 #ifdef BUILDFIXED
191 static int virgin = 1;
192 static code *lenfix, *distfix;
193 static code fixed[544];
194
195 /* build fixed huffman tables if first call (may not be thread safe) */
196 if (virgin) {
197 unsigned sym, bits;
198 static code *next;
199
200 /* literal/length table */
201 sym = 0;
202 while (sym < 144) state->lens[sym++] = 8;
203 while (sym < 256) state->lens[sym++] = 9;
204 while (sym < 280) state->lens[sym++] = 7;
205 while (sym < 288) state->lens[sym++] = 8;
206 next = fixed;
207 lenfix = next;
208 bits = 9;
209 inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
210
211 /* distance table */
212 sym = 0;
213 while (sym < 32) state->lens[sym++] = 5;
214 distfix = next;
215 bits = 5;
216 inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
217
218 /* do this just once */
219 virgin = 0;
220 }
221 #else /* !BUILDFIXED */
222 # include "inffixed.h"
223 #endif /* BUILDFIXED */
224 state->lencode = lenfix;
225 state->lenbits = 9;
226 state->distcode = distfix;
227 state->distbits = 5;
228 }
229
230 #ifdef MAKEFIXED
231 #include <stdio.h>
232
233 /*
234 Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
235 defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
236 those tables to stdout, which would be piped to inffixed.h. A small program
237 can simply call makefixed to do this:
238
239 void makefixed(void);
240
241 int main(void)
242 {
243 makefixed();
244 return 0;
245 }
246
247 Then that can be linked with zlib built with MAKEFIXED defined and run:
248
249 a.out > inffixed.h
250 */
251 void makefixed()
252 {
253 unsigned low, size;
254 struct inflate_state state;
255
256 fixedtables(&state);
257 puts(" /* inffixed.h -- table for decoding fixed codes");
258 puts(" * Generated automatically by makefixed().");
259 puts(" */");
260 puts("");
261 puts(" /* WARNING: this file should *not* be used by applications.");
262 puts(" It is part of the implementation of this library and is");
263 puts(" subject to change. Applications should only use zlib.h.");
264 puts(" */");
265 puts("");
266 size = 1U << 9;
267 printf(" static const code lenfix[%u] = {", size);
268 low = 0;
269 for (;;) {
270 if ((low % 7) == 0) printf("\n ");
271 printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
272 state.lencode[low].val);
273 if (++low == size) break;
274 putchar(',');
275 }
276 puts("\n };");
277 size = 1U << 5;
278 printf("\n static const code distfix[%u] = {", size);
279 low = 0;
280 for (;;) {
281 if ((low % 6) == 0) printf("\n ");
282 printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
283 state.distcode[low].val);
284 if (++low == size) break;
285 putchar(',');
286 }
287 puts("\n };");
288 }
289 #endif /* MAKEFIXED */
290
291 /*
292 Update the window with the last wsize (normally 32K) bytes written before
293 returning. If window does not exist yet, create it. This is only called
294 when a window is already in use, or when output has been written during this
295 inflate call, but the end of the deflate stream has not been reached yet.
296 It is also called to create a window for dictionary data when a dictionary
297 is loaded.
298
299 Providing output buffers larger than 32K to inflate() should provide a speed
300 advantage, since only the last 32K of output is copied to the sliding window
301 upon return from inflate(), and since all distances after the first 32K of
302 output will fall in the output data, making match copies simpler and faster.
303 The advantage may be dependent on the size of the processor's data caches.
304 */
305 local int updatewindow(strm, out)
306 z_streamp strm;
307 unsigned out;
308 {
309 struct inflate_state FAR *state;
310 unsigned copy, dist;
311
312 state = (struct inflate_state FAR *)strm->state;
313
314 /* if it hasn't been done already, allocate space for the window */
315 if (state->window == Z_NULL) {
316 state->window = (unsigned char FAR *)
317 ZALLOC(strm, 1U << state->wbits,
318 sizeof(unsigned char));
319 if (state->window == Z_NULL) return 1;
320 }
321
322 /* if window not in use yet, initialize */
323 if (state->wsize == 0) {
324 state->wsize = 1U << state->wbits;
325 state->write = 0;
326 state->whave = 0;
327 }
328
329 /* copy state->wsize or less output bytes into the circular window */
330 copy = out - strm->avail_out;
331 if (copy >= state->wsize) {
332 zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
333 state->write = 0;
334 state->whave = state->wsize;
335 }
336 else {
337 dist = state->wsize - state->write;
338 if (dist > copy) dist = copy;
339 zmemcpy(state->window + state->write, strm->next_out - copy, dist);
340 copy -= dist;
341 if (copy) {
342 zmemcpy(state->window, strm->next_out - copy, copy);
343 state->write = copy;
344 state->whave = state->wsize;
345 }
346 else {
347 state->write += dist;
348 if (state->write == state->wsize) state->write = 0;
349 if (state->whave < state->wsize) state->whave += dist;
350 }
351 }
352 return 0;
353 }
354
355 /* Macros for inflate(): */
356
357 /* check function to use adler32() for zlib or crc32() for gzip */
358 #ifdef GUNZIP
359 # define UPDATE(check, buf, len) \
360 (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
361 #else
362 # define UPDATE(check, buf, len) adler32(check, buf, len)
363 #endif
364
365 /* check macros for header crc */
366 #ifdef GUNZIP
367 # define CRC2(check, word) \
368 do { \
369 hbuf[0] = (unsigned char)(word); \
370 hbuf[1] = (unsigned char)((word) >> 8); \
371 check = crc32(check, hbuf, 2); \
372 } while (0)
373
374 # define CRC4(check, word) \
375 do { \
376 hbuf[0] = (unsigned char)(word); \
377 hbuf[1] = (unsigned char)((word) >> 8); \
378 hbuf[2] = (unsigned char)((word) >> 16); \
379 hbuf[3] = (unsigned char)((word) >> 24); \
380 check = crc32(check, hbuf, 4); \
381 } while (0)
382 #endif
383
384 /* Load registers with state in inflate() for speed */
385 #define LOAD() \
386 do { \
387 put = strm->next_out; \
388 left = strm->avail_out; \
389 next = strm->next_in; \
390 have = strm->avail_in; \
391 hold = state->hold; \
392 bits = state->bits; \
393 } while (0)
394
395 /* Restore state from registers in inflate() */
396 #define RESTORE() \
397 do { \
398 strm->next_out = put; \
399 strm->avail_out = left; \
400 strm->next_in = next; \
401 strm->avail_in = have; \
402 state->hold = hold; \
403 state->bits = bits; \
404 } while (0)
405
406 /* Clear the input bit accumulator */
407 #define INITBITS() \
408 do { \
409 hold = 0; \
410 bits = 0; \
411 } while (0)
412
413 /* Get a byte of input into the bit accumulator, or return from inflate()
414 if there is no input available. */
415 #define PULLBYTE() \
416 do { \
417 if (have == 0) goto inf_leave; \
418 have--; \
419 hold += (unsigned long)(*next++) << bits; \
420 bits += 8; \
421 } while (0)
422
423 /* Assure that there are at least n bits in the bit accumulator. If there is
424 not enough available input to do that, then return from inflate(). */
425 #define NEEDBITS(n) \
426 do { \
427 while (bits < (unsigned)(n)) \
428 PULLBYTE(); \
429 } while (0)
430
431 /* Return the low n bits of the bit accumulator (n < 16) */
432 #define BITS(n) \
433 ((unsigned)hold & ((1U << (n)) - 1))
434
435 /* Remove n bits from the bit accumulator */
436 #define DROPBITS(n) \
437 do { \
438 hold >>= (n); \
439 bits -= (unsigned)(n); \
440 } while (0)
441
442 /* Remove zero to seven bits as needed to go to a byte boundary */
443 #define BYTEBITS() \
444 do { \
445 hold >>= bits & 7; \
446 bits -= bits & 7; \
447 } while (0)
448
449 /* Reverse the bytes in a 32-bit value */
450 #define REVERSE(q) \
451 ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
452 (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
453
454 /*
455 inflate() uses a state machine to process as much input data and generate as
456 much output data as possible before returning. The state machine is
457 structured roughly as follows:
458
459 for (;;) switch (state) {
460 ...
461 case STATEn:
462 if (not enough input data or output space to make progress)
463 return;
464 ... make progress ...
465 state = STATEm;
466 break;
467 ...
468 }
469
470 so when inflate() is called again, the same case is attempted again, and
471 if the appropriate resources are provided, the machine proceeds to the
472 next state. The NEEDBITS() macro is usually the way the state evaluates
473 whether it can proceed or should return. NEEDBITS() does the return if
474 the requested bits are not available. The typical use of the BITS macros
475 is:
476
477 NEEDBITS(n);
478 ... do something with BITS(n) ...
479 DROPBITS(n);
480
481 where NEEDBITS(n) either returns from inflate() if there isn't enough
482 input left to load n bits into the accumulator, or it continues. BITS(n)
483 gives the low n bits in the accumulator. When done, DROPBITS(n) drops
484 the low n bits off the accumulator. INITBITS() clears the accumulator
485 and sets the number of available bits to zero. BYTEBITS() discards just
486 enough bits to put the accumulator on a byte boundary. After BYTEBITS()
487 and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
488
489 NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
490 if there is no input available. The decoding of variable length codes uses
491 PULLBYTE() directly in order to pull just enough bytes to decode the next
492 code, and no more.
493
494 Some states loop until they get enough input, making sure that enough
495 state information is maintained to continue the loop where it left off
496 if NEEDBITS() returns in the loop. For example, want, need, and keep
497 would all have to actually be part of the saved state in case NEEDBITS()
498 returns:
499
500 case STATEw:
501 while (want < need) {
502 NEEDBITS(n);
503 keep[want++] = BITS(n);
504 DROPBITS(n);
505 }
506 state = STATEx;
507 case STATEx:
508
509 As shown above, if the next state is also the next case, then the break
510 is omitted.
511
512 A state may also return if there is not enough output space available to
513 complete that state. Those states are copying stored data, writing a
514 literal byte, and copying a matching string.
515
516 When returning, a "goto inf_leave" is used to update the total counters,
517 update the check value, and determine whether any progress has been made
518 during that inflate() call in order to return the proper return code.
519 Progress is defined as a change in either strm->avail_in or strm->avail_out.
520 When there is a window, goto inf_leave will update the window with the last
521 output written. If a goto inf_leave occurs in the middle of decompression
522 and there is no window currently, goto inf_leave will create one and copy
523 output to the window for the next call of inflate().
524
525 In this implementation, the flush parameter of inflate() only affects the
526 return code (per zlib.h). inflate() always writes as much as possible to
527 strm->next_out, given the space available and the provided input--the effect
528 documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
529 the allocation of and copying into a sliding window until necessary, which
530 provides the effect documented in zlib.h for Z_FINISH when the entire input
531 stream available. So the only thing the flush parameter actually does is:
532 when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
533 will return Z_BUF_ERROR if it has not reached the end of the stream.
534 */
535
536 int ZEXPORT inflate(strm, flush)
537 z_streamp strm;
538 int flush;
539 {
540 struct inflate_state FAR *state;
541 unsigned char FAR *next; /* next input */
542 unsigned char FAR *put; /* next output */
543 unsigned have, left; /* available input and output */
544 unsigned long hold; /* bit buffer */
545 unsigned bits; /* bits in bit buffer */
546 unsigned in, out; /* save starting available input and output */
547 unsigned copy; /* number of stored or match bytes to copy */
548 unsigned char FAR *from; /* where to copy match bytes from */
549 code this; /* current decoding table entry */
550 code last; /* parent table entry */
551 unsigned len; /* length to copy for repeats, bits to drop */
552 int ret; /* return code */
553 #ifdef GUNZIP
554 unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
555 #endif
556 static const unsigned short order[19] = /* permutation of code lengths */
557 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
558
559 if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
560 (strm->next_in == Z_NULL && strm->avail_in != 0))
561 return Z_STREAM_ERROR;
562
563 state = (struct inflate_state FAR *)strm->state;
564 if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
565 LOAD();
566 in = have;
567 out = left;
568 ret = Z_OK;
569 for (;;)
570 switch (state->mode) {
571 case HEAD:
572 if (state->wrap == 0) {
573 state->mode = TYPEDO;
574 break;
575 }
576 NEEDBITS(16);
577 #ifdef GUNZIP
578 if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
579 state->check = crc32(0L, Z_NULL, 0);
580 CRC2(state->check, hold);
581 INITBITS();
582 state->mode = FLAGS;
583 break;
584 }
585 state->flags = 0; /* expect zlib header */
586 if (state->head != Z_NULL)
587 state->head->done = -1;
588 if (!(state->wrap & 1) || /* check if zlib header allowed */
589 #else
590 if (
591 #endif
592 ((BITS(8) << 8) + (hold >> 8)) % 31) {
593 strm->msg = (char *)"incorrect header check";
594 state->mode = BAD;
595 break;
596 }
597 if (BITS(4) != Z_DEFLATED) {
598 strm->msg = (char *)"unknown compression method";
599 state->mode = BAD;
600 break;
601 }
602 DROPBITS(4);
603 len = BITS(4) + 8;
604 if (len > state->wbits) {
605 strm->msg = (char *)"invalid window size";
606 state->mode = BAD;
607 break;
608 }
609 state->dmax = 1U << len;
610 Tracev((stderr, "inflate: zlib header ok\n"));
611 strm->adler = state->check = adler32(0L, Z_NULL, 0);
612 state->mode = hold & 0x200 ? DICTID : TYPE;
613 INITBITS();
614 break;
615 #ifdef GUNZIP
616 case FLAGS:
617 NEEDBITS(16);
618 state->flags = (int)(hold);
619 if ((state->flags & 0xff) != Z_DEFLATED) {
620 strm->msg = (char *)"unknown compression method";
621 state->mode = BAD;
622 break;
623 }
624 if (state->flags & 0xe000) {
625 strm->msg = (char *)"unknown header flags set";
626 state->mode = BAD;
627 break;
628 }
629 if (state->head != Z_NULL)
630 state->head->text = (int)((hold >> 8) & 1);
631 if (state->flags & 0x0200) CRC2(state->check, hold);
632 INITBITS();
633 state->mode = TIME;
634 case TIME:
635 NEEDBITS(32);
636 if (state->head != Z_NULL)
637 state->head->time = hold;
638 if (state->flags & 0x0200) CRC4(state->check, hold);
639 INITBITS();
640 state->mode = OS;
641 case OS:
642 NEEDBITS(16);
643 if (state->head != Z_NULL) {
644 state->head->xflags = (int)(hold & 0xff);
645 state->head->os = (int)(hold >> 8);
646 }
647 if (state->flags & 0x0200) CRC2(state->check, hold);
648 INITBITS();
649 state->mode = EXLEN;
650 case EXLEN:
651 if (state->flags & 0x0400) {
652 NEEDBITS(16);
653 state->length = (unsigned)(hold);
654 if (state->head != Z_NULL)
655 state->head->extra_len = (unsigned)hold;
656 if (state->flags & 0x0200) CRC2(state->check, hold);
657 INITBITS();
658 }
659 else if (state->head != Z_NULL)
660 state->head->extra = Z_NULL;
661 state->mode = EXTRA;
662 case EXTRA:
663 if (state->flags & 0x0400) {
664 copy = state->length;
665 if (copy > have) copy = have;
666 if (copy) {
667 if (state->head != Z_NULL &&
668 state->head->extra != Z_NULL) {
669 len = state->head->extra_len - state->length;
670 zmemcpy(state->head->extra + len, next,
671 len + copy > state->head->extra_max ?
672 state->head->extra_max - len : copy);
673 }
674 if (state->flags & 0x0200)
675 state->check = crc32(state->check, next, copy);
676 have -= copy;
677 next += copy;
678 state->length -= copy;
679 }
680 if (state->length) goto inf_leave;
681 }
682 state->length = 0;
683 state->mode = NAME;
684 case NAME:
685 if (state->flags & 0x0800) {
686 if (have == 0) goto inf_leave;
687 copy = 0;
688 do {
689 len = (unsigned)(next[copy++]);
690 if (state->head != Z_NULL &&
691 state->head->name != Z_NULL &&
692 state->length < state->head->name_max)
693 state->head->name[state->length++] = len;
694 } while (len && copy < have);
695 if (state->flags & 0x0200)
696 state->check = crc32(state->check, next, copy);
697 have -= copy;
698 next += copy;
699 if (len) goto inf_leave;
700 }
701 else if (state->head != Z_NULL)
702 state->head->name = Z_NULL;
703 state->length = 0;
704 state->mode = COMMENT;
705 case COMMENT:
706 if (state->flags & 0x1000) {
707 if (have == 0) goto inf_leave;
708 copy = 0;
709 do {
710 len = (unsigned)(next[copy++]);
711 if (state->head != Z_NULL &&
712 state->head->comment != Z_NULL &&
713 state->length < state->head->comm_max)
714 state->head->comment[state->length++] = len;
715 } while (len && copy < have);
716 if (state->flags & 0x0200)
717 state->check = crc32(state->check, next, copy);
718 have -= copy;
719 next += copy;
720 if (len) goto inf_leave;
721 }
722 else if (state->head != Z_NULL)
723 state->head->comment = Z_NULL;
724 state->mode = HCRC;
725 case HCRC:
726 if (state->flags & 0x0200) {
727 NEEDBITS(16);
728 if (hold != (state->check & 0xffff)) {
729 strm->msg = (char *)"header crc mismatch";
730 state->mode = BAD;
731 break;
732 }
733 INITBITS();
734 }
735 if (state->head != Z_NULL) {
736 state->head->hcrc = (int)((state->flags >> 9) & 1);
737 state->head->done = 1;
738 }
739 strm->adler = state->check = crc32(0L, Z_NULL, 0);
740 state->mode = TYPE;
741 break;
742 #endif
743 case DICTID:
744 NEEDBITS(32);
745 strm->adler = state->check = REVERSE(hold);
746 INITBITS();
747 state->mode = DICT;
748 case DICT:
749 if (state->havedict == 0) {
750 RESTORE();
751 return Z_NEED_DICT;
752 }
753 strm->adler = state->check = adler32(0L, Z_NULL, 0);
754 state->mode = TYPE;
755 case TYPE:
756 if (flush == Z_BLOCK) goto inf_leave;
757 case TYPEDO:
758 if (state->last) {
759 BYTEBITS();
760 state->mode = CHECK;
761 break;
762 }
763 NEEDBITS(3);
764 state->last = BITS(1);
765 DROPBITS(1);
766 switch (BITS(2)) {
767 case 0: /* stored block */
768 Tracev((stderr, "inflate: stored block%s\n",
769 state->last ? " (last)" : ""));
770 state->mode = STORED;
771 break;
772 case 1: /* fixed block */
773 fixedtables(state);
774 Tracev((stderr, "inflate: fixed codes block%s\n",
775 state->last ? " (last)" : ""));
776 state->mode = LEN; /* decode codes */
777 break;
778 case 2: /* dynamic block */
779 Tracev((stderr, "inflate: dynamic codes block%s\n",
780 state->last ? " (last)" : ""));
781 state->mode = TABLE;
782 break;
783 case 3:
784 strm->msg = (char *)"invalid block type";
785 state->mode = BAD;
786 }
787 DROPBITS(2);
788 break;
789 case STORED:
790 BYTEBITS(); /* go to byte boundary */
791 NEEDBITS(32);
792 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
793 strm->msg = (char *)"invalid stored block lengths";
794 state->mode = BAD;
795 break;
796 }
797 state->length = (unsigned)hold & 0xffff;
798 Tracev((stderr, "inflate: stored length %u\n",
799 state->length));
800 INITBITS();
801 state->mode = COPY;
802 case COPY:
803 copy = state->length;
804 if (copy) {
805 if (copy > have) copy = have;
806 if (copy > left) copy = left;
807 if (copy == 0) goto inf_leave;
808 zmemcpy(put, next, copy);
809 have -= copy;
810 next += copy;
811 left -= copy;
812 put += copy;
813 state->length -= copy;
814 break;
815 }
816 Tracev((stderr, "inflate: stored end\n"));
817 state->mode = TYPE;
818 break;
819 case TABLE:
820 NEEDBITS(14);
821 state->nlen = BITS(5) + 257;
822 DROPBITS(5);
823 state->ndist = BITS(5) + 1;
824 DROPBITS(5);
825 state->ncode = BITS(4) + 4;
826 DROPBITS(4);
827 #ifndef PKZIP_BUG_WORKAROUND
828 if (state->nlen > 286 || state->ndist > 30) {
829 strm->msg = (char *)"too many length or distance symbols";
830 state->mode = BAD;
831 break;
832 }
833 #endif
834 Tracev((stderr, "inflate: table sizes ok\n"));
835 state->have = 0;
836 state->mode = LENLENS;
837 case LENLENS:
838 while (state->have < state->ncode) {
839 NEEDBITS(3);
840 state->lens[order[state->have++]] = (unsigned short)BITS(3);
841 DROPBITS(3);
842 }
843 while (state->have < 19)
844 state->lens[order[state->have++]] = 0;
845 state->next = state->codes;
846 state->lencode = (code const FAR *)(state->next);
847 state->lenbits = 7;
848 ret = inflate_table(CODES, state->lens, 19, &(state->next),
849 &(state->lenbits), state->work);
850 if (ret) {
851 strm->msg = (char *)"invalid code lengths set";
852 state->mode = BAD;
853 break;
854 }
855 Tracev((stderr, "inflate: code lengths ok\n"));
856 state->have = 0;
857 state->mode = CODELENS;
858 case CODELENS:
859 while (state->have < state->nlen + state->ndist) {
860 for (;;) {
861 this = state->lencode[BITS(state->lenbits)];
862 if ((unsigned)(this.bits) <= bits) break;
863 PULLBYTE();
864 }
865 if (this.val < 16) {
866 NEEDBITS(this.bits);
867 DROPBITS(this.bits);
868 state->lens[state->have++] = this.val;
869 }
870 else {
871 if (this.val == 16) {
872 NEEDBITS(this.bits + 2);
873 DROPBITS(this.bits);
874 if (state->have == 0) {
875 strm->msg = (char *)"invalid bit length repeat";
876 state->mode = BAD;
877 break;
878 }
879 len = state->lens[state->have - 1];
880 copy = 3 + BITS(2);
881 DROPBITS(2);
882 }
883 else if (this.val == 17) {
884 NEEDBITS(this.bits + 3);
885 DROPBITS(this.bits);
886 len = 0;
887 copy = 3 + BITS(3);
888 DROPBITS(3);
889 }
890 else {
891 NEEDBITS(this.bits + 7);
892 DROPBITS(this.bits);
893 len = 0;
894 copy = 11 + BITS(7);
895 DROPBITS(7);
896 }
897 if (state->have + copy > state->nlen + state->ndist) {
898 strm->msg = (char *)"invalid bit length repeat";
899 state->mode = BAD;
900 break;
901 }
902 while (copy--)
903 state->lens[state->have++] = (unsigned short)len;
904 }
905 }
906
907 /* handle error breaks in while */
908 if (state->mode == BAD) break;
909
910 /* build code tables */
911 state->next = state->codes;
912 state->lencode = (code const FAR *)(state->next);
913 state->lenbits = 9;
914 ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
915 &(state->lenbits), state->work);
916 if (ret) {
917 strm->msg = (char *)"invalid literal/lengths set";
918 state->mode = BAD;
919 break;
920 }
921 state->distcode = (code const FAR *)(state->next);
922 state->distbits = 6;
923 ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
924 &(state->next), &(state->distbits), state->work);
925 if (ret) {
926 strm->msg = (char *)"invalid distances set";
927 state->mode = BAD;
928 break;
929 }
930 Tracev((stderr, "inflate: codes ok\n"));
931 state->mode = LEN;
932 case LEN:
933 if (have >= 6 && left >= 258) {
934 RESTORE();
935 inflate_fast(strm, out);
936 LOAD();
937 break;
938 }
939 for (;;) {
940 this = state->lencode[BITS(state->lenbits)];
941 if ((unsigned)(this.bits) <= bits) break;
942 PULLBYTE();
943 }
944 if (this.op && (this.op & 0xf0) == 0) {
945 last = this;
946 for (;;) {
947 this = state->lencode[last.val +
948 (BITS(last.bits + last.op) >> last.bits)];
949 if ((unsigned)(last.bits + this.bits) <= bits) break;
950 PULLBYTE();
951 }
952 DROPBITS(last.bits);
953 }
954 DROPBITS(this.bits);
955 state->length = (unsigned)this.val;
956 if ((int)(this.op) == 0) {
957 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
958 "inflate: literal '%c'\n" :
959 "inflate: literal 0x%02x\n", this.val));
960 state->mode = LIT;
961 break;
962 }
963 if (this.op & 32) {
964 Tracevv((stderr, "inflate: end of block\n"));
965 state->mode = TYPE;
966 break;
967 }
968 if (this.op & 64) {
969 strm->msg = (char *)"invalid literal/length code";
970 state->mode = BAD;
971 break;
972 }
973 state->extra = (unsigned)(this.op) & 15;
974 state->mode = LENEXT;
975 case LENEXT:
976 if (state->extra) {
977 NEEDBITS(state->extra);
978 state->length += BITS(state->extra);
979 DROPBITS(state->extra);
980 }
981 Tracevv((stderr, "inflate: length %u\n", state->length));
982 state->mode = DIST;
983 case DIST:
984 for (;;) {
985 this = state->distcode[BITS(state->distbits)];
986 if ((unsigned)(this.bits) <= bits) break;
987 PULLBYTE();
988 }
989 if ((this.op & 0xf0) == 0) {
990 last = this;
991 for (;;) {
992 this = state->distcode[last.val +
993 (BITS(last.bits + last.op) >> last.bits)];
994 if ((unsigned)(last.bits + this.bits) <= bits) break;
995 PULLBYTE();
996 }
997 DROPBITS(last.bits);
998 }
999 DROPBITS(this.bits);
1000 if (this.op & 64) {
1001 strm->msg = (char *)"invalid distance code";
1002 state->mode = BAD;
1003 break;
1004 }
1005 state->offset = (unsigned)this.val;
1006 state->extra = (unsigned)(this.op) & 15;
1007 state->mode = DISTEXT;
1008 case DISTEXT:
1009 if (state->extra) {
1010 NEEDBITS(state->extra);
1011 state->offset += BITS(state->extra);
1012 DROPBITS(state->extra);
1013 }
1014 #ifdef INFLATE_STRICT
1015 if (state->offset > state->dmax) {
1016 strm->msg = (char *)"invalid distance too far back";
1017 state->mode = BAD;
1018 break;
1019 }
1020 #endif
1021 if (state->offset > state->whave + out - left) {
1022 strm->msg = (char *)"invalid distance too far back";
1023 state->mode = BAD;
1024 break;
1025 }
1026 Tracevv((stderr, "inflate: distance %u\n", state->offset));
1027 state->mode = MATCH;
1028 case MATCH:
1029 if (left == 0) goto inf_leave;
1030 copy = out - left;
1031 if (state->offset > copy) { /* copy from window */
1032 copy = state->offset - copy;
1033 if (copy > state->write) {
1034 copy -= state->write;
1035 from = state->window + (state->wsize - copy);
1036 }
1037 else
1038 from = state->window + (state->write - copy);
1039 if (copy > state->length) copy = state->length;
1040 }
1041 else { /* copy from output */
1042 from = put - state->offset;
1043 copy = state->length;
1044 }
1045 if (copy > left) copy = left;
1046 left -= copy;
1047 state->length -= copy;
1048 do {
1049 *put++ = *from++;
1050 } while (--copy);
1051 if (state->length == 0) state->mode = LEN;
1052 break;
1053 case LIT:
1054 if (left == 0) goto inf_leave;
1055 *put++ = (unsigned char)(state->length);
1056 left--;
1057 state->mode = LEN;
1058 break;
1059 case CHECK:
1060 if (state->wrap) {
1061 NEEDBITS(32);
1062 out -= left;
1063 strm->total_out += out;
1064 state->total += out;
1065 if (out)
1066 strm->adler = state->check =
1067 UPDATE(state->check, put - out, out);
1068 out = left;
1069 if ((
1070 #ifdef GUNZIP
1071 state->flags ? hold :
1072 #endif
1073 REVERSE(hold)) != state->check) {
1074 strm->msg = (char *)"incorrect data check";
1075 state->mode = BAD;
1076 break;
1077 }
1078 INITBITS();
1079 Tracev((stderr, "inflate: check matches trailer\n"));
1080 }
1081 #ifdef GUNZIP
1082 state->mode = LENGTH;
1083 case LENGTH:
1084 if (state->wrap && state->flags) {
1085 NEEDBITS(32);
1086 if (hold != (state->total & 0xffffffffUL)) {
1087 strm->msg = (char *)"incorrect length check";
1088 state->mode = BAD;
1089 break;
1090 }
1091 INITBITS();
1092 Tracev((stderr, "inflate: length matches trailer\n"));
1093 }
1094 #endif
1095 state->mode = DONE;
1096 case DONE:
1097 ret = Z_STREAM_END;
1098 goto inf_leave;
1099 case BAD:
1100 ret = Z_DATA_ERROR;
1101 goto inf_leave;
1102 case MEM:
1103 return Z_MEM_ERROR;
1104 case SYNC:
1105 default:
1106 return Z_STREAM_ERROR;
1107 }
1108
1109 /*
1110 Return from inflate(), updating the total counts and the check value.
1111 If there was no progress during the inflate() call, return a buffer
1112 error. Call updatewindow() to create and/or update the window state.
1113 Note: a memory error from inflate() is non-recoverable.
1114 */
1115 inf_leave:
1116 RESTORE();
1117 if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
1118 if (updatewindow(strm, out)) {
1119 state->mode = MEM;
1120 return Z_MEM_ERROR;
1121 }
1122 in -= strm->avail_in;
1123 out -= strm->avail_out;
1124 strm->total_in += in;
1125 strm->total_out += out;
1126 state->total += out;
1127 if (state->wrap && out)
1128 strm->adler = state->check =
1129 UPDATE(state->check, strm->next_out - out, out);
1130 strm->data_type = state->bits + (state->last ? 64 : 0) +
1131 (state->mode == TYPE ? 128 : 0);
1132 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1133 ret = Z_BUF_ERROR;
1134 return ret;
1135 }
1136
1137 int ZEXPORT inflateEnd(strm)
1138 z_streamp strm;
1139 {
1140 struct inflate_state FAR *state;
1141 if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
1142 return Z_STREAM_ERROR;
1143 state = (struct inflate_state FAR *)strm->state;
1144 if (state->window != Z_NULL) ZFREE(strm, state->window);
1145 ZFREE(strm, strm->state);
1146 strm->state = Z_NULL;
1147 Tracev((stderr, "inflate: end\n"));
1148 return Z_OK;
1149 }
1150
1151 int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
1152 z_streamp strm;
1153 const Bytef *dictionary;
1154 uInt dictLength;
1155 {
1156 struct inflate_state FAR *state;
1157 unsigned long id;
1158
1159 /* check state */
1160 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1161 state = (struct inflate_state FAR *)strm->state;
1162 if (state->wrap != 0 && state->mode != DICT)
1163 return Z_STREAM_ERROR;
1164
1165 /* check for correct dictionary id */
1166 if (state->mode == DICT) {
1167 id = adler32(0L, Z_NULL, 0);
1168 id = adler32(id, dictionary, dictLength);
1169 if (id != state->check)
1170 return Z_DATA_ERROR;
1171 }
1172
1173 /* copy dictionary to window */
1174 if (updatewindow(strm, strm->avail_out)) {
1175 state->mode = MEM;
1176 return Z_MEM_ERROR;
1177 }
1178 if (dictLength > state->wsize) {
1179 zmemcpy(state->window, dictionary + dictLength - state->wsize,
1180 state->wsize);
1181 state->whave = state->wsize;
1182 }
1183 else {
1184 zmemcpy(state->window + state->wsize - dictLength, dictionary,
1185 dictLength);
1186 state->whave = dictLength;
1187 }
1188 state->havedict = 1;
1189 Tracev((stderr, "inflate: dictionary set\n"));
1190 return Z_OK;
1191 }
1192
1193 int ZEXPORT inflateGetHeader(strm, head)
1194 z_streamp strm;
1195 gz_headerp head;
1196 {
1197 struct inflate_state FAR *state;
1198
1199 /* check state */
1200 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1201 state = (struct inflate_state FAR *)strm->state;
1202 if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
1203
1204 /* save header structure */
1205 state->head = head;
1206 head->done = 0;
1207 return Z_OK;
1208 }
1209
1210 /*
1211 Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
1212 or when out of input. When called, *have is the number of pattern bytes
1213 found in order so far, in 0..3. On return *have is updated to the new
1214 state. If on return *have equals four, then the pattern was found and the
1215 return value is how many bytes were read including the last byte of the
1216 pattern. If *have is less than four, then the pattern has not been found
1217 yet and the return value is len. In the latter case, syncsearch() can be
1218 called again with more data and the *have state. *have is initialized to
1219 zero for the first call.
1220 */
1221 local unsigned syncsearch(have, buf, len)
1222 unsigned FAR *have;
1223 unsigned char FAR *buf;
1224 unsigned len;
1225 {
1226 unsigned got;
1227 unsigned next;
1228
1229 got = *have;
1230 next = 0;
1231 while (next < len && got < 4) {
1232 if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
1233 got++;
1234 else if (buf[next])
1235 got = 0;
1236 else
1237 got = 4 - got;
1238 next++;
1239 }
1240 *have = got;
1241 return next;
1242 }
1243
1244 int ZEXPORT inflateSync(strm)
1245 z_streamp strm;
1246 {
1247 unsigned len; /* number of bytes to look at or looked at */
1248 unsigned long in, out; /* temporary to save total_in and total_out */
1249 unsigned char buf[4]; /* to restore bit buffer to byte string */
1250 struct inflate_state FAR *state;
1251
1252 /* check parameters */
1253 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1254 state = (struct inflate_state FAR *)strm->state;
1255 if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
1256
1257 /* if first time, start search in bit buffer */
1258 if (state->mode != SYNC) {
1259 state->mode = SYNC;
1260 state->hold <<= state->bits & 7;
1261 state->bits -= state->bits & 7;
1262 len = 0;
1263 while (state->bits >= 8) {
1264 buf[len++] = (unsigned char)(state->hold);
1265 state->hold >>= 8;
1266 state->bits -= 8;
1267 }
1268 state->have = 0;
1269 syncsearch(&(state->have), buf, len);
1270 }
1271
1272 /* search available input */
1273 len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
1274 strm->avail_in -= len;
1275 strm->next_in += len;
1276 strm->total_in += len;
1277
1278 /* return no joy or set up to restart inflate() on a new block */
1279 if (state->have != 4) return Z_DATA_ERROR;
1280 in = strm->total_in; out = strm->total_out;
1281 inflateReset(strm);
1282 strm->total_in = in; strm->total_out = out;
1283 state->mode = TYPE;
1284 return Z_OK;
1285 }
1286
1287 /*
1288 Returns true if inflate is currently at the end of a block generated by
1289 Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1290 implementation to provide an additional safety check. PPP uses
1291 Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1292 block. When decompressing, PPP checks that at the end of input packet,
1293 inflate is waiting for these length bytes.
1294 */
1295 int ZEXPORT inflateSyncPoint(strm)
1296 z_streamp strm;
1297 {
1298 struct inflate_state FAR *state;
1299
1300 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1301 state = (struct inflate_state FAR *)strm->state;
1302 return state->mode == STORED && state->bits == 0;
1303 }
1304
1305 int ZEXPORT inflateCopy(dest, source)
1306 z_streamp dest;
1307 z_streamp source;
1308 {
1309 struct inflate_state FAR *state;
1310 struct inflate_state FAR *copy;
1311 unsigned char FAR *window;
1312
1313 /* check input */
1314 if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
1315 source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
1316 return Z_STREAM_ERROR;
1317 state = (struct inflate_state FAR *)source->state;
1318
1319 /* allocate space */
1320 copy = (struct inflate_state FAR *)
1321 ZALLOC(source, 1, sizeof(struct inflate_state));
1322 if (copy == Z_NULL) return Z_MEM_ERROR;
1323 window = Z_NULL;
1324 if (state->window != Z_NULL) {
1325 window = (unsigned char FAR *)
1326 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1327 if (window == Z_NULL) {
1328 ZFREE(source, copy);
1329 return Z_MEM_ERROR;
1330 }
1331 }
1332
1333 /* copy state */
1334 zmemcpy(dest, source, sizeof(z_stream));
1335 zmemcpy(copy, state, sizeof(struct inflate_state));
1336 copy->lencode = copy->codes + (state->lencode - state->codes);
1337 copy->distcode = copy->codes + (state->distcode - state->codes);
1338 copy->next = copy->codes + (state->next - state->codes);
1339 if (window != Z_NULL)
1340 zmemcpy(window, state->window, 1U << state->wbits);
1341 copy->window = window;
1342 dest->state = (voidpf)copy;
1343 return Z_OK;
1344 }
0 /* inflate.h -- internal inflate state definition
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* define NO_GZIP when compiling if you want to disable gzip header and
11 trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
12 the crc code when it is not needed. For shared libraries, gzip decoding
13 should be left enabled. */
14 #ifndef NO_GZIP
15 # define GUNZIP
16 #endif
17
18 /* Possible inflate modes between inflate() calls */
19 typedef enum {
20 HEAD, /* i: waiting for magic header */
21 FLAGS, /* i: waiting for method and flags (gzip) */
22 TIME, /* i: waiting for modification time (gzip) */
23 OS, /* i: waiting for extra flags and operating system (gzip) */
24 EXLEN, /* i: waiting for extra length (gzip) */
25 EXTRA, /* i: waiting for extra bytes (gzip) */
26 NAME, /* i: waiting for end of file name (gzip) */
27 COMMENT, /* i: waiting for end of comment (gzip) */
28 HCRC, /* i: waiting for header crc (gzip) */
29 DICTID, /* i: waiting for dictionary check value */
30 DICT, /* waiting for inflateSetDictionary() call */
31 TYPE, /* i: waiting for type bits, including last-flag bit */
32 TYPEDO, /* i: same, but skip check to exit inflate on new block */
33 STORED, /* i: waiting for stored size (length and complement) */
34 COPY, /* i/o: waiting for input or output to copy stored block */
35 TABLE, /* i: waiting for dynamic block table lengths */
36 LENLENS, /* i: waiting for code length code lengths */
37 CODELENS, /* i: waiting for length/lit and distance code lengths */
38 LEN, /* i: waiting for length/lit code */
39 LENEXT, /* i: waiting for length extra bits */
40 DIST, /* i: waiting for distance code */
41 DISTEXT, /* i: waiting for distance extra bits */
42 MATCH, /* o: waiting for output space to copy string */
43 LIT, /* o: waiting for output space to write literal */
44 CHECK, /* i: waiting for 32-bit check value */
45 LENGTH, /* i: waiting for 32-bit length (gzip) */
46 DONE, /* finished check, done -- remain here until reset */
47 BAD, /* got a data error -- remain here until reset */
48 MEM, /* got an inflate() memory error -- remain here until reset */
49 SYNC /* looking for synchronization bytes to restart inflate() */
50 } inflate_mode;
51
52 /*
53 State transitions between above modes -
54
55 (most modes can go to the BAD or MEM mode -- not shown for clarity)
56
57 Process header:
58 HEAD -> (gzip) or (zlib)
59 (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
60 NAME -> COMMENT -> HCRC -> TYPE
61 (zlib) -> DICTID or TYPE
62 DICTID -> DICT -> TYPE
63 Read deflate blocks:
64 TYPE -> STORED or TABLE or LEN or CHECK
65 STORED -> COPY -> TYPE
66 TABLE -> LENLENS -> CODELENS -> LEN
67 Read deflate codes:
68 LEN -> LENEXT or LIT or TYPE
69 LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
70 LIT -> LEN
71 Process trailer:
72 CHECK -> LENGTH -> DONE
73 */
74
75 /* state maintained between inflate() calls. Approximately 7K bytes. */
76 struct inflate_state {
77 inflate_mode mode; /* current inflate mode */
78 int last; /* true if processing last block */
79 int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
80 int havedict; /* true if dictionary provided */
81 int flags; /* gzip header method and flags (0 if zlib) */
82 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
83 unsigned long check; /* protected copy of check value */
84 unsigned long total; /* protected copy of output count */
85 gz_headerp head; /* where to save gzip header information */
86 /* sliding window */
87 unsigned wbits; /* log base 2 of requested window size */
88 unsigned wsize; /* window size or zero if not using window */
89 unsigned whave; /* valid bytes in the window */
90 unsigned write; /* window write index */
91 unsigned char FAR *window; /* allocated sliding window, if needed */
92 /* bit accumulator */
93 unsigned long hold; /* input bit accumulator */
94 unsigned bits; /* number of bits in "in" */
95 /* for string and stored block copying */
96 unsigned length; /* literal or length of data to copy */
97 unsigned offset; /* distance back to copy string from */
98 /* for table and code decoding */
99 unsigned extra; /* extra bits needed */
100 /* fixed and dynamic code tables */
101 code const FAR *lencode; /* starting table for length/literal codes */
102 code const FAR *distcode; /* starting table for distance codes */
103 unsigned lenbits; /* index bits for lencode */
104 unsigned distbits; /* index bits for distcode */
105 /* dynamic table building */
106 unsigned ncode; /* number of code length code lengths */
107 unsigned nlen; /* number of length code lengths */
108 unsigned ndist; /* number of distance code lengths */
109 unsigned have; /* number of code lengths in lens[] */
110 code FAR *next; /* next available space in codes[] */
111 unsigned short lens[320]; /* temporary storage for code lengths */
112 unsigned short work[288]; /* work area for code table building */
113 code codes[ENOUGH]; /* space for code tables */
114 };
0 /* inftrees.c -- generate Huffman trees for efficient decoding
1 * Copyright (C) 1995-2004 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 #include "zutil.h"
6 #include "inftrees.h"
7
8 #define MAXBITS 15
9
10 const char inflate_copyright[] =
11 " inflate 1.2.2.2 Copyright 1995-2004 Mark Adler ";
12 /*
13 If you use the zlib library in a product, an acknowledgment is welcome
14 in the documentation of your product. If for some reason you cannot
15 include such an acknowledgment, I would appreciate that you keep this
16 copyright string in the executable of your product.
17 */
18
19 /*
20 Build a set of tables to decode the provided canonical Huffman code.
21 The code lengths are lens[0..codes-1]. The result starts at *table,
22 whose indices are 0..2^bits-1. work is a writable array of at least
23 lens shorts, which is used as a work area. type is the type of code
24 to be generated, CODES, LENS, or DISTS. On return, zero is success,
25 -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
26 on return points to the next available entry's address. bits is the
27 requested root table index bits, and on return it is the actual root
28 table index bits. It will differ if the request is greater than the
29 longest code or if it is less than the shortest code.
30 */
31 int inflate_table(type, lens, codes, table, bits, work)
32 codetype type;
33 unsigned short FAR *lens;
34 unsigned codes;
35 code FAR * FAR *table;
36 unsigned FAR *bits;
37 unsigned short FAR *work;
38 {
39 unsigned len; /* a code's length in bits */
40 unsigned sym; /* index of code symbols */
41 unsigned min, max; /* minimum and maximum code lengths */
42 unsigned root; /* number of index bits for root table */
43 unsigned curr; /* number of index bits for current table */
44 unsigned drop; /* code bits to drop for sub-table */
45 int left; /* number of prefix codes available */
46 unsigned used; /* code entries in table used */
47 unsigned huff; /* Huffman code */
48 unsigned incr; /* for incrementing code, index */
49 unsigned fill; /* index for replicating entries */
50 unsigned low; /* low bits for current root entry */
51 unsigned mask; /* mask for low root bits */
52 code this; /* table entry for duplication */
53 code FAR *next; /* next available space in table */
54 const unsigned short FAR *base; /* base value table to use */
55 const unsigned short FAR *extra; /* extra bits table to use */
56 int end; /* use base and extra for symbol > end */
57 unsigned short count[MAXBITS+1]; /* number of codes of each length */
58 unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
59 static const unsigned short lbase[31] = { /* Length codes 257..285 base */
60 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
61 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
62 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
63 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
64 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 199};
65 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
66 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
67 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
68 8193, 12289, 16385, 24577, 0, 0};
69 static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
70 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
71 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
72 28, 28, 29, 29, 64, 64};
73
74 /*
75 Process a set of code lengths to create a canonical Huffman code. The
76 code lengths are lens[0..codes-1]. Each length corresponds to the
77 symbols 0..codes-1. The Huffman code is generated by first sorting the
78 symbols by length from short to long, and retaining the symbol order
79 for codes with equal lengths. Then the code starts with all zero bits
80 for the first code of the shortest length, and the codes are integer
81 increments for the same length, and zeros are appended as the length
82 increases. For the deflate format, these bits are stored backwards
83 from their more natural integer increment ordering, and so when the
84 decoding tables are built in the large loop below, the integer codes
85 are incremented backwards.
86
87 This routine assumes, but does not check, that all of the entries in
88 lens[] are in the range 0..MAXBITS. The caller must assure this.
89 1..MAXBITS is interpreted as that code length. zero means that that
90 symbol does not occur in this code.
91
92 The codes are sorted by computing a count of codes for each length,
93 creating from that a table of starting indices for each length in the
94 sorted table, and then entering the symbols in order in the sorted
95 table. The sorted table is work[], with that space being provided by
96 the caller.
97
98 The length counts are used for other purposes as well, i.e. finding
99 the minimum and maximum length codes, determining if there are any
100 codes at all, checking for a valid set of lengths, and looking ahead
101 at length counts to determine sub-table sizes when building the
102 decoding tables.
103 */
104
105 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
106 for (len = 0; len <= MAXBITS; len++)
107 count[len] = 0;
108 for (sym = 0; sym < codes; sym++)
109 count[lens[sym]]++;
110
111 /* bound code lengths, force root to be within code lengths */
112 root = *bits;
113 for (max = MAXBITS; max >= 1; max--)
114 if (count[max] != 0) break;
115 if (root > max) root = max;
116 if (max == 0) { /* no symbols to code at all */
117 this.op = (unsigned char)64; /* invalid code marker */
118 this.bits = (unsigned char)1;
119 this.val = (unsigned short)0;
120 *(*table)++ = this; /* make a table to force an error */
121 *(*table)++ = this;
122 *bits = 1;
123 return 0; /* no symbols, but wait for decoding to report error */
124 }
125 for (min = 1; min <= MAXBITS; min++)
126 if (count[min] != 0) break;
127 if (root < min) root = min;
128
129 /* check for an over-subscribed or incomplete set of lengths */
130 left = 1;
131 for (len = 1; len <= MAXBITS; len++) {
132 left <<= 1;
133 left -= count[len];
134 if (left < 0) return -1; /* over-subscribed */
135 }
136 if (left > 0 && (type == CODES || max != 1))
137 return -1; /* incomplete set */
138
139 /* generate offsets into symbol table for each length for sorting */
140 offs[1] = 0;
141 for (len = 1; len < MAXBITS; len++)
142 offs[len + 1] = offs[len] + count[len];
143
144 /* sort symbols by length, by symbol order within each length */
145 for (sym = 0; sym < codes; sym++)
146 if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
147
148 /*
149 Create and fill in decoding tables. In this loop, the table being
150 filled is at next and has curr index bits. The code being used is huff
151 with length len. That code is converted to an index by dropping drop
152 bits off of the bottom. For codes where len is less than drop + curr,
153 those top drop + curr - len bits are incremented through all values to
154 fill the table with replicated entries.
155
156 root is the number of index bits for the root table. When len exceeds
157 root, sub-tables are created pointed to by the root entry with an index
158 of the low root bits of huff. This is saved in low to check for when a
159 new sub-table should be started. drop is zero when the root table is
160 being filled, and drop is root when sub-tables are being filled.
161
162 When a new sub-table is needed, it is necessary to look ahead in the
163 code lengths to determine what size sub-table is needed. The length
164 counts are used for this, and so count[] is decremented as codes are
165 entered in the tables.
166
167 used keeps track of how many table entries have been allocated from the
168 provided *table space. It is checked when a LENS table is being made
169 against the space in *table, ENOUGH, minus the maximum space needed by
170 the worst case distance code, MAXD. This should never happen, but the
171 sufficiency of ENOUGH has not been proven exhaustively, hence the check.
172 This assumes that when type == LENS, bits == 9.
173
174 sym increments through all symbols, and the loop terminates when
175 all codes of length max, i.e. all codes, have been processed. This
176 routine permits incomplete codes, so another loop after this one fills
177 in the rest of the decoding tables with invalid code markers.
178 */
179
180 /* set up for code type */
181 switch (type) {
182 case CODES:
183 base = extra = work; /* dummy value--not used */
184 end = 19;
185 break;
186 case LENS:
187 base = lbase;
188 base -= 257;
189 extra = lext;
190 extra -= 257;
191 end = 256;
192 break;
193 default: /* DISTS */
194 base = dbase;
195 extra = dext;
196 end = -1;
197 }
198
199 /* initialize state for loop */
200 huff = 0; /* starting code */
201 sym = 0; /* starting code symbol */
202 len = min; /* starting code length */
203 next = *table; /* current table to fill in */
204 curr = root; /* current table index bits */
205 drop = 0; /* current bits to drop from code for index */
206 low = (unsigned)(-1); /* trigger new sub-table when len > root */
207 used = 1U << root; /* use root table entries */
208 mask = used - 1; /* mask for comparing low */
209
210 /* check available table space */
211 if (type == LENS && used >= ENOUGH - MAXD)
212 return 1;
213
214 /* process all codes and make table entries */
215 for (;;) {
216 /* create table entry */
217 this.bits = (unsigned char)(len - drop);
218 if ((int)(work[sym]) < end) {
219 this.op = (unsigned char)0;
220 this.val = work[sym];
221 }
222 else if ((int)(work[sym]) > end) {
223 this.op = (unsigned char)(extra[work[sym]]);
224 this.val = base[work[sym]];
225 }
226 else {
227 this.op = (unsigned char)(32 + 64); /* end of block */
228 this.val = 0;
229 }
230
231 /* replicate for those indices with low len bits equal to huff */
232 incr = 1U << (len - drop);
233 fill = 1U << curr;
234 do {
235 fill -= incr;
236 next[(huff >> drop) + fill] = this;
237 } while (fill != 0);
238
239 /* backwards increment the len-bit code huff */
240 incr = 1U << (len - 1);
241 while (huff & incr)
242 incr >>= 1;
243 if (incr != 0) {
244 huff &= incr - 1;
245 huff += incr;
246 }
247 else
248 huff = 0;
249
250 /* go to next symbol, update count, len */
251 sym++;
252 if (--(count[len]) == 0) {
253 if (len == max) break;
254 len = lens[work[sym]];
255 }
256
257 /* create new sub-table if needed */
258 if (len > root && (huff & mask) != low) {
259 /* if first time, transition to sub-tables */
260 if (drop == 0)
261 drop = root;
262
263 /* increment past last table */
264 next += 1U << curr;
265
266 /* determine length of next table */
267 curr = len - drop;
268 left = (int)(1 << curr);
269 while (curr + drop < max) {
270 left -= count[curr + drop];
271 if (left <= 0) break;
272 curr++;
273 left <<= 1;
274 }
275
276 /* check for enough space */
277 used += 1U << curr;
278 if (type == LENS && used >= ENOUGH - MAXD)
279 return 1;
280
281 /* point entry in root table to sub-table */
282 low = huff & mask;
283 (*table)[low].op = (unsigned char)curr;
284 (*table)[low].bits = (unsigned char)root;
285 (*table)[low].val = (unsigned short)(next - *table);
286 }
287 }
288
289 /*
290 Fill in rest of table for incomplete codes. This loop is similar to the
291 loop above in incrementing huff for table indices. It is assumed that
292 len is equal to curr + drop, so there is no loop needed to increment
293 through high index bits. When the current sub-table is filled, the loop
294 drops back to the root table to fill in any remaining entries there.
295 */
296 this.op = (unsigned char)64; /* invalid code marker */
297 this.bits = (unsigned char)(len - drop);
298 this.val = (unsigned short)0;
299 while (huff != 0) {
300 /* when done with sub-table, drop back to root table */
301 if (drop != 0 && (huff & mask) != low) {
302 drop = 0;
303 len = root;
304 next = *table;
305 this.bits = (unsigned char)len;
306 }
307
308 /* put invalid code marker in table */
309 next[huff >> drop] = this;
310
311 /* backwards increment the len-bit code huff */
312 incr = 1U << (len - 1);
313 while (huff & incr)
314 incr >>= 1;
315 if (incr != 0) {
316 huff &= incr - 1;
317 huff += incr;
318 }
319 else
320 huff = 0;
321 }
322
323 /* set return parameters */
324 *table += used;
325 *bits = root;
326 return 0;
327 }
0 /* inftrees.h -- header to use inftrees.c
1 * Copyright (C) 1995-2003 Mark Adler
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* Structure for decoding tables. Each entry provides either the
11 information needed to do the operation requested by the code that
12 indexed that table entry, or it provides a pointer to another
13 table that indexes more bits of the code. op indicates whether
14 the entry is a pointer to another table, a literal, a length or
15 distance, an end-of-block, or an invalid code. For a table
16 pointer, the low four bits of op is the number of index bits of
17 that table. For a length or distance, the low four bits of op
18 is the number of extra bits to get after the code. bits is
19 the number of bits in this code or part of the code to drop off
20 of the bit buffer. val is the actual byte to output in the case
21 of a literal, the base length or distance, or the offset from
22 the current table to the next table. Each entry is four bytes. */
23 typedef struct {
24 unsigned char op; /* operation, extra bits, table bits */
25 unsigned char bits; /* bits in this part of the code */
26 unsigned short val; /* offset in table or code value */
27 } code;
28
29 /* op values as set by inflate_table():
30 00000000 - literal
31 0000tttt - table link, tttt != 0 is the number of table index bits
32 0001eeee - length or distance, eeee is the number of extra bits
33 01100000 - end of block
34 01000000 - invalid code
35 */
36
37 /* Maximum size of dynamic tree. The maximum found in a long but non-
38 exhaustive search was 1004 code structures (850 for length/literals
39 and 154 for distances, the latter actually the result of an
40 exhaustive search). The true maximum is not known, but the value
41 below is more than safe. */
42 #define ENOUGH 1440
43 #define MAXD 154
44
45 /* Type of code to build for inftable() */
46 typedef enum {
47 CODES,
48 LENS,
49 DISTS
50 } codetype;
51
52 extern int inflate_table OF((codetype type, unsigned short FAR *lens,
53 unsigned codes, code FAR * FAR *table,
54 unsigned FAR *bits, unsigned short FAR *work));
0 $! make libz under VMS
1 $! written by Martin P.J. Zinser <m.zinser@gsi.de>
2 $!
3 $! Look for the compiler used
4 $!
5 $ ccopt = ""
6 $ if f$getsyi("HW_MODEL").ge.1024
7 $ then
8 $ ccopt = "/prefix=all"+ccopt
9 $ comp = "__decc__=1"
10 $ if f$trnlnm("SYS").eqs."" then define sys sys$library:
11 $ else
12 $ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
13 $ then
14 $ comp = "__vaxc__=1"
15 $ if f$trnlnm("SYS").eqs."" then define sys sys$library:
16 $ else
17 $ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
18 $ ccopt = "/decc/prefix=all"+ccopt
19 $ comp = "__decc__=1"
20 $ endif
21 $ endif
22 $!
23 $! Build the thing plain or with mms
24 $!
25 $ write sys$output "Compiling Zlib sources ..."
26 $ if f$search("SYS$SYSTEM:MMS.EXE").eqs.""
27 $ then
28 $ dele example.obj;*,minigzip.obj;*
29 $ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
30 adler32.c zlib.h zconf.h
31 $ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
32 compress.c zlib.h zconf.h
33 $ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
34 crc32.c crc32.h zlib.h zconf.h zutil.h
35 $ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
36 deflate.c deflate.h zutil.h zlib.h zconf.h
37 $ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio /define=""NO_vsnprintf""" -
38 gzio.c zutil.h zlib.h zconf.h
39 $ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
40 infback.c zutil.h zlib.h zconf.h -
41 "inftrees.h inflate.h inffast.h inffixed.h"
42 $ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
43 inffast.c zutil.h zlib.h zconf.h -
44 "inftrees.h inflate.h inffast.h"
45 $ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
46 inflate.c zutil.h zlib.h zconf.h -
47 "inftrees.h inflate.h inffast.h inffixed.h"
48 $ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
49 inftrees.c zutil.h zlib.h zconf.h inftrees.h
50 $ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
51 trees.c trees.h deflate.h zutil.h zlib.h zconf.h
52 $ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
53 uncompr.c zlib.h zconf.h
54 $ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
55 zutil.c zutil.h zlib.h zconf.h
56 $ write sys$output "Building Zlib ..."
57 $ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
58 $ write sys$output "Building example..."
59 $ CALL MAKE example.OBJ "CC ''CCOPT' example" -
60 example.c zlib.h zconf.h
61 $ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
62 $ write sys$output "Building minigzip..."
63 $ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
64 minigzip.c zlib.h zconf.h
65 $ call make minigzip.exe -
66 "LINK minigzip,libz.olb/lib" -
67 minigzip.obj libz.olb
68 $ else
69 $ mms/macro=('comp')
70 $ endif
71 $ write sys$output "Zlib build completed"
72 $ exit
73 $!
74 $!
75 $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
76 $ V = 'F$Verify(0)
77 $! P1 = What we are trying to make
78 $! P2 = Command to make it
79 $! P3 - P8 What it depends on
80 $
81 $ If F$Search(P1) .Eqs. "" Then Goto Makeit
82 $ Time = F$CvTime(F$File(P1,"RDT"))
83 $arg=3
84 $Loop:
85 $ Argument = P'arg
86 $ If Argument .Eqs. "" Then Goto Exit
87 $ El=0
88 $Loop2:
89 $ File = F$Element(El," ",Argument)
90 $ If File .Eqs. " " Then Goto Endl
91 $ AFile = ""
92 $Loop3:
93 $ OFile = AFile
94 $ AFile = F$Search(File)
95 $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
96 $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
97 $ Goto Loop3
98 $NextEL:
99 $ El = El + 1
100 $ Goto Loop2
101 $EndL:
102 $ arg=arg+1
103 $ If arg .Le. 8 Then Goto Loop
104 $ Goto Exit
105 $
106 $Makeit:
107 $ VV=F$VERIFY(0)
108 $ write sys$output P2
109 $ 'P2
110 $ VV='F$Verify(VV)
111 $Exit:
112 $ If V Then Set Verify
113 $ENDSUBROUTINE
0 /* minigzip.c -- simulate gzip using the zlib compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 * minigzip is a minimal implementation of the gzip utility. This is
7 * only an example of using zlib and isn't meant to replace the
8 * full-featured gzip. No attempt is made to deal with file systems
9 * limiting names to 14 or 8+3 characters, etc... Error checking is
10 * very limited. So use minigzip only for testing; use gzip for the
11 * real thing. On MSDOS, use only on file names without extension
12 * or in pipe mode.
13 */
14
15 /* @(#) $Id$ */
16
17 #include <stdio.h>
18 #include "zlib.h"
19
20 #ifdef STDC
21 # include <string.h>
22 # include <stdlib.h>
23 #endif
24
25 #ifdef USE_MMAP
26 # include <sys/types.h>
27 # include <sys/mman.h>
28 # include <sys/stat.h>
29 #endif
30
31 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
32 # include <fcntl.h>
33 # include <io.h>
34 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
35 #else
36 # define SET_BINARY_MODE(file)
37 #endif
38
39 #ifdef VMS
40 # define unlink delete
41 # define GZ_SUFFIX "-gz"
42 #endif
43 #ifdef RISCOS
44 # define unlink remove
45 # define GZ_SUFFIX "-gz"
46 # define fileno(file) file->__file
47 #endif
48 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
49 # include <unix.h> /* for fileno */
50 #endif
51
52 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
53 extern int unlink OF((const char *));
54 #endif
55
56 #ifndef GZ_SUFFIX
57 # define GZ_SUFFIX ".gz"
58 #endif
59 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
60
61 #define BUFLEN 16384
62 #define MAX_NAME_LEN 1024
63
64 #ifdef MAXSEG_64K
65 # define local static
66 /* Needed for systems with limitation on stack size. */
67 #else
68 # define local
69 #endif
70
71 char *prog;
72
73 void error OF((const char *msg));
74 void gz_compress OF((FILE *in, gzFile out));
75 #ifdef USE_MMAP
76 int gz_compress_mmap OF((FILE *in, gzFile out));
77 #endif
78 void gz_uncompress OF((gzFile in, FILE *out));
79 void file_compress OF((char *file, char *mode));
80 void file_uncompress OF((char *file));
81 int main OF((int argc, char *argv[]));
82
83 /* ===========================================================================
84 * Display error message and exit
85 */
86 void error(msg)
87 const char *msg;
88 {
89 fprintf(stderr, "%s: %s\n", prog, msg);
90 exit(1);
91 }
92
93 /* ===========================================================================
94 * Compress input to output then close both files.
95 */
96
97 void gz_compress(in, out)
98 FILE *in;
99 gzFile out;
100 {
101 local char buf[BUFLEN];
102 int len;
103 int err;
104
105 #ifdef USE_MMAP
106 /* Try first compressing with mmap. If mmap fails (minigzip used in a
107 * pipe), use the normal fread loop.
108 */
109 if (gz_compress_mmap(in, out) == Z_OK) return;
110 #endif
111 for (;;) {
112 len = (int)fread(buf, 1, sizeof(buf), in);
113 if (ferror(in)) {
114 perror("fread");
115 exit(1);
116 }
117 if (len == 0) break;
118
119 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
120 }
121 fclose(in);
122 if (gzclose(out) != Z_OK) error("failed gzclose");
123 }
124
125 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
126
127 /* Try compressing the input file at once using mmap. Return Z_OK if
128 * if success, Z_ERRNO otherwise.
129 */
130 int gz_compress_mmap(in, out)
131 FILE *in;
132 gzFile out;
133 {
134 int len;
135 int err;
136 int ifd = fileno(in);
137 caddr_t buf; /* mmap'ed buffer for the entire input file */
138 off_t buf_len; /* length of the input file */
139 struct stat sb;
140
141 /* Determine the size of the file, needed for mmap: */
142 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
143 buf_len = sb.st_size;
144 if (buf_len <= 0) return Z_ERRNO;
145
146 /* Now do the actual mmap: */
147 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
148 if (buf == (caddr_t)(-1)) return Z_ERRNO;
149
150 /* Compress the whole file at once: */
151 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
152
153 if (len != (int)buf_len) error(gzerror(out, &err));
154
155 munmap(buf, buf_len);
156 fclose(in);
157 if (gzclose(out) != Z_OK) error("failed gzclose");
158 return Z_OK;
159 }
160 #endif /* USE_MMAP */
161
162 /* ===========================================================================
163 * Uncompress input to output then close both files.
164 */
165 void gz_uncompress(in, out)
166 gzFile in;
167 FILE *out;
168 {
169 local char buf[BUFLEN];
170 int len;
171 int err;
172
173 for (;;) {
174 len = gzread(in, buf, sizeof(buf));
175 if (len < 0) error (gzerror(in, &err));
176 if (len == 0) break;
177
178 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
179 error("failed fwrite");
180 }
181 }
182 if (fclose(out)) error("failed fclose");
183
184 if (gzclose(in) != Z_OK) error("failed gzclose");
185 }
186
187
188 /* ===========================================================================
189 * Compress the given file: create a corresponding .gz file and remove the
190 * original.
191 */
192 void file_compress(file, mode)
193 char *file;
194 char *mode;
195 {
196 local char outfile[MAX_NAME_LEN];
197 FILE *in;
198 gzFile out;
199
200 strcpy(outfile, file);
201 strcat(outfile, GZ_SUFFIX);
202
203 in = fopen(file, "rb");
204 if (in == NULL) {
205 perror(file);
206 exit(1);
207 }
208 out = gzopen(outfile, mode);
209 if (out == NULL) {
210 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
211 exit(1);
212 }
213 gz_compress(in, out);
214
215 unlink(file);
216 }
217
218
219 /* ===========================================================================
220 * Uncompress the given file and remove the original.
221 */
222 void file_uncompress(file)
223 char *file;
224 {
225 local char buf[MAX_NAME_LEN];
226 char *infile, *outfile;
227 FILE *out;
228 gzFile in;
229 uInt len = (uInt)strlen(file);
230
231 strcpy(buf, file);
232
233 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
234 infile = file;
235 outfile = buf;
236 outfile[len-3] = '\0';
237 } else {
238 outfile = file;
239 infile = buf;
240 strcat(infile, GZ_SUFFIX);
241 }
242 in = gzopen(infile, "rb");
243 if (in == NULL) {
244 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
245 exit(1);
246 }
247 out = fopen(outfile, "wb");
248 if (out == NULL) {
249 perror(file);
250 exit(1);
251 }
252
253 gz_uncompress(in, out);
254
255 unlink(infile);
256 }
257
258
259 /* ===========================================================================
260 * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
261 * -d : decompress
262 * -f : compress with Z_FILTERED
263 * -h : compress with Z_HUFFMAN_ONLY
264 * -r : compress with Z_RLE
265 * -1 to -9 : compression level
266 */
267
268 int main(argc, argv)
269 int argc;
270 char *argv[];
271 {
272 int uncompr = 0;
273 gzFile file;
274 char outmode[20];
275
276 strcpy(outmode, "wb6 ");
277
278 prog = argv[0];
279 argc--, argv++;
280
281 while (argc > 0) {
282 if (strcmp(*argv, "-d") == 0)
283 uncompr = 1;
284 else if (strcmp(*argv, "-f") == 0)
285 outmode[3] = 'f';
286 else if (strcmp(*argv, "-h") == 0)
287 outmode[3] = 'h';
288 else if (strcmp(*argv, "-r") == 0)
289 outmode[3] = 'R';
290 else if (strcmp(*argv, "-R") == 0)
291 outmode[3] = 's';
292 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
293 (*argv)[2] == 0)
294 outmode[2] = (*argv)[1];
295 else
296 break;
297 argc--, argv++;
298 }
299 if (argc == 0) {
300 SET_BINARY_MODE(stdin);
301 SET_BINARY_MODE(stdout);
302 if (uncompr) {
303 file = gzdopen(fileno(stdin), "rb");
304 if (file == NULL) error("can't gzdopen stdin");
305 gz_uncompress(file, stdout);
306 } else {
307 file = gzdopen(fileno(stdout), outmode);
308 if (file == NULL) error("can't gzdopen stdout");
309 gz_compress(stdin, file);
310 }
311 } else {
312 do {
313 if (uncompr) {
314 file_uncompress(*argv);
315 } else {
316 file_compress(*argv, outmode);
317 }
318 } while (argv++, --argc);
319 }
320 return 0;
321 }
0 # Makefile for zlib
1 # Borland C++
2 # Last updated: 15-Mar-2003
3
4 # To use, do "make -fmakefile.bor"
5 # To compile in small model, set below: MODEL=s
6
7 # WARNING: the small model is supported but only for small values of
8 # MAX_WBITS and MAX_MEM_LEVEL. For example:
9 # -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
10 # If you wish to reduce the memory requirements (default 256K for big
11 # objects plus a few K), you can add to the LOC macro below:
12 # -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
13 # See zconf.h for details about the memory requirements.
14
15 # ------------ Turbo C++, Borland C++ ------------
16
17 # Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
18 # should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
19 # to the declaration of LOC here:
20 LOC = $(LOCAL_ZLIB)
21
22 # type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
23 CPU_TYP = 0
24
25 # memory model: one of s, m, c, l (small, medium, compact, large)
26 MODEL=l
27
28 # replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
29 CC=bcc
30 LD=bcc
31 AR=tlib
32
33 # compiler flags
34 # replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
35 CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
36
37 LDFLAGS=-m$(MODEL) -f-
38
39
40 # variables
41 ZLIB_LIB = zlib_$(MODEL).lib
42
43 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
44 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
45 OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
46 OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
47
48
49 # targets
50 all: $(ZLIB_LIB) example.exe minigzip.exe
51
52 .c.obj:
53 $(CC) -c $(CFLAGS) $*.c
54
55 adler32.obj: adler32.c zlib.h zconf.h
56
57 compress.obj: compress.c zlib.h zconf.h
58
59 crc32.obj: crc32.c zlib.h zconf.h crc32.h
60
61 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
62
63 gzio.obj: gzio.c zutil.h zlib.h zconf.h
64
65 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
66 inffast.h inffixed.h
67
68 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
69 inffast.h
70
71 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
72 inffast.h inffixed.h
73
74 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
75
76 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
77
78 uncompr.obj: uncompr.c zlib.h zconf.h
79
80 zutil.obj: zutil.c zutil.h zlib.h zconf.h
81
82 example.obj: example.c zlib.h zconf.h
83
84 minigzip.obj: minigzip.c zlib.h zconf.h
85
86
87 # the command line is cut to fit in the MS-DOS 128 byte limit:
88 $(ZLIB_LIB): $(OBJ1) $(OBJ2)
89 -del $(ZLIB_LIB)
90 $(AR) $(ZLIB_LIB) $(OBJP1)
91 $(AR) $(ZLIB_LIB) $(OBJP2)
92
93 example.exe: example.obj $(ZLIB_LIB)
94 $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
95
96 minigzip.exe: minigzip.obj $(ZLIB_LIB)
97 $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
98
99 test: example.exe minigzip.exe
100 example
101 echo hello world | minigzip | minigzip -d
102
103 clean:
104 -del *.obj
105 -del *.lib
106 -del *.exe
107 -del zlib_*.bak
108 -del foo.gz
0 # Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
1 # Copyright (C) 1995-1998 Jean-loup Gailly.
2 # For conditions of distribution and use, see copyright notice in zlib.h
3
4 # To compile, or to compile and test, type:
5 #
6 # make -fmakefile.dj2; make test -fmakefile.dj2
7 #
8 # To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
9 #
10 # make install -fmakefile.dj2
11 #
12 # after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
13 # in the sample below if the pattern of the DJGPP distribution is to
14 # be followed. Remember that, while <sp>'es around <=> are ignored in
15 # makefiles, they are *not* in batch files or in djgpp.env.
16 # - - - - -
17 # [make]
18 # INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
19 # LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
20 # BUTT=-m486
21 # - - - - -
22 # Alternately, these variables may be defined below, overriding the values
23 # in djgpp.env, as
24 # INCLUDE_PATH=c:\usr\include
25 # LIBRARY_PATH=c:\usr\lib
26
27 CC=gcc
28
29 #CFLAGS=-MMD -O
30 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
31 #CFLAGS=-MMD -g -DDEBUG
32 CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
33 -Wstrict-prototypes -Wmissing-prototypes
34
35 # If cp.exe is available, replace "copy /Y" with "cp -fp" .
36 CP=copy /Y
37 # If gnu install.exe is available, replace $(CP) with ginstall.
38 INSTALL=$(CP)
39 # The default value of RM is "rm -f." If "rm.exe" is found, comment out:
40 RM=del
41 LDLIBS=-L. -lz
42 LD=$(CC) -s -o
43 LDSHARED=$(CC)
44
45 INCL=zlib.h zconf.h
46 LIBS=libz.a
47
48 AR=ar rcs
49
50 prefix=/usr/local
51 exec_prefix = $(prefix)
52
53 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
54 zutil.o inflate.o infback.o inftrees.o inffast.o
55
56 OBJA =
57 # to use the asm code: make OBJA=match.o
58
59 TEST_OBJS = example.o minigzip.o
60
61 all: example.exe minigzip.exe
62
63 check: test
64 test: all
65 ./example
66 echo hello world | .\minigzip | .\minigzip -d
67
68 %.o : %.c
69 $(CC) $(CFLAGS) -c $< -o $@
70
71 libz.a: $(OBJS) $(OBJA)
72 $(AR) $@ $(OBJS) $(OBJA)
73
74 %.exe : %.o $(LIBS)
75 $(LD) $@ $< $(LDLIBS)
76
77 # INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
78
79 .PHONY : uninstall clean
80
81 install: $(INCL) $(LIBS)
82 -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
83 -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
84 $(INSTALL) zlib.h $(INCLUDE_PATH)
85 $(INSTALL) zconf.h $(INCLUDE_PATH)
86 $(INSTALL) libz.a $(LIBRARY_PATH)
87
88 uninstall:
89 $(RM) $(INCLUDE_PATH)\zlib.h
90 $(RM) $(INCLUDE_PATH)\zconf.h
91 $(RM) $(LIBRARY_PATH)\libz.a
92
93 clean:
94 $(RM) *.d
95 $(RM) *.o
96 $(RM) *.exe
97 $(RM) libz.a
98 $(RM) foo.gz
99
100 DEPS := $(wildcard *.d)
101 ifneq ($(DEPS),)
102 include $(DEPS)
103 endif
0 # Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
1 # Copyright (C) 1995-1998 Jean-loup Gailly.
2 # For conditions of distribution and use, see copyright notice in zlib.h
3
4 # To compile, or to compile and test, type:
5 #
6 # make -fmakefile.emx; make test -fmakefile.emx
7 #
8
9 CC=gcc
10
11 #CFLAGS=-MMD -O
12 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
13 #CFLAGS=-MMD -g -DDEBUG
14 CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
15 -Wstrict-prototypes -Wmissing-prototypes
16
17 # If cp.exe is available, replace "copy /Y" with "cp -fp" .
18 CP=copy /Y
19 # If gnu install.exe is available, replace $(CP) with ginstall.
20 INSTALL=$(CP)
21 # The default value of RM is "rm -f." If "rm.exe" is found, comment out:
22 RM=del
23 LDLIBS=-L. -lzlib
24 LD=$(CC) -s -o
25 LDSHARED=$(CC)
26
27 INCL=zlib.h zconf.h
28 LIBS=zlib.a
29
30 AR=ar rcs
31
32 prefix=/usr/local
33 exec_prefix = $(prefix)
34
35 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
36 zutil.o inflate.o infback.o inftrees.o inffast.o
37
38 TEST_OBJS = example.o minigzip.o
39
40 all: example.exe minigzip.exe
41
42 test: all
43 ./example
44 echo hello world | .\minigzip | .\minigzip -d
45
46 %.o : %.c
47 $(CC) $(CFLAGS) -c $< -o $@
48
49 zlib.a: $(OBJS)
50 $(AR) $@ $(OBJS)
51
52 %.exe : %.o $(LIBS)
53 $(LD) $@ $< $(LDLIBS)
54
55
56 .PHONY : clean
57
58 clean:
59 $(RM) *.d
60 $(RM) *.o
61 $(RM) *.exe
62 $(RM) zlib.a
63 $(RM) foo.gz
64
65 DEPS := $(wildcard *.d)
66 ifneq ($(DEPS),)
67 include $(DEPS)
68 endif
0 # Makefile for zlib
1 # Microsoft C 5.1 or later
2 # Last updated: 19-Mar-2003
3
4 # To use, do "make makefile.msc"
5 # To compile in small model, set below: MODEL=S
6
7 # If you wish to reduce the memory requirements (default 256K for big
8 # objects plus a few K), you can add to the LOC macro below:
9 # -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
10 # See zconf.h for details about the memory requirements.
11
12 # ------------- Microsoft C 5.1 and later -------------
13
14 # Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
15 # should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
16 # to the declaration of LOC here:
17 LOC = $(LOCAL_ZLIB)
18
19 # Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
20 CPU_TYP = 0
21
22 # Memory model: one of S, M, C, L (small, medium, compact, large)
23 MODEL=L
24
25 CC=cl
26 CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
27 #-Ox generates bad code with MSC 5.1
28 LIB_CFLAGS=-Zl $(CFLAGS)
29
30 LD=link
31 LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
32 # "/farcall/packcode" are only useful for `large code' memory models
33 # but should be a "no-op" for small code models.
34
35
36 # variables
37 ZLIB_LIB = zlib_$(MODEL).lib
38
39 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
40 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
41
42
43 # targets
44 all: $(ZLIB_LIB) example.exe minigzip.exe
45
46 .c.obj:
47 $(CC) -c $(LIB_CFLAGS) $*.c
48
49 adler32.obj: adler32.c zlib.h zconf.h
50
51 compress.obj: compress.c zlib.h zconf.h
52
53 crc32.obj: crc32.c zlib.h zconf.h crc32.h
54
55 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
56
57 gzio.obj: gzio.c zutil.h zlib.h zconf.h
58
59 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
60 inffast.h inffixed.h
61
62 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
63 inffast.h
64
65 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
66 inffast.h inffixed.h
67
68 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
69
70 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
71
72 uncompr.obj: uncompr.c zlib.h zconf.h
73
74 zutil.obj: zutil.c zutil.h zlib.h zconf.h
75
76 example.obj: example.c zlib.h zconf.h
77 $(CC) -c $(CFLAGS) $*.c
78
79 minigzip.obj: minigzip.c zlib.h zconf.h
80 $(CC) -c $(CFLAGS) $*.c
81
82
83 # the command line is cut to fit in the MS-DOS 128 byte limit:
84 $(ZLIB_LIB): $(OBJ1) $(OBJ2)
85 if exist $(ZLIB_LIB) del $(ZLIB_LIB)
86 lib $(ZLIB_LIB) $(OBJ1);
87 lib $(ZLIB_LIB) $(OBJ2);
88
89 example.exe: example.obj $(ZLIB_LIB)
90 $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
91
92 minigzip.exe: minigzip.obj $(ZLIB_LIB)
93 $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
94
95 test: example.exe minigzip.exe
96 example
97 echo hello world | minigzip | minigzip -d
98
99 clean:
100 -del *.obj
101 -del *.lib
102 -del *.exe
103 -del *.map
104 -del zlib_*.bak
105 -del foo.gz
0 # Makefile for zlib
1 # Turbo C 2.01, Turbo C++ 1.01
2 # Last updated: 15-Mar-2003
3
4 # To use, do "make -fmakefile.tc"
5 # To compile in small model, set below: MODEL=s
6
7 # WARNING: the small model is supported but only for small values of
8 # MAX_WBITS and MAX_MEM_LEVEL. For example:
9 # -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10 # If you wish to reduce the memory requirements (default 256K for big
11 # objects plus a few K), you can add to CFLAGS below:
12 # -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
13 # See zconf.h for details about the memory requirements.
14
15 # ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
16 MODEL=l
17 CC=tcc
18 LD=tcc
19 AR=tlib
20 # CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
21 CFLAGS=-O2 -G -Z -m$(MODEL)
22 LDFLAGS=-m$(MODEL) -f-
23
24
25 # variables
26 ZLIB_LIB = zlib_$(MODEL).lib
27
28 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
29 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
30 OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
31 OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
32
33
34 # targets
35 all: $(ZLIB_LIB) example.exe minigzip.exe
36
37 .c.obj:
38 $(CC) -c $(CFLAGS) $*.c
39
40 adler32.obj: adler32.c zlib.h zconf.h
41
42 compress.obj: compress.c zlib.h zconf.h
43
44 crc32.obj: crc32.c zlib.h zconf.h crc32.h
45
46 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
47
48 gzio.obj: gzio.c zutil.h zlib.h zconf.h
49
50 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
51 inffast.h inffixed.h
52
53 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
54 inffast.h
55
56 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
57 inffast.h inffixed.h
58
59 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
60
61 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
62
63 uncompr.obj: uncompr.c zlib.h zconf.h
64
65 zutil.obj: zutil.c zutil.h zlib.h zconf.h
66
67 example.obj: example.c zlib.h zconf.h
68
69 minigzip.obj: minigzip.c zlib.h zconf.h
70
71
72 # the command line is cut to fit in the MS-DOS 128 byte limit:
73 $(ZLIB_LIB): $(OBJ1) $(OBJ2)
74 -del $(ZLIB_LIB)
75 $(AR) $(ZLIB_LIB) $(OBJP1)
76 $(AR) $(ZLIB_LIB) $(OBJP2)
77
78 example.exe: example.obj $(ZLIB_LIB)
79 $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
80
81 minigzip.exe: minigzip.obj $(ZLIB_LIB)
82 $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
83
84 test: example.exe minigzip.exe
85 example
86 echo hello world | minigzip | minigzip -d
87
88 clean:
89 -del *.obj
90 -del *.lib
91 -del *.exe
92 -del zlib_*.bak
93 -del foo.gz
0 # Project: zlib_1_03
1 # Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
2 # test works out-of-the-box, installs `somewhere' on demand
3
4 # Toolflags:
5 CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
6 C++flags = -c -depend !Depend -IC: -throwback
7 Linkflags = -aif -c++ -o $@
8 ObjAsmflags = -throwback -NoCache -depend !Depend
9 CMHGflags =
10 LibFileflags = -c -l -o $@
11 Squeezeflags = -o $@
12
13 # change the line below to where _you_ want the library installed.
14 libdest = lib:zlib
15
16 # Final targets:
17 @.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
18 @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
19 @.o.uncompr @.o.zutil
20 LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
21 @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
22 @.o.trees @.o.uncompr @.o.zutil
23 test: @.minigzip @.example @.lib
24 @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
25 @echo running tests: hang on.
26 @/@.minigzip -f -9 libc
27 @/@.minigzip -d libc-gz
28 @/@.minigzip -f -1 libc
29 @/@.minigzip -d libc-gz
30 @/@.minigzip -h -9 libc
31 @/@.minigzip -d libc-gz
32 @/@.minigzip -h -1 libc
33 @/@.minigzip -d libc-gz
34 @/@.minigzip -9 libc
35 @/@.minigzip -d libc-gz
36 @/@.minigzip -1 libc
37 @/@.minigzip -d libc-gz
38 @diff @.lib @.libc
39 @echo that should have reported '@.lib and @.libc identical' if you have diff.
40 @/@.example @.fred @.fred
41 @echo that will have given lots of hello!'s.
42
43 @.minigzip: @.o.minigzip @.lib C:o.Stubs
44 Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
45 @.example: @.o.example @.lib C:o.Stubs
46 Link $(Linkflags) @.o.example @.lib C:o.Stubs
47
48 install: @.lib
49 cdir $(libdest)
50 cdir $(libdest).h
51 @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
52 @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
53 @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
54 @echo okay, installed zlib in $(libdest)
55
56 clean:; remove @.minigzip
57 remove @.example
58 remove @.libc
59 -wipe @.o.* F~r~cV
60 remove @.fred
61
62 # User-editable dependencies:
63 .c.o:
64 cc $(ccflags) -o $@ $<
65
66 # Static dependencies:
67
68 # Dynamic dependencies:
69 o.example: c.example
70 o.example: h.zlib
71 o.example: h.zconf
72 o.minigzip: c.minigzip
73 o.minigzip: h.zlib
74 o.minigzip: h.zconf
75 o.adler32: c.adler32
76 o.adler32: h.zlib
77 o.adler32: h.zconf
78 o.compress: c.compress
79 o.compress: h.zlib
80 o.compress: h.zconf
81 o.crc32: c.crc32
82 o.crc32: h.zlib
83 o.crc32: h.zconf
84 o.deflate: c.deflate
85 o.deflate: h.deflate
86 o.deflate: h.zutil
87 o.deflate: h.zlib
88 o.deflate: h.zconf
89 o.gzio: c.gzio
90 o.gzio: h.zutil
91 o.gzio: h.zlib
92 o.gzio: h.zconf
93 o.infblock: c.infblock
94 o.infblock: h.zutil
95 o.infblock: h.zlib
96 o.infblock: h.zconf
97 o.infblock: h.infblock
98 o.infblock: h.inftrees
99 o.infblock: h.infcodes
100 o.infblock: h.infutil
101 o.infcodes: c.infcodes
102 o.infcodes: h.zutil
103 o.infcodes: h.zlib
104 o.infcodes: h.zconf
105 o.infcodes: h.inftrees
106 o.infcodes: h.infblock
107 o.infcodes: h.infcodes
108 o.infcodes: h.infutil
109 o.infcodes: h.inffast
110 o.inffast: c.inffast
111 o.inffast: h.zutil
112 o.inffast: h.zlib
113 o.inffast: h.zconf
114 o.inffast: h.inftrees
115 o.inffast: h.infblock
116 o.inffast: h.infcodes
117 o.inffast: h.infutil
118 o.inffast: h.inffast
119 o.inflate: c.inflate
120 o.inflate: h.zutil
121 o.inflate: h.zlib
122 o.inflate: h.zconf
123 o.inflate: h.infblock
124 o.inftrees: c.inftrees
125 o.inftrees: h.zutil
126 o.inftrees: h.zlib
127 o.inftrees: h.zconf
128 o.inftrees: h.inftrees
129 o.inftrees: h.inffixed
130 o.infutil: c.infutil
131 o.infutil: h.zutil
132 o.infutil: h.zlib
133 o.infutil: h.zconf
134 o.infutil: h.infblock
135 o.infutil: h.inftrees
136 o.infutil: h.infcodes
137 o.infutil: h.infutil
138 o.trees: c.trees
139 o.trees: h.deflate
140 o.trees: h.zutil
141 o.trees: h.zlib
142 o.trees: h.zconf
143 o.trees: h.trees
144 o.uncompr: c.uncompr
145 o.uncompr: h.zlib
146 o.uncompr: h.zconf
147 o.zutil: c.zutil
148 o.zutil: h.zutil
149 o.zutil: h.zlib
150 o.zutil: h.zconf
0 This directory contains files that have not been updated for zlib 1.2.x
1
2 (Volunteers are encouraged to help clean this up. Thanks.)
0 # descrip.mms: MMS description file for building zlib on VMS
1 # written by Martin P.J. Zinser <m.zinser@gsi.de>
2
3 cc_defs =
4 c_deb =
5
6 .ifdef __DECC__
7 pref = /prefix=all
8 .endif
9
10 OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
11 deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
12 inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
13
14 CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
15
16 all : example.exe minigzip.exe
17 @ write sys$output " Example applications available"
18 libz.olb : libz.olb($(OBJS))
19 @ write sys$output " libz available"
20
21 example.exe : example.obj libz.olb
22 link example,libz.olb/lib
23
24 minigzip.exe : minigzip.obj libz.olb
25 link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
26
27 clean :
28 delete *.obj;*,libz.olb;*
29
30
31 # Other dependencies.
32 adler32.obj : zutil.h zlib.h zconf.h
33 compress.obj : zlib.h zconf.h
34 crc32.obj : zutil.h zlib.h zconf.h
35 deflate.obj : deflate.h zutil.h zlib.h zconf.h
36 example.obj : zlib.h zconf.h
37 gzio.obj : zutil.h zlib.h zconf.h
38 infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
39 infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
40 inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
41 inflate.obj : zutil.h zlib.h zconf.h infblock.h
42 inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
43 infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
44 minigzip.obj : zlib.h zconf.h
45 trees.obj : deflate.h zutil.h zlib.h zconf.h
46 uncompr.obj : zlib.h zconf.h
47 zutil.obj : zutil.h zlib.h zconf.h
0 # Makefile for zlib under OS/2 using GCC (PGCC)
1 # For conditions of distribution and use, see copyright notice in zlib.h
2
3 # To compile and test, type:
4 # cp Makefile.os2 ..
5 # cd ..
6 # make -f Makefile.os2 test
7
8 # This makefile will build a static library z.lib, a shared library
9 # z.dll and a import library zdll.lib. You can use either z.lib or
10 # zdll.lib by specifying either -lz or -lzdll on gcc's command line
11
12 CC=gcc -Zomf -s
13
14 CFLAGS=-O6 -Wall
15 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
16 #CFLAGS=-g -DDEBUG
17 #CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
18 # -Wstrict-prototypes -Wmissing-prototypes
19
20 #################### BUG WARNING: #####################
21 ## infcodes.c hits a bug in pgcc-1.0, so you have to use either
22 ## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
23 ## This bug is reportedly fixed in pgcc >1.0, but this was not tested
24 CFLAGS+=-fno-force-mem
25
26 LDFLAGS=-s -L. -lzdll -Zcrtdll
27 LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
28
29 VER=1.1.0
30 ZLIB=z.lib
31 SHAREDLIB=z.dll
32 SHAREDLIBIMP=zdll.lib
33 LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
34
35 AR=emxomfar cr
36 IMPLIB=emximp
37 RANLIB=echo
38 TAR=tar
39 SHELL=bash
40
41 prefix=/usr/local
42 exec_prefix = $(prefix)
43
44 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
45 zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
46
47 TEST_OBJS = example.o minigzip.o
48
49 DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
50 algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
51 nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
52 contrib/asm386/*.asm contrib/asm386/*.c \
53 contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
54 contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
55 contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
56
57 all: example.exe minigzip.exe
58
59 test: all
60 @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
61 echo hello world | ./minigzip | ./minigzip -d || \
62 echo ' *** minigzip test FAILED ***' ; \
63 if ./example; then \
64 echo ' *** zlib test OK ***'; \
65 else \
66 echo ' *** zlib test FAILED ***'; \
67 fi
68
69 $(ZLIB): $(OBJS)
70 $(AR) $@ $(OBJS)
71 -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
72
73 $(SHAREDLIB): $(OBJS) os2/z.def
74 $(LDSHARED) -o $@ $^
75
76 $(SHAREDLIBIMP): os2/z.def
77 $(IMPLIB) -o $@ $^
78
79 example.exe: example.o $(LIBS)
80 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
81
82 minigzip.exe: minigzip.o $(LIBS)
83 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
84
85 clean:
86 rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
87
88 distclean: clean
89
90 zip:
91 mv Makefile Makefile~; cp -p Makefile.in Makefile
92 rm -f test.c ztest*.c
93 v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
94 zip -ul9 zlib$$v $(DISTFILES)
95 mv Makefile~ Makefile
96
97 dist:
98 mv Makefile Makefile~; cp -p Makefile.in Makefile
99 rm -f test.c ztest*.c
100 d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
101 rm -f $$d.tar.gz; \
102 if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
103 files=""; \
104 for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
105 cd ..; \
106 GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
107 if test ! -d $$d; then rm -f $$d; fi
108 mv Makefile~ Makefile
109
110 tags:
111 etags *.[ch]
112
113 depend:
114 makedepend -- $(CFLAGS) -- *.[ch]
115
116 # DO NOT DELETE THIS LINE -- make depend depends on it.
117
118 adler32.o: zlib.h zconf.h
119 compress.o: zlib.h zconf.h
120 crc32.o: zlib.h zconf.h
121 deflate.o: deflate.h zutil.h zlib.h zconf.h
122 example.o: zlib.h zconf.h
123 gzio.o: zutil.h zlib.h zconf.h
124 infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
125 infcodes.o: zutil.h zlib.h zconf.h
126 infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
127 inffast.o: zutil.h zlib.h zconf.h inftrees.h
128 inffast.o: infblock.h infcodes.h infutil.h inffast.h
129 inflate.o: zutil.h zlib.h zconf.h infblock.h
130 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
131 infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
132 minigzip.o: zlib.h zconf.h
133 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
134 uncompr.o: zlib.h zconf.h
135 zutil.o: zutil.h zlib.h zconf.h
0 ;
1 ; Slightly modified version of ../nt/zlib.dnt :-)
2 ;
3
4 LIBRARY Z
5 DESCRIPTION "Zlib compression library for OS/2"
6 CODE PRELOAD MOVEABLE DISCARDABLE
7 DATA PRELOAD MOVEABLE MULTIPLE
8
9 EXPORTS
10 adler32
11 compress
12 crc32
13 deflate
14 deflateCopy
15 deflateEnd
16 deflateInit2_
17 deflateInit_
18 deflateParams
19 deflateReset
20 deflateSetDictionary
21 gzclose
22 gzdopen
23 gzerror
24 gzflush
25 gzopen
26 gzread
27 gzwrite
28 inflate
29 inflateEnd
30 inflateInit2_
31 inflateInit_
32 inflateReset
33 inflateSetDictionary
34 inflateSync
35 uncompress
36 zlibVersion
37 gzprintf
38 gzputc
39 gzgetc
40 gzseek
41 gzrewind
42 gztell
43 gzeof
44 gzsetparams
45 zError
46 inflateSyncPoint
47 get_crc_table
48 compress2
49 gzputs
50 gzgets
0 See below some functions declarations for Visual Basic.
1
2 Frequently Asked Question:
3
4 Q: Each time I use the compress function I get the -5 error (not enough
5 room in the output buffer).
6
7 A: Make sure that the length of the compressed buffer is passed by
8 reference ("as any"), not by value ("as long"). Also check that
9 before the call of compress this length is equal to the total size of
10 the compressed buffer and not zero.
11
12
13 From: "Jon Caruana" <jon-net@usa.net>
14 Subject: Re: How to port zlib declares to vb?
15 Date: Mon, 28 Oct 1996 18:33:03 -0600
16
17 Got the answer! (I haven't had time to check this but it's what I got, and
18 looks correct):
19
20 He has the following routines working:
21 compress
22 uncompress
23 gzopen
24 gzwrite
25 gzread
26 gzclose
27
28 Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
29
30 #If Win16 Then 'Use Win16 calls.
31 Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
32 String, comprLen As Any, ByVal buf As String, ByVal buflen
33 As Long) As Integer
34 Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
35 As String, uncomprLen As Any, ByVal compr As String, ByVal
36 lcompr As Long) As Integer
37 Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
38 String, ByVal mode As String) As Long
39 Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
40 Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
41 As Integer
42 Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
43 Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
44 As Integer
45 Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
46 Long) As Integer
47 #Else
48 Declare Function compress Lib "ZLIB32.DLL"
49 (ByVal compr As String, comprLen As Any, ByVal buf As
50 String, ByVal buflen As Long) As Integer
51 Declare Function uncompress Lib "ZLIB32.DLL"
52 (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
53 String, ByVal lcompr As Long) As Long
54 Declare Function gzopen Lib "ZLIB32.DLL"
55 (ByVal file As String, ByVal mode As String) As Long
56 Declare Function gzread Lib "ZLIB32.DLL"
57 (ByVal file As Long, ByVal uncompr As String, ByVal
58 uncomprLen As Long) As Long
59 Declare Function gzwrite Lib "ZLIB32.DLL"
60 (ByVal file As Long, ByVal uncompr As String, ByVal
61 uncomprLen As Long) As Long
62 Declare Function gzclose Lib "ZLIB32.DLL"
63 (ByVal file As Long) As Long
64 #End If
65
66 -Jon Caruana
67 jon-net@usa.net
68 Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
69
70
71 Here is another example from Michael <michael_borgsys@hotmail.com> that he
72 says conforms to the VB guidelines, and that solves the problem of not
73 knowing the uncompressed size by storing it at the end of the file:
74
75 'Calling the functions:
76 'bracket meaning: <parameter> [optional] {Range of possible values}
77 'Call subCompressFile(<path with filename to compress> [, <path with
78 filename to write to>, [level of compression {1..9}]])
79 'Call subUncompressFile(<path with filename to compress>)
80
81 Option Explicit
82 Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
83 Private Const SUCCESS As Long = 0
84 Private Const strFilExt As String = ".cpr"
85 Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
86 dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
87 ByVal level As Integer) As Long
88 Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
89 dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
90 As Long
91
92 Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
93 strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
94 Dim strCprPth As String
95 Dim lngOriSiz As Long
96 Dim lngCprSiz As Long
97 Dim bytaryOri() As Byte
98 Dim bytaryCpr() As Byte
99 lngOriSiz = FileLen(strargOriFilPth)
100 ReDim bytaryOri(lngOriSiz - 1)
101 Open strargOriFilPth For Binary Access Read As #1
102 Get #1, , bytaryOri()
103 Close #1
104 strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
105 'Select file path and name
106 strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
107 strFilExt, "", strFilExt) 'Add file extension if not exists
108 lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
109 more space then original file size
110 ReDim bytaryCpr(lngCprSiz - 1)
111 If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
112 SUCCESS Then
113 lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
114 ReDim Preserve bytaryCpr(lngCprSiz - 1)
115 Open strCprPth For Binary Access Write As #1
116 Put #1, , bytaryCpr()
117 Put #1, , lngOriSiz 'Add the the original size value to the end
118 (last 4 bytes)
119 Close #1
120 Else
121 MsgBox "Compression error"
122 End If
123 Erase bytaryCpr
124 Erase bytaryOri
125 End Sub
126
127 Public Sub subUncompressFile(ByVal strargFilPth As String)
128 Dim bytaryCpr() As Byte
129 Dim bytaryOri() As Byte
130 Dim lngOriSiz As Long
131 Dim lngCprSiz As Long
132 Dim strOriPth As String
133 lngCprSiz = FileLen(strargFilPth)
134 ReDim bytaryCpr(lngCprSiz - 1)
135 Open strargFilPth For Binary Access Read As #1
136 Get #1, , bytaryCpr()
137 Close #1
138 'Read the original file size value:
139 lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
140 + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
141 + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
142 + bytaryCpr(lngCprSiz - 4)
143 ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
144 ReDim bytaryOri(lngOriSiz - 1)
145 If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
146 Then
147 strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
148 Open strOriPth For Binary Access Write As #1
149 Put #1, , bytaryOri()
150 Close #1
151 Else
152 MsgBox "Uncompression error"
153 End If
154 Erase bytaryCpr
155 Erase bytaryOri
156 End Sub
157 Public Property Get lngPercentSmaller() As Long
158 lngPercentSmaller = lngpvtPcnSml
159 End Property
0 <html>
1 <head>
2 <title>
3 zlib general purpose compression library version 1.1.4
4 </title>
5 </head>
6 <body bgcolor="White" text="Black" vlink="Red" alink="Navy" link="Red">
7 <!-- background="zlibbg.gif" -->
8
9 <h1> zlib 1.1.4 Manual </h1>
10 <hr>
11 <a name="Contents"><h2>Contents</h2>
12 <ol type="I">
13 <li> <a href="#Prologue">Prologue</a>
14 <li> <a href="#Introduction">Introduction</a>
15 <li> <a href="#Utility functions">Utility functions</a>
16 <li> <a href="#Basic functions">Basic functions</a>
17 <li> <a href="#Advanced functions">Advanced functions</a>
18 <li> <a href="#Constants">Constants</a>
19 <li> <a href="#struct z_stream_s">struct z_stream_s</a>
20 <li> <a href="#Checksum functions">Checksum functions</a>
21 <li> <a href="#Misc">Misc</a>
22 </ol>
23 <hr>
24 <a name="Prologue"><h2> Prologue </h2>
25 'zlib' general purpose compression library version 1.1.4, March 11th, 2002
26 <p>
27 Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
28 <p>
29 This software is provided 'as-is', without any express or implied
30 warranty. In no event will the authors be held liable for any damages
31 arising from the use of this software.
32 <p>
33 Permission is granted to anyone to use this software for any purpose,
34 including commercial applications, and to alter it and redistribute it
35 freely, subject to the following restrictions:
36 <ol>
37 <li> The origin of this software must not be misrepresented ; you must not
38 claim that you wrote the original software. If you use this software
39 in a product, an acknowledgment in the product documentation would be
40 appreciated but is not required.
41 <li> Altered source versions must be plainly marked as such, and must not be
42 misrepresented as being the original software.
43 <li> This notice may not be removed or altered from any source distribution.
44 </ol>
45
46 <dl>
47 <dt>Jean-loup Gailly
48 <dd><a href="mailto:jloup@gzip.org">jloup@gzip.org</a>
49 <dt>Mark Adler
50 <dd><a href="mailto:madler@alumni.caltech.edu">madler@alumni.caltech.edu</a>
51 </dl>
52
53 The data format used by the zlib library is described by RFCs (Request for
54 Comments) 1950 to 1952 in the files
55 <a href="ftp://ds.internic.net/rfc/rfc1950.txt">
56 ftp://ds.internic.net/rfc/rfc1950.txt </a>
57 (zlib format),
58 <a href="ftp://ds.internic.net/rfc/rfc1951.txt">
59 rfc1951.txt </a>
60 (<a href="#deflate">deflate</a> format) and
61 <a href="ftp://ds.internic.net/rfc/rfc1952.txt">
62 rfc1952.txt </a>
63 (gzip format).
64 <p>
65 This manual is converted from zlib.h by
66 <a href="mailto:piaip@csie.ntu.edu.tw"> piaip </a>
67 <p>
68 Visit <a href="http://ftp.cdrom.com/pub/infozip/zlib/">
69 http://ftp.cdrom.com/pub/infozip/zlib/</a>
70 for the official zlib web page.
71 <p>
72
73 <hr>
74 <a name="Introduction"><h2> Introduction </h2>
75 The 'zlib' compression library provides in-memory compression and
76 decompression functions, including integrity checks of the uncompressed
77 data. This version of the library supports only one compression method
78 (deflation) but other algorithms will be added later and will have the same
79 stream interface.
80 <p>
81
82 Compression can be done in a single step if the buffers are large
83 enough (for example if an input file is mmap'ed), or can be done by
84 repeated calls of the compression function. In the latter case, the
85 application must provide more input and/or consume the output
86 (providing more output space) before each call.
87 <p>
88
89 The library also supports reading and writing files in gzip (.gz) format
90 with an interface similar to that of stdio.
91 <p>
92
93 The library does not install any signal handler. The decoder checks
94 the consistency of the compressed data, so the library should never
95 crash even in case of corrupted input.
96 <p>
97
98 <hr>
99 <a name="Utility functions"><h2> Utility functions </h2>
100 The following utility functions are implemented on top of the
101 <a href="#Basic functions">basic stream-oriented functions</a>.
102 To simplify the interface, some
103 default options are assumed (compression level and memory usage,
104 standard memory allocation functions). The source code of these
105 utility functions can easily be modified if you need special options.
106 <h3> Function list </h3>
107 <ul>
108 <li> int <a href="#compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
109 <li> int <a href="#compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);
110 <li> int <a href="#uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
111 <li> typedef voidp gzFile;
112 <li> gzFile <a href="#gzopen">gzopen</a> (const char *path, const char *mode);
113 <li> gzFile <a href="#gzdopen">gzdopen</a> (int fd, const char *mode);
114 <li> int <a href="#gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);
115 <li> int <a href="#gzread">gzread</a> (gzFile file, voidp buf, unsigned len);
116 <li> int <a href="#gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);
117 <li> int VA <a href="#gzprintf">gzprintf</a> (gzFile file, const char *format, ...);
118 <li> int <a href="#gzputs">gzputs</a> (gzFile file, const char *s);
119 <li> char * <a href="#gzgets">gzgets</a> (gzFile file, char *buf, int len);
120 <li> int <a href="#gzputc">gzputc</a> (gzFile file, int c);
121 <li> int <a href="#gzgetc">gzgetc</a> (gzFile file);
122 <li> int <a href="#gzflush">gzflush</a> (gzFile file, int flush);
123 <li> z_off_t <a href="#gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);
124 <li> z_off_t <a href="#gztell">gztell</a> (gzFile file);
125 <li> int <a href="#gzrewind">gzrewind</a> (gzFile file);
126 <li> int <a href="#gzeof">gzeof</a> (gzFile file);
127 <li> int <a href="#gzclose">gzclose</a> (gzFile file);
128 <li> const char * <a href="#gzerror">gzerror</a> (gzFile file, int *errnum);
129 </ul>
130 <h3> Function description </h3>
131 <dl>
132 <font color="Blue"><dt> int <a name="compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
133 <dd>
134 Compresses the source buffer into the destination buffer. sourceLen is
135 the byte length of the source buffer. Upon entry, destLen is the total
136 size of the destination buffer, which must be at least 0.1% larger than
137 sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
138 compressed buffer.<p>
139 This function can be used to <a href="#compress">compress</a> a whole file at once if the
140 input file is mmap'ed.<p>
141 <a href="#compress">compress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
142 enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
143 buffer.<p>
144
145 <font color="Blue"><dt> int <a name="compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);</font>
146 <dd>
147 Compresses the source buffer into the destination buffer. The level
148 parameter has the same meaning as in <a href="#deflateInit">deflateInit</a>. sourceLen is the byte
149 length of the source buffer. Upon entry, destLen is the total size of the
150 destination buffer, which must be at least 0.1% larger than sourceLen plus
151 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
152 <p>
153
154 <a href="#compress2">compress2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
155 memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output buffer,
156 <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the level parameter is invalid.
157 <p>
158
159 <font color="Blue"><dt> int <a name="uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font>
160 <dd>
161 Decompresses the source buffer into the destination buffer. sourceLen is
162 the byte length of the source buffer. Upon entry, destLen is the total
163 size of the destination buffer, which must be large enough to hold the
164 entire uncompressed data. (The size of the uncompressed data must have
165 been saved previously by the compressor and transmitted to the decompressor
166 by some mechanism outside the scope of this compression library.)
167 Upon exit, destLen is the actual size of the compressed buffer. <p>
168 This function can be used to decompress a whole file at once if the
169 input file is mmap'ed.
170 <p>
171
172 <a href="#uncompress">uncompress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
173 enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output
174 buffer, or <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was corrupted.
175 <p>
176
177 <dt> typedef voidp gzFile;
178 <dd> <p>
179
180 <font color="Blue"><dt> gzFile <a name="gzopen">gzopen</a> (const char *path, const char *mode);</font>
181 <dd>
182 Opens a gzip (.gz) file for reading or writing. The mode parameter
183 is as in fopen ("rb" or "wb") but can also include a compression level
184 ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
185 Huffman only compression as in "wb1h". (See the description
186 of <a href="#deflateInit2">deflateInit2</a> for more information about the strategy parameter.)
187 <p>
188
189 <a href="#gzopen">gzopen</a> can be used to read a file which is not in gzip format ; in this
190 case <a href="#gzread">gzread</a> will directly read from the file without decompression.
191 <p>
192
193 <a href="#gzopen">gzopen</a> returns NULL if the file could not be opened or if there was
194 insufficient memory to allocate the (de)compression <a href="#state">state</a> ; errno
195 can be checked to distinguish the two cases (if errno is zero, the
196 zlib error is <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a>).
197 <p>
198
199 <font color="Blue"><dt> gzFile <a name="gzdopen">gzdopen</a> (int fd, const char *mode);</font>
200 <dd>
201 <a href="#gzdopen">gzdopen</a>() associates a gzFile with the file descriptor fd. File
202 descriptors are obtained from calls like open, dup, creat, pipe or
203 fileno (in the file has been previously opened with fopen).
204 The mode parameter is as in <a href="#gzopen">gzopen</a>.
205 <p>
206 The next call of <a href="#gzclose">gzclose</a> on the returned gzFile will also close the
207 file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
208 descriptor fd. If you want to keep fd open, use <a href="#gzdopen">gzdopen</a>(dup(fd), mode).
209 <p>
210 <a href="#gzdopen">gzdopen</a> returns NULL if there was insufficient memory to allocate
211 the (de)compression <a href="#state">state</a>.
212 <p>
213
214 <font color="Blue"><dt> int <a name="gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);</font>
215 <dd>
216 Dynamically update the compression level or strategy. See the description
217 of <a href="#deflateInit2">deflateInit2</a> for the meaning of these parameters.
218 <p>
219 <a href="#gzsetparams">gzsetparams</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the file was not
220 opened for writing.
221 <p>
222
223 <font color="Blue"><dt> int <a name="gzread">gzread</a> (gzFile file, voidp buf, unsigned len);</font>
224 <dd>
225 Reads the given number of uncompressed bytes from the compressed file.
226 If the input file was not in gzip format, <a href="#gzread">gzread</a> copies the given number
227 of bytes into the buffer.
228 <p>
229 <a href="#gzread">gzread</a> returns the number of uncompressed bytes actually read (0 for
230 end of file, -1 for error).
231 <p>
232
233 <font color="Blue"><dt> int <a name="gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);</font>
234 <dd>
235 Writes the given number of uncompressed bytes into the compressed file.
236 <a href="#gzwrite">gzwrite</a> returns the number of uncompressed bytes actually written
237 (0 in case of error).
238 <p>
239
240 <font color="Blue"><dt> int VA <a name="gzprintf">gzprintf</a> (gzFile file, const char *format, ...);</font>
241 <dd>
242 Converts, formats, and writes the args to the compressed file under
243 control of the format string, as in fprintf. <a href="#gzprintf">gzprintf</a> returns the number of
244 uncompressed bytes actually written (0 in case of error).
245 <p>
246
247 <font color="Blue"><dt> int <a name="gzputs">gzputs</a> (gzFile file, const char *s);</font>
248 <dd>
249 Writes the given null-terminated string to the compressed file, excluding
250 the terminating null character.
251 <p>
252 <a href="#gzputs">gzputs</a> returns the number of characters written, or -1 in case of error.
253 <p>
254
255 <font color="Blue"><dt> char * <a name="gzgets">gzgets</a> (gzFile file, char *buf, int len);</font>
256 <dd>
257 Reads bytes from the compressed file until len-1 characters are read, or
258 a newline character is read and transferred to buf, or an end-of-file
259 condition is encountered. The string is then terminated with a null
260 character.
261 <p>
262 <a href="#gzgets">gzgets</a> returns buf, or <a href="#Z_NULL">Z_NULL</a> in case of error.
263 <p>
264
265 <font color="Blue"><dt> int <a name="gzputc">gzputc</a> (gzFile file, int c);</font>
266 <dd>
267 Writes c, converted to an unsigned char, into the compressed file.
268 <a href="#gzputc">gzputc</a> returns the value that was written, or -1 in case of error.
269 <p>
270
271 <font color="Blue"><dt> int <a name="gzgetc">gzgetc</a> (gzFile file);</font>
272 <dd>
273 Reads one byte from the compressed file. <a href="#gzgetc">gzgetc</a> returns this byte
274 or -1 in case of end of file or error.
275 <p>
276
277 <font color="Blue"><dt> int <a name="gzflush">gzflush</a> (gzFile file, int flush);</font>
278 <dd>
279 Flushes all pending output into the compressed file. The parameter
280 flush is as in the <a href="#deflate">deflate</a>() function. The return value is the zlib
281 error number (see function <a href="#gzerror">gzerror</a> below). <a href="#gzflush">gzflush</a> returns <a href="#Z_OK">Z_OK</a> if
282 the flush parameter is <a href="#Z_FINISH">Z_FINISH</a> and all output could be flushed.
283 <p>
284 <a href="#gzflush">gzflush</a> should be called only when strictly necessary because it can
285 degrade compression.
286 <p>
287
288 <font color="Blue"><dt> z_off_t <a name="gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);</font>
289 <dd>
290 Sets the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the
291 given compressed file. The offset represents a number of bytes in the
292 uncompressed data stream. The whence parameter is defined as in lseek(2);
293 the value SEEK_END is not supported.
294 <p>
295 If the file is opened for reading, this function is emulated but can be
296 extremely slow. If the file is opened for writing, only forward seeks are
297 supported ; <a href="#gzseek">gzseek</a> then compresses a sequence of zeroes up to the new
298 starting position.
299 <p>
300 <a href="#gzseek">gzseek</a> returns the resulting offset location as measured in bytes from
301 the beginning of the uncompressed stream, or -1 in case of error, in
302 particular if the file is opened for writing and the new starting position
303 would be before the current position.
304 <p>
305
306 <font color="Blue"><dt> int <a name="gzrewind">gzrewind</a> (gzFile file);</font>
307 <dd>
308 Rewinds the given file. This function is supported only for reading.
309 <p>
310 <a href="#gzrewind">gzrewind</a>(file) is equivalent to (int)<a href="#gzseek">gzseek</a>(file, 0L, SEEK_SET)
311 <p>
312
313 <font color="Blue"><dt> z_off_t <a name="gztell">gztell</a> (gzFile file);</font>
314 <dd>
315 Returns the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the
316 given compressed file. This position represents a number of bytes in the
317 uncompressed data stream.
318 <p>
319
320 <a href="#gztell">gztell</a>(file) is equivalent to <a href="#gzseek">gzseek</a>(file, 0L, SEEK_CUR)
321 <p>
322
323 <font color="Blue"><dt> int <a name="gzeof">gzeof</a> (gzFile file);</font>
324 <dd>
325 Returns 1 when EOF has previously been detected reading the given
326 input stream, otherwise zero.
327 <p>
328
329 <font color="Blue"><dt> int <a name="gzclose">gzclose</a> (gzFile file);</font>
330 <dd>
331 Flushes all pending output if necessary, closes the compressed file
332 and deallocates all the (de)compression <a href="#state">state</a>. The return value is the zlib
333 error number (see function <a href="#gzerror">gzerror</a> below).
334 <p>
335
336 <font color="Blue"><dt> const char * <a name="gzerror">gzerror</a> (gzFile file, int *errnum);</font>
337 <dd>
338 Returns the error message for the last error which occurred on the
339 given compressed file. errnum is set to zlib error number. If an
340 error occurred in the file system and not in the compression library,
341 errnum is set to <a href="#Z_ERRNO">Z_ERRNO</a> and the application may consult errno
342 to get the exact error code.
343 <p>
344 </dl>
345 <hr>
346 <a name="Basic functions"><h2> Basic functions </h2>
347 <h3> Function list </h3>
348 <ul>
349 <li> const char * <a href="#zlibVersion">zlibVersion</a> (void);
350 <li> int <a href="#deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);
351 <li> int <a href="#deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
352 <li> int <a href="#deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
353 <li> int <a href="#inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);
354 <li> int <a href="#inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);
355 <li> int <a href="#inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);
356 </ul>
357
358 <h3> Function description </h3>
359 <dl>
360 <font color="Blue"><dt> const char * <a name="zlibVersion">zlibVersion</a> (void);</font>
361 <dd> The application can compare <a href="#zlibVersion">zlibVersion</a> and ZLIB_VERSION for consistency.
362 If the first character differs, the library code actually used is
363 not compatible with the zlib.h header file used by the application.
364 This check is automatically made by <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a>.
365 <p>
366
367 <font color="Blue"><dt> int <a name="deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);</font>
368 <dd>
369 Initializes the internal stream <a href="#state">state</a> for compression. The fields
370 <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by the caller.
371 If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#deflateInit">deflateInit</a> updates them to
372 use default allocation functions.
373 <p>
374
375 The compression level must be <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a>, or between 0 and 9:
376 1 gives best speed, 9 gives best compression, 0 gives no compression at
377 all (the input data is simply copied a block at a time).
378 <p>
379
380 <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> requests a default compromise between speed and
381 compression (currently equivalent to level 6).
382 <p>
383
384 <a href="#deflateInit">deflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
385 enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if level is not a valid compression level,
386 <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version (<a href="#zlib_version">zlib_version</a>) is incompatible
387 with the version assumed by the caller (ZLIB_VERSION).
388 <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit">deflateInit</a> does not
389 perform any compression: this will be done by <a href="#deflate">deflate</a>().
390 <p>
391
392 <font color="Blue"><dt> int <a name="deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
393 <dd>
394 <a href="#deflate">deflate</a> compresses as much data as possible, and stops when the input
395 buffer becomes empty or the output buffer becomes full. It may introduce some
396 output latency (reading input without producing any output) except when
397 forced to flush.<p>
398
399 The detailed semantics are as follows. <a href="#deflate">deflate</a> performs one or both of the
400 following actions:
401
402 <ul>
403 <li> Compress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
404 accordingly. If not all input can be processed (because there is not
405 enough room in the output buffer), <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> are updated and
406 processing will resume at this point for the next call of <a href="#deflate">deflate</a>().
407
408 <li>
409 Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a>
410 accordingly. This action is forced if the parameter flush is non zero.
411 Forcing flush frequently degrades the compression ratio, so this parameter
412 should be set only when necessary (in interactive applications).
413 Some output may be provided even if flush is not set.
414 </ul> <p>
415
416 Before the call of <a href="#deflate">deflate</a>(), the application should ensure that at least
417 one of the actions is possible, by providing more input and/or consuming
418 more output, and updating <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> accordingly ; <a href="#avail_out">avail_out</a>
419 should never be zero before the call. The application can consume the
420 compressed output when it wants, for example when the output buffer is full
421 (<a href="#avail_out">avail_out</a> == 0), or after each call of <a href="#deflate">deflate</a>(). If <a href="#deflate">deflate</a> returns <a href="#Z_OK">Z_OK</a>
422 and with zero <a href="#avail_out">avail_out</a>, it must be called again after making room in the
423 output buffer because there might be more output pending.
424 <p>
425
426 If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, all pending output is
427 flushed to the output buffer and the output is aligned on a byte boundary, so
428 that the decompressor can get all input data available so far. (In particular
429 <a href="#avail_in">avail_in</a> is zero after the call if enough output space has been provided
430 before the call.) Flushing may degrade compression for some compression
431 algorithms and so it should be used only when necessary.
432 <p>
433
434 If flush is set to <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>, all output is flushed as with
435 <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, and the compression <a href="#state">state</a> is reset so that decompression can
436 restart from this point if previous compressed data has been damaged or if
437 random access is desired. Using <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a> too often can seriously degrade
438 the compression.
439 <p>
440
441 If <a href="#deflate">deflate</a> returns with <a href="#avail_out">avail_out</a> == 0, this function must be called again
442 with the same value of the flush parameter and more output space (updated
443 <a href="#avail_out">avail_out</a>), until the flush is complete (<a href="#deflate">deflate</a> returns with non-zero
444 <a href="#avail_out">avail_out</a>).
445 <p>
446
447 If the parameter flush is set to <a href="#Z_FINISH">Z_FINISH</a>, pending input is processed,
448 pending output is flushed and <a href="#deflate">deflate</a> returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> if there
449 was enough output space ; if <a href="#deflate">deflate</a> returns with <a href="#Z_OK">Z_OK</a>, this function must be
450 called again with <a href="#Z_FINISH">Z_FINISH</a> and more output space (updated <a href="#avail_out">avail_out</a>) but no
451 more input data, until it returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> or an error. After
452 <a href="#deflate">deflate</a> has returned <a href="#Z_STREAM_END">Z_STREAM_END</a>, the only possible operations on the
453 stream are <a href="#deflateReset">deflateReset</a> or <a href="#deflateEnd">deflateEnd</a>.
454 <p>
455
456 <a href="#Z_FINISH">Z_FINISH</a> can be used immediately after <a href="#deflateInit">deflateInit</a> if all the compression
457 is to be done in a single step. In this case, <a href="#avail_out">avail_out</a> must be at least
458 0.1% larger than <a href="#avail_in">avail_in</a> plus 12 bytes. If <a href="#deflate">deflate</a> does not return
459 <a href="#Z_STREAM_END">Z_STREAM_END</a>, then it must be called again as described above.
460 <p>
461
462 <a href="#deflate">deflate</a>() sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all input read
463 so far (that is, <a href="#total_in">total_in</a> bytes).
464 <p>
465
466 <a href="#deflate">deflate</a>() may update <a href="#data_type">data_type</a> if it can make a good guess about
467 the input data type (<a href="#Z_ASCII">Z_ASCII</a> or <a href="#Z_BINARY">Z_BINARY</a>). In doubt, the data is considered
468 binary. This field is only for information purposes and does not affect
469 the compression algorithm in any manner.
470 <p>
471
472 <a href="#deflate">deflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input
473 processed or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if all input has been
474 consumed and all output has been produced (only when flush is set to
475 <a href="#Z_FINISH">Z_FINISH</a>), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a> was inconsistent (for example
476 if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible
477 (for example <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> was zero).
478 <p>
479
480 <font color="Blue"><dt> int <a name="deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
481 <dd>
482 All dynamically allocated data structures for this stream are freed.
483 This function discards any unprocessed input and does not flush any
484 pending output.
485 <p>
486
487 <a href="#deflateEnd">deflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the
488 stream <a href="#state">state</a> was inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the stream was freed
489 prematurely (some input or output was discarded). In the error case,
490 <a href="#msg">msg</a> may be set but then points to a static string (which must not be
491 deallocated).
492 <p>
493
494 <font color="Blue"><dt> int <a name="inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
495 <dd>
496 Initializes the internal stream <a href="#state">state</a> for decompression. The fields
497 <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
498 the caller. If <a href="#next_in">next_in</a> is not <a href="#Z_NULL">Z_NULL</a> and <a href="#avail_in">avail_in</a> is large enough (the exact
499 value depends on the compression method), <a href="#inflateInit">inflateInit</a> determines the
500 compression method from the zlib header and allocates all data structures
501 accordingly ; otherwise the allocation will be deferred to the first call of
502 <a href="#inflate">inflate</a>. If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#inflateInit">inflateInit</a> updates them to
503 use default allocation functions.
504 <p>
505
506 <a href="#inflateInit">inflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
507 memory, <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version is incompatible with the
508 version assumed by the caller. <a href="#msg">msg</a> is set to null if there is no error
509 message. <a href="#inflateInit">inflateInit</a> does not perform any decompression apart from reading
510 the zlib header if present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and
511 <a href="#avail_in">avail_in</a> may be modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)
512 <p>
513
514 <font color="Blue"><dt> int <a name="inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font>
515 <dd>
516 <a href="#inflate">inflate</a> decompresses as much data as possible, and stops when the input
517 buffer becomes empty or the output buffer becomes full. It may some
518 introduce some output latency (reading input without producing any output)
519 except when forced to flush.
520 <p>
521
522 The detailed semantics are as follows. <a href="#inflate">inflate</a> performs one or both of the
523 following actions:
524
525 <ul>
526 <li> Decompress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a>
527 accordingly. If not all input can be processed (because there is not
528 enough room in the output buffer), <a href="#next_in">next_in</a> is updated and processing
529 will resume at this point for the next call of <a href="#inflate">inflate</a>().
530
531 <li> Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and
532 <a href="#avail_out">avail_out</a> accordingly. <a href="#inflate">inflate</a>() provides as much output as possible,
533 until there is no more input data or no more space in the output buffer
534 (see below about the flush parameter).
535 </ul> <p>
536
537 Before the call of <a href="#inflate">inflate</a>(), the application should ensure that at least
538 one of the actions is possible, by providing more input and/or consuming
539 more output, and updating the next_* and avail_* values accordingly.
540 The application can consume the uncompressed output when it wants, for
541 example when the output buffer is full (<a href="#avail_out">avail_out</a> == 0), or after each
542 call of <a href="#inflate">inflate</a>(). If <a href="#inflate">inflate</a> returns <a href="#Z_OK">Z_OK</a> and with zero <a href="#avail_out">avail_out</a>, it
543 must be called again after making room in the output buffer because there
544 might be more output pending.
545 <p>
546
547 If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, <a href="#inflate">inflate</a> flushes as much
548 output as possible to the output buffer. The flushing behavior of <a href="#inflate">inflate</a> is
549 not specified for values of the flush parameter other than <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>
550 and <a href="#Z_FINISH">Z_FINISH</a>, but the current implementation actually flushes as much output
551 as possible anyway.
552 <p>
553
554 <a href="#inflate">inflate</a>() should normally be called until it returns <a href="#Z_STREAM_END">Z_STREAM_END</a> or an
555 error. However if all decompression is to be performed in a single step
556 (a single call of <a href="#inflate">inflate</a>), the parameter flush should be set to
557 <a href="#Z_FINISH">Z_FINISH</a>. In this case all pending input is processed and all pending
558 output is flushed ; <a href="#avail_out">avail_out</a> must be large enough to hold all the
559 uncompressed data. (The size of the uncompressed data may have been saved
560 by the compressor for this purpose.) The next operation on this stream must
561 be <a href="#inflateEnd">inflateEnd</a> to deallocate the decompression <a href="#state">state</a>. The use of <a href="#Z_FINISH">Z_FINISH</a>
562 is never required, but can be used to inform <a href="#inflate">inflate</a> that a faster routine
563 may be used for the single <a href="#inflate">inflate</a>() call.
564 <p>
565
566 If a preset dictionary is needed at this point (see <a href="#inflateSetDictionary">inflateSetDictionary</a>
567 below), <a href="#inflate">inflate</a> sets strm-<a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of the
568 dictionary chosen by the compressor and returns <a href="#Z_NEED_DICT">Z_NEED_DICT</a> ; otherwise
569 it sets strm-&gt <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all output produced
570 so far (that is, <a href="#total_out">total_out</a> bytes) and returns <a href="#Z_OK">Z_OK</a>, <a href="#Z_STREAM_END">Z_STREAM_END</a> or
571 an error code as described below. At the end of the stream, <a href="#inflate">inflate</a>()
572 checks that its computed <a href="#adler32">adler32</a> checksum is equal to that saved by the
573 compressor and returns <a href="#Z_STREAM_END">Z_STREAM_END</a> only if the checksum is correct.
574 <p>
575
576 <a href="#inflate">inflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input processed
577 or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if the end of the compressed data has
578 been reached and all uncompressed output has been produced, <a href="#Z_NEED_DICT">Z_NEED_DICT</a> if a
579 preset dictionary is needed at this point, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was
580 corrupted (input stream not conforming to the zlib format or incorrect
581 <a href="#adler32">adler32</a> checksum), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent
582 (for example if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
583 enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible or if there was not
584 enough room in the output buffer when <a href="#Z_FINISH">Z_FINISH</a> is used. In the <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a>
585 case, the application may then call <a href="#inflateSync">inflateSync</a> to look for a good
586 compression block.
587 <p>
588
589 <font color="Blue"><dt> int <a name="inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
590 <dd>
591 All dynamically allocated data structures for this stream are freed.
592 This function discards any unprocessed input and does not flush any
593 pending output.
594 <p>
595
596 <a href="#inflateEnd">inflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a>
597 was inconsistent. In the error case, <a href="#msg">msg</a> may be set but then points to a
598 static string (which must not be deallocated).
599 </dl>
600 <hr>
601 <a name="Advanced functions"><h2> Advanced functions </h2>
602 The following functions are needed only in some special applications.
603 <h3> Function list </h3>
604 <ul>
605 <li> int <a href="#deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm,
606 <li> int <a href="#deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
607 <li> int <a href="#deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);
608 <li> int <a href="#deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
609 <li> int <a href="#deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);
610 <li> int <a href="#inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);
611 <li> int <a href="#inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);
612 <li> int <a href="#inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);
613 <li> int <a href="#inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);
614
615 </ul>
616 <h3> Function description </h3>
617 <dl>
618 <font color="Blue"><dt> int <a name="deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int method, int windowBits, int memLevel, int strategy);</font>
619
620 <dd> This is another version of <a href="#deflateInit">deflateInit</a> with more compression options. The
621 fields <a href="#next_in">next_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by
622 the caller.<p>
623
624 The method parameter is the compression method. It must be <a href="#Z_DEFLATED">Z_DEFLATED</a> in
625 this version of the library.<p>
626
627 The windowBits parameter is the base two logarithm of the window size
628 (the size of the history buffer). It should be in the range 8..15 for this
629 version of the library. Larger values of this parameter result in better
630 compression at the expense of memory usage. The default value is 15 if
631 <a href="#deflateInit">deflateInit</a> is used instead.<p>
632
633 The memLevel parameter specifies how much memory should be allocated
634 for the internal compression <a href="#state">state</a>. memLevel=1 uses minimum memory but
635 is slow and reduces compression ratio ; memLevel=9 uses maximum memory
636 for optimal speed. The default value is 8. See zconf.h for total memory
637 usage as a function of windowBits and memLevel.<p>
638
639 The strategy parameter is used to tune the compression algorithm. Use the
640 value <a href="#Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> for normal data, <a href="#Z_FILTERED">Z_FILTERED</a> for data produced by a
641 filter (or predictor), or <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> to force Huffman encoding only (no
642 string match). Filtered data consists mostly of small values with a
643 somewhat random distribution. In this case, the compression algorithm is
644 tuned to <a href="#compress">compress</a> them better. The effect of <a href="#Z_FILTERED">Z_FILTERED</a> is to force more
645 Huffman coding and less string matching ; it is somewhat intermediate
646 between Z_DEFAULT and <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a>. The strategy parameter only affects
647 the compression ratio but not the correctness of the compressed output even
648 if it is not set appropriately.<p>
649
650 <a href="#deflateInit2">deflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
651 memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as an invalid
652 method). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit2">deflateInit2</a> does
653 not perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
654
655 <font color="Blue"><dt> int <a name="deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
656 <dd>
657 Initializes the compression dictionary from the given byte sequence
658 without producing any compressed output. This function must be called
659 immediately after <a href="#deflateInit">deflateInit</a>, <a href="#deflateInit2">deflateInit2</a> or <a href="#deflateReset">deflateReset</a>, before any
660 call of <a href="#deflate">deflate</a>. The compressor and decompressor must use exactly the same
661 dictionary (see <a href="#inflateSetDictionary">inflateSetDictionary</a>).<p>
662
663 The dictionary should consist of strings (byte sequences) that are likely
664 to be encountered later in the data to be compressed, with the most commonly
665 used strings preferably put towards the end of the dictionary. Using a
666 dictionary is most useful when the data to be compressed is short and can be
667 predicted with good accuracy ; the data can then be compressed better than
668 with the default empty dictionary.<p>
669
670 Depending on the size of the compression data structures selected by
671 <a href="#deflateInit">deflateInit</a> or <a href="#deflateInit2">deflateInit2</a>, a part of the dictionary may in effect be
672 discarded, for example if the dictionary is larger than the window size in
673 <a href="#deflate">deflate</a> or deflate2. Thus the strings most likely to be useful should be
674 put at the end of the dictionary, not at the front.<p>
675
676 Upon return of this function, strm-&gt <a href="#adler">adler</a> is set to the Adler32 value
677 of the dictionary ; the decompressor may later use this value to determine
678 which dictionary has been used by the compressor. (The Adler32 value
679 applies to the whole dictionary even if only a subset of the dictionary is
680 actually used by the compressor.)<p>
681
682 <a href="#deflateSetDictionary">deflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
683 parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
684 inconsistent (for example if <a href="#deflate">deflate</a> has already been called for this stream
685 or if the compression method is bsort). <a href="#deflateSetDictionary">deflateSetDictionary</a> does not
686 perform any compression: this will be done by <a href="#deflate">deflate</a>().<p>
687
688 <font color="Blue"><dt> int <a name="deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);</font>
689 <dd>
690 Sets the destination stream as a complete copy of the source stream.<p>
691
692 This function can be useful when several compression strategies will be
693 tried, for example when there are several ways of pre-processing the input
694 data with a filter. The streams that will be discarded should then be freed
695 by calling <a href="#deflateEnd">deflateEnd</a>. Note that <a href="#deflateCopy">deflateCopy</a> duplicates the internal
696 compression <a href="#state">state</a> which can be quite large, so this strategy is slow and
697 can consume lots of memory.<p>
698
699 <a href="#deflateCopy">deflateCopy</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not
700 enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source stream <a href="#state">state</a> was inconsistent
701 (such as <a href="#zalloc">zalloc</a> being NULL). <a href="#msg">msg</a> is left unchanged in both source and
702 destination.<p>
703
704 <font color="Blue"><dt> int <a name="deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
705 <dd> This function is equivalent to <a href="#deflateEnd">deflateEnd</a> followed by <a href="#deflateInit">deflateInit</a>,
706 but does not free and reallocate all the internal compression <a href="#state">state</a>.
707 The stream will keep the same compression level and any other attributes
708 that may have been set by <a href="#deflateInit2">deflateInit2</a>.<p>
709
710 <a href="#deflateReset">deflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
711 stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).<p>
712
713 <font color="Blue"><dt> int <a name="deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);</font>
714 <dd>
715 Dynamically update the compression level and compression strategy. The
716 interpretation of level and strategy is as in <a href="#deflateInit2">deflateInit2</a>. This can be
717 used to switch between compression and straight copy of the input data, or
718 to switch to a different kind of input data requiring a different
719 strategy. If the compression level is changed, the input available so far
720 is compressed with the old level (and may be flushed); the new level will
721 take effect only at the next call of <a href="#deflate">deflate</a>().<p>
722
723 Before the call of <a href="#deflateParams">deflateParams</a>, the stream <a href="#state">state</a> must be set as for
724 a call of <a href="#deflate">deflate</a>(), since the currently available input may have to
725 be compressed and flushed. In particular, strm-&gt <a href="#avail_out">avail_out</a> must be
726 non-zero.<p>
727
728 <a href="#deflateParams">deflateParams</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
729 stream <a href="#state">state</a> was inconsistent or if a parameter was invalid, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
730 if strm-&gtavail_out was zero.<p>
731
732 <font color="Blue"><dt> int <a name="inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);</font>
733
734 <dd> This is another version of <a href="#inflateInit">inflateInit</a> with an extra parameter. The
735 fields <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized
736 before by the caller.<p>
737
738 The windowBits parameter is the base two logarithm of the maximum window
739 size (the size of the history buffer). It should be in the range 8..15 for
740 this version of the library. The default value is 15 if <a href="#inflateInit">inflateInit</a> is used
741 instead. If a compressed stream with a larger window size is given as
742 input, <a href="#inflate">inflate</a>() will return with the error code <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> instead of
743 trying to allocate a larger window.<p>
744
745 <a href="#inflateInit2">inflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough
746 memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as a negative
747 memLevel). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#inflateInit2">inflateInit2</a>
748 does not perform any decompression apart from reading the zlib header if
749 present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> may be
750 modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)<p>
751
752 <font color="Blue"><dt> int <a name="inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font>
753 <dd>
754 Initializes the decompression dictionary from the given uncompressed byte
755 sequence. This function must be called immediately after a call of <a href="#inflate">inflate</a>
756 if this call returned <a href="#Z_NEED_DICT">Z_NEED_DICT</a>. The dictionary chosen by the compressor
757 can be determined from the Adler32 value returned by this call of
758 <a href="#inflate">inflate</a>. The compressor and decompressor must use exactly the same
759 dictionary (see <a href="#deflateSetDictionary">deflateSetDictionary</a>).<p>
760
761 <a href="#inflateSetDictionary">inflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a
762 parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is
763 inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the given dictionary doesn't match the
764 expected one (incorrect Adler32 value). <a href="#inflateSetDictionary">inflateSetDictionary</a> does not
765 perform any decompression: this will be done by subsequent calls of
766 <a href="#inflate">inflate</a>().<p>
767
768 <font color="Blue"><dt> int <a name="inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
769
770 <dd> Skips invalid compressed data until a full flush point (see above the
771 description of <a href="#deflate">deflate</a> with <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>) can be found, or until all
772 available input is skipped. No output is provided.<p>
773
774 <a href="#inflateSync">inflateSync</a> returns <a href="#Z_OK">Z_OK</a> if a full flush point has been found, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a>
775 if no more input was provided, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if no flush point has been found,
776 or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent. In the success
777 case, the application may save the current current value of <a href="#total_in">total_in</a> which
778 indicates where valid compressed data was found. In the error case, the
779 application may repeatedly call <a href="#inflateSync">inflateSync</a>, providing more input each time,
780 until success or end of the input data.<p>
781
782 <font color="Blue"><dt> int <a name="inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font>
783 <dd>
784 This function is equivalent to <a href="#inflateEnd">inflateEnd</a> followed by <a href="#inflateInit">inflateInit</a>,
785 but does not free and reallocate all the internal decompression <a href="#state">state</a>.
786 The stream will keep attributes that may have been set by <a href="#inflateInit2">inflateInit2</a>.
787 <p>
788
789 <a href="#inflateReset">inflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source
790 stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).
791 <p>
792 </dl>
793
794 <hr>
795 <a name="Checksum functions"><h2> Checksum functions </h2>
796 These functions are not related to compression but are exported
797 anyway because they might be useful in applications using the
798 compression library.
799 <h3> Function list </h3>
800 <ul>
801 <li> uLong <a href="#adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);
802 <li> uLong <a href="#crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);
803 </ul>
804 <h3> Function description </h3>
805 <dl>
806 <font color="Blue"><dt> uLong <a name="adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);</font>
807 <dd>
808 Update a running Adler-32 checksum with the bytes buf[0..len-1] and
809 return the updated checksum. If buf is NULL, this function returns
810 the required initial value for the checksum.
811 <p>
812 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
813 much faster. Usage example:
814 <pre>
815
816 uLong <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
817
818 while (read_buffer(buffer, length) != EOF) {
819 <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(<a href="#adler">adler</a>, buffer, length);
820 }
821 if (<a href="#adler">adler</a> != original_adler) error();
822 </pre>
823
824 <font color="Blue"><dt> uLong <a name="crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);</font>
825 <dd>
826 Update a running crc with the bytes buf[0..len-1] and return the updated
827 crc. If buf is NULL, this function returns the required initial value
828 for the crc. Pre- and post-conditioning (one's complement) is performed
829 within this function so it shouldn't be done by the application.
830 Usage example:
831 <pre>
832
833 uLong crc = <a href="#crc32">crc32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0);
834
835 while (read_buffer(buffer, length) != EOF) {
836 crc = <a href="#crc32">crc32</a>(crc, buffer, length);
837 }
838 if (crc != original_crc) error();
839 </pre>
840 </dl>
841 <hr>
842 <a name="struct z_stream_s"><h2> struct z_stream_s </h2>
843 <font color="Blue">
844 <a name="z_stream_s">
845 <pre>
846 typedef struct z_stream_s {
847 Bytef *<a name="next_in">next_in</a>; /* next input byte */
848 uInt <a name="avail_in">avail_in</a>; /* number of bytes available at <a href="#next_in">next_in</a> */
849 uLong <a name="total_in">total_in</a>; /* total nb of input bytes read so far */
850
851 Bytef *<a name="next_out">next_out</a>; /* next output byte should be put there */
852 uInt <a name="avail_out">avail_out</a>; /* remaining free space at <a href="#next_out">next_out</a> */
853 uLong <a name="total_out">total_out</a>; /* total nb of bytes output so far */
854
855 char *<a name="msg">msg</a>; /* last error message, NULL if no error */
856 struct internal_state FAR *<a name="state">state</a>; /* not visible by applications */
857
858 alloc_func <a name="zalloc">zalloc</a>; /* used to allocate the internal <a href="#state">state</a> */
859 free_func <a name="zfree">zfree</a>; /* used to free the internal <a href="#state">state</a> */
860 voidpf <a name="opaque">opaque</a>; /* private data object passed to <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> */
861
862 int <a name="data_type">data_type</a>; /* best guess about the data type: ascii or binary */
863 uLong <a name="adler">adler</a>; /* <a href="#adler32">adler32</a> value of the uncompressed data */
864 uLong <a name="reserved">reserved</a>; /* <a href="#reserved">reserved</a> for future use */
865 } <a href="#z_stream_s">z_stream</a> ;
866
867 typedef <a href="#z_stream_s">z_stream</a> FAR * <a name="z_streamp">z_streamp</a>; ÿ
868 </pre>
869 </font>
870 The application must update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> when <a href="#avail_in">avail_in</a> has
871 dropped to zero. It must update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> when <a href="#avail_out">avail_out</a>
872 has dropped to zero. The application must initialize <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and
873 <a href="#opaque">opaque</a> before calling the init function. All other fields are set by the
874 compression library and must not be updated by the application. <p>
875
876 The <a href="#opaque">opaque</a> value provided by the application will be passed as the first
877 parameter for calls of <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a>. This can be useful for custom
878 memory management. The compression library attaches no meaning to the
879 <a href="#opaque">opaque</a> value. <p>
880
881 <a href="#zalloc">zalloc</a> must return <a href="#Z_NULL">Z_NULL</a> if there is not enough memory for the object.
882 If zlib is used in a multi-threaded application, <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be
883 thread safe. <p>
884
885 On 16-bit systems, the functions <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be able to allocate
886 exactly 65536 bytes, but will not be required to allocate more than this
887 if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
888 pointers returned by <a href="#zalloc">zalloc</a> for objects of exactly 65536 bytes *must*
889 have their offset normalized to zero. The default allocation function
890 provided by this library ensures this (see zutil.c). To reduce memory
891 requirements and avoid any allocation of 64K objects, at the expense of
892 compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
893 <p>
894
895 The fields <a href="#total_in">total_in</a> and <a href="#total_out">total_out</a> can be used for statistics or
896 progress reports. After compression, <a href="#total_in">total_in</a> holds the total size of
897 the uncompressed data and may be saved for use in the decompressor
898 (particularly if the decompressor wants to decompress everything in
899 a single step). <p>
900
901 <hr>
902 <a name="Constants"><h2> Constants </h2>
903 <font color="Blue">
904 <pre>
905 #define <a name="Z_NO_FLUSH">Z_NO_FLUSH</a> 0
906 #define <a name="Z_PARTIAL_FLUSH">Z_PARTIAL_FLUSH</a> 1
907 /* will be removed, use <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> instead */
908 #define <a name="Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> 2
909 #define <a name="Z_FULL_FLUSH">Z_FULL_FLUSH</a> 3
910 #define <a name="Z_FINISH">Z_FINISH</a> 4
911 /* Allowed flush values ; see <a href="#deflate">deflate</a>() below for details */
912
913 #define <a name="Z_OK">Z_OK</a> 0
914 #define <a name="Z_STREAM_END">Z_STREAM_END</a> 1
915 #define <a name="Z_NEED_DICT">Z_NEED_DICT</a> 2
916 #define <a name="Z_ERRNO">Z_ERRNO</a> (-1)
917 #define <a name="Z_STREAM_ERROR">Z_STREAM_ERROR</a> (-2)
918 #define <a name="Z_DATA_ERROR">Z_DATA_ERROR</a> (-3)
919 #define <a name="Z_MEM_ERROR">Z_MEM_ERROR</a> (-4)
920 #define <a name="Z_BUF_ERROR">Z_BUF_ERROR</a> (-5)
921 #define <a name="Z_VERSION_ERROR">Z_VERSION_ERROR</a> (-6)
922 /* Return codes for the compression/decompression functions. Negative
923 * values are errors, positive values are used for special but normal events.
924 */
925
926 #define <a name="Z_NO_COMPRESSION">Z_NO_COMPRESSION</a> 0
927 #define <a name="Z_BEST_SPEED">Z_BEST_SPEED</a> 1
928 #define <a name="Z_BEST_COMPRESSION">Z_BEST_COMPRESSION</a> 9
929 #define <a name="Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> (-1)
930 /* compression levels */
931
932 #define <a name="Z_FILTERED">Z_FILTERED</a> 1
933 #define <a name="Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> 2
934 #define <a name="Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> 0
935 /* compression strategy ; see <a href="#deflateInit2">deflateInit2</a>() below for details */
936
937 #define <a name="Z_BINARY">Z_BINARY</a> 0
938 #define <a name="Z_ASCII">Z_ASCII</a> 1
939 #define <a name="Z_UNKNOWN">Z_UNKNOWN</a> 2
940 /* Possible values of the <a href="#data_type">data_type</a> field */
941
942 #define <a name="Z_DEFLATED">Z_DEFLATED</a> 8
943 /* The <a href="#deflate">deflate</a> compression method (the only one supported in this version) */
944
945 #define <a name="Z_NULL">Z_NULL</a> 0 /* for initializing <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a>, <a href="#opaque">opaque</a> */
946
947 #define <a name="zlib_version">zlib_version</a> <a href="#zlibVersion">zlibVersion</a>()
948 /* for compatibility with versions less than 1.0.2 */
949 </pre>
950 </font>
951
952 <hr>
953 <a name="Misc"><h2> Misc </h2>
954 <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a> are macros to allow checking the zlib version
955 and the compiler's view of <a href="#z_stream_s">z_stream</a>.
956 <p>
957 Other functions:
958 <dl>
959 <font color="Blue"><dt> const char * <a name="zError">zError</a> (int err);</font>
960 <font color="Blue"><dt> int <a name="inflateSyncPoint">inflateSyncPoint</a> (<a href="#z_streamp">z_streamp</a> z);</font>
961 <font color="Blue"><dt> const uLongf * <a name="get_crc_table">get_crc_table</a> (void);</font>
962 </dl>
963 <hr>
964 <font size="-1">
965 Last update: Wed Oct 13 20:42:34 1999<br>
966 piapi@csie.ntu.edu.tw
967 </font>
968
969 </body>
970 </html>
0 This directory contains project files for building zlib under various
1 Integrated Development Environments (IDE).
2
3 If you wish to submit a new project to this directory, you should comply
4 to the following requirements. Otherwise (e.g. if you wish to integrate
5 a custom piece of code that changes the zlib interface or its behavior),
6 please consider submitting the project to the contrib directory.
7
8
9 Requirements
10 ============
11
12 - The project must build zlib using the source files from the official
13 zlib source distribution, exclusively.
14
15 - If the project produces redistributable builds (e.g. shared objects
16 or DLL files), these builds must be compatible to those produced by
17 makefiles, if such makefiles exist in the zlib distribution.
18 In particular, if the project produces a DLL build for the Win32
19 platform, this build must comply to the officially-ammended Win32 DLL
20 Application Binary Interface (ABI), described in win32/DLL_FAQ.txt.
21
22 - The project may provide additional build targets, which depend on
23 3rd-party (unofficially-supported) software, present in the contrib
24 directory. For example, it is possible to provide an "ASM build",
25 besides the officially-supported build, and have ASM source files
26 among its dependencies.
27
28 - If there are significant differences between the project files created
29 by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name
30 of the project directory should contain the version number of the IDE
31 for which the project is intended (e.g. "visualc6" for Visual C++ 6.0,
32 or "visualc7" for Visual C++ 7.0 and 7.1).
33
34
35 Current projects
36 ================
37
38 visualc6/ by Simon-Pierre Cadieux <methodex@methodex.ca>
39 and Cosmin Truta <cosmint@cs.ubbcluj.ro>
40 Project for Microsoft Visual C++ 6.0
0 Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
1
2 Copyright (C) 2000-2004 Simon-Pierre Cadieux.
3 Copyright (C) 2004 Cosmin Truta.
4 For conditions of distribution and use, see copyright notice in zlib.h.
5
6
7 This project builds the zlib binaries as follows:
8
9 * Win32_DLL_Release\zlib1.dll DLL build
10 * Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
11 * Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
12 * Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
13 * Win32_LIB_Release\zlib.lib static build
14 * Win32_LIB_Debug\zlibd.lib static build (debug version)
15 * Win32_LIB_ASM_Release\zlib.lib static build using ASM code
16 * Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
17
18
19 For more information regarding the DLL builds, please see the DLL FAQ
20 in ..\..\win32\DLL_FAQ.txt.
21
22
23 To build and test:
24
25 1) On the main menu, select "File | Open Workspace".
26 Open "zlib.dsw".
27
28 2) Select "Build | Set Active Configuration".
29 Choose the configuration you wish to build.
30
31 3) Select "Build | Clean".
32
33 4) Select "Build | Build ... (F7)". Ignore warning messages about
34 not being able to find certain include files (e.g. alloc.h).
35
36 5) If you built one of the sample programs (example or minigzip),
37 select "Build | Execute ... (Ctrl+F5)".
38
39
40 To use:
41
42 1) Select "Project | Settings (Alt+F7)".
43 Make note of the configuration names used in your project.
44 Usually, these names are "Win32 Release" and "Win32 Debug".
45
46 2) In the Workspace window, select the "FileView" tab.
47 Right-click on the root item "Workspace '...'".
48 Select "Insert Project into Workspace".
49 Switch on the checkbox "Dependency of:", and select the name
50 of your project. Open "zlib.dsp".
51
52 3) Select "Build | Configurations".
53 For each configuration of your project:
54 3.1) Choose the zlib configuration you wish to use.
55 3.2) Click on "Add".
56 3.3) Set the new zlib configuration name to the name used by
57 the configuration from the current iteration.
58
59 4) Select "Build | Set Active Configuration".
60 Choose the configuration you wish to build.
61
62 5) Select "Build | Build ... (F7)".
63
64 6) If you built an executable program, select
65 "Build | Execute ... (Ctrl+F5)".
66
67
68 Note:
69
70 To build the ASM-enabled code, you need Microsoft Assembler
71 (ML.EXE). You can get it by downloading and installing the
72 latest Processor Pack for Visual C++ 6.0.
0 # Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
1 # Microsoft Developer Studio Generated Build File, Format Version 6.00
2 # ** DO NOT EDIT **
3
4 # TARGTYPE "Win32 (x86) Console Application" 0x0103
5
6 CFG=example - Win32 LIB Debug
7 !MESSAGE This is not a valid makefile. To build this project using NMAKE,
8 !MESSAGE use the Export Makefile command and run
9 !MESSAGE
10 !MESSAGE NMAKE /f "example.mak".
11 !MESSAGE
12 !MESSAGE You can specify a configuration when running NMAKE
13 !MESSAGE by defining the macro CFG on the command line. For example:
14 !MESSAGE
15 !MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"
16 !MESSAGE
17 !MESSAGE Possible choices for configuration are:
18 !MESSAGE
19 !MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")
20 !MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
21 !MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
22 !MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
23 !MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")
24 !MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
25 !MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
26 !MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
27 !MESSAGE
28
29 # Begin Project
30 # PROP AllowPerConfigDependencies 0
31 # PROP Scc_ProjName ""
32 # PROP Scc_LocalPath ""
33 CPP=cl.exe
34 RSC=rc.exe
35
36 !IF "$(CFG)" == "example - Win32 DLL Release"
37
38 # PROP BASE Use_MFC 0
39 # PROP BASE Use_Debug_Libraries 0
40 # PROP BASE Output_Dir "example___Win32_DLL_Release"
41 # PROP BASE Intermediate_Dir "example___Win32_DLL_Release"
42 # PROP BASE Target_Dir ""
43 # PROP Use_MFC 0
44 # PROP Use_Debug_Libraries 0
45 # PROP Output_Dir "Win32_DLL_Release"
46 # PROP Intermediate_Dir "Win32_DLL_Release"
47 # PROP Ignore_Export_Lib 0
48 # PROP Target_Dir ""
49 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
50 # SUBTRACT BASE CPP /YX
51 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
52 # SUBTRACT CPP /YX
53 # ADD BASE RSC /l 0x409 /d "NDEBUG"
54 # ADD RSC /l 0x409 /d "NDEBUG"
55 BSC32=bscmake.exe
56 # ADD BASE BSC32 /nologo
57 # ADD BSC32 /nologo
58 LINK32=link.exe
59 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
60 # ADD LINK32 /nologo /subsystem:console /machine:I386
61
62 !ELSEIF "$(CFG)" == "example - Win32 DLL Debug"
63
64 # PROP BASE Use_MFC 0
65 # PROP BASE Use_Debug_Libraries 1
66 # PROP BASE Output_Dir "example___Win32_DLL_Debug"
67 # PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"
68 # PROP BASE Target_Dir ""
69 # PROP Use_MFC 0
70 # PROP Use_Debug_Libraries 1
71 # PROP Output_Dir "Win32_DLL_Debug"
72 # PROP Intermediate_Dir "Win32_DLL_Debug"
73 # PROP Ignore_Export_Lib 0
74 # PROP Target_Dir ""
75 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
76 # SUBTRACT BASE CPP /YX
77 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
78 # SUBTRACT CPP /YX
79 # ADD BASE RSC /l 0x409 /d "_DEBUG"
80 # ADD RSC /l 0x409 /d "_DEBUG"
81 BSC32=bscmake.exe
82 # ADD BASE BSC32 /nologo
83 # ADD BSC32 /nologo
84 LINK32=link.exe
85 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
86 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
87
88 !ELSEIF "$(CFG)" == "example - Win32 DLL ASM Release"
89
90 # PROP BASE Use_MFC 0
91 # PROP BASE Use_Debug_Libraries 0
92 # PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"
93 # PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"
94 # PROP BASE Target_Dir ""
95 # PROP Use_MFC 0
96 # PROP Use_Debug_Libraries 0
97 # PROP Output_Dir "Win32_DLL_ASM_Release"
98 # PROP Intermediate_Dir "Win32_DLL_ASM_Release"
99 # PROP Ignore_Export_Lib 0
100 # PROP Target_Dir ""
101 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
102 # SUBTRACT BASE CPP /YX
103 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
104 # SUBTRACT CPP /YX
105 # ADD BASE RSC /l 0x409 /d "NDEBUG"
106 # ADD RSC /l 0x409 /d "NDEBUG"
107 BSC32=bscmake.exe
108 # ADD BASE BSC32 /nologo
109 # ADD BSC32 /nologo
110 LINK32=link.exe
111 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
112 # ADD LINK32 /nologo /subsystem:console /machine:I386
113
114 !ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug"
115
116 # PROP BASE Use_MFC 0
117 # PROP BASE Use_Debug_Libraries 1
118 # PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"
119 # PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"
120 # PROP BASE Target_Dir ""
121 # PROP Use_MFC 0
122 # PROP Use_Debug_Libraries 1
123 # PROP Output_Dir "Win32_DLL_ASM_Debug"
124 # PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
125 # PROP Ignore_Export_Lib 0
126 # PROP Target_Dir ""
127 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
128 # SUBTRACT BASE CPP /YX
129 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
130 # SUBTRACT CPP /YX
131 # ADD BASE RSC /l 0x409 /d "_DEBUG"
132 # ADD RSC /l 0x409 /d "_DEBUG"
133 BSC32=bscmake.exe
134 # ADD BASE BSC32 /nologo
135 # ADD BSC32 /nologo
136 LINK32=link.exe
137 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
138 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
139
140 !ELSEIF "$(CFG)" == "example - Win32 LIB Release"
141
142 # PROP BASE Use_MFC 0
143 # PROP BASE Use_Debug_Libraries 0
144 # PROP BASE Output_Dir "example___Win32_LIB_Release"
145 # PROP BASE Intermediate_Dir "example___Win32_LIB_Release"
146 # PROP BASE Target_Dir ""
147 # PROP Use_MFC 0
148 # PROP Use_Debug_Libraries 0
149 # PROP Output_Dir "Win32_LIB_Release"
150 # PROP Intermediate_Dir "Win32_LIB_Release"
151 # PROP Ignore_Export_Lib 0
152 # PROP Target_Dir ""
153 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
154 # SUBTRACT BASE CPP /YX
155 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
156 # SUBTRACT CPP /YX
157 # ADD BASE RSC /l 0x409 /d "NDEBUG"
158 # ADD RSC /l 0x409 /d "NDEBUG"
159 BSC32=bscmake.exe
160 # ADD BASE BSC32 /nologo
161 # ADD BSC32 /nologo
162 LINK32=link.exe
163 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
164 # ADD LINK32 /nologo /subsystem:console /machine:I386
165
166 !ELSEIF "$(CFG)" == "example - Win32 LIB Debug"
167
168 # PROP BASE Use_MFC 0
169 # PROP BASE Use_Debug_Libraries 1
170 # PROP BASE Output_Dir "example___Win32_LIB_Debug"
171 # PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"
172 # PROP BASE Target_Dir ""
173 # PROP Use_MFC 0
174 # PROP Use_Debug_Libraries 1
175 # PROP Output_Dir "Win32_LIB_Debug"
176 # PROP Intermediate_Dir "Win32_LIB_Debug"
177 # PROP Ignore_Export_Lib 0
178 # PROP Target_Dir ""
179 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
180 # SUBTRACT BASE CPP /YX
181 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
182 # SUBTRACT CPP /YX
183 # ADD BASE RSC /l 0x409 /d "_DEBUG"
184 # ADD RSC /l 0x409 /d "_DEBUG"
185 BSC32=bscmake.exe
186 # ADD BASE BSC32 /nologo
187 # ADD BSC32 /nologo
188 LINK32=link.exe
189 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
190 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
191
192 !ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release"
193
194 # PROP BASE Use_MFC 0
195 # PROP BASE Use_Debug_Libraries 0
196 # PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"
197 # PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"
198 # PROP BASE Target_Dir ""
199 # PROP Use_MFC 0
200 # PROP Use_Debug_Libraries 0
201 # PROP Output_Dir "Win32_LIB_ASM_Release"
202 # PROP Intermediate_Dir "Win32_LIB_ASM_Release"
203 # PROP Ignore_Export_Lib 0
204 # PROP Target_Dir ""
205 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
206 # SUBTRACT BASE CPP /YX
207 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
208 # SUBTRACT CPP /YX
209 # ADD BASE RSC /l 0x409 /d "NDEBUG"
210 # ADD RSC /l 0x409 /d "NDEBUG"
211 BSC32=bscmake.exe
212 # ADD BASE BSC32 /nologo
213 # ADD BSC32 /nologo
214 LINK32=link.exe
215 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
216 # ADD LINK32 /nologo /subsystem:console /machine:I386
217
218 !ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug"
219
220 # PROP BASE Use_MFC 0
221 # PROP BASE Use_Debug_Libraries 1
222 # PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"
223 # PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"
224 # PROP BASE Target_Dir ""
225 # PROP Use_MFC 0
226 # PROP Use_Debug_Libraries 1
227 # PROP Output_Dir "Win32_LIB_ASM_Debug"
228 # PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
229 # PROP Ignore_Export_Lib 0
230 # PROP Target_Dir ""
231 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
232 # SUBTRACT BASE CPP /YX
233 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
234 # SUBTRACT CPP /YX
235 # ADD BASE RSC /l 0x409 /d "_DEBUG"
236 # ADD RSC /l 0x409 /d "_DEBUG"
237 BSC32=bscmake.exe
238 # ADD BASE BSC32 /nologo
239 # ADD BSC32 /nologo
240 LINK32=link.exe
241 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
242 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
243
244 !ENDIF
245
246 # Begin Target
247
248 # Name "example - Win32 DLL Release"
249 # Name "example - Win32 DLL Debug"
250 # Name "example - Win32 DLL ASM Release"
251 # Name "example - Win32 DLL ASM Debug"
252 # Name "example - Win32 LIB Release"
253 # Name "example - Win32 LIB Debug"
254 # Name "example - Win32 LIB ASM Release"
255 # Name "example - Win32 LIB ASM Debug"
256 # Begin Group "Source Files"
257
258 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
259 # Begin Source File
260
261 SOURCE=..\..\example.c
262 # End Source File
263 # End Group
264 # Begin Group "Header Files"
265
266 # PROP Default_Filter "h;hpp;hxx;hm;inl"
267 # Begin Source File
268
269 SOURCE=..\..\zconf.h
270 # End Source File
271 # Begin Source File
272
273 SOURCE=..\..\zlib.h
274 # End Source File
275 # End Group
276 # End Target
277 # End Project
0 # Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>
1 # Microsoft Developer Studio Generated Build File, Format Version 6.00
2 # ** DO NOT EDIT **
3
4 # TARGTYPE "Win32 (x86) Console Application" 0x0103
5
6 CFG=minigzip - Win32 LIB Debug
7 !MESSAGE This is not a valid makefile. To build this project using NMAKE,
8 !MESSAGE use the Export Makefile command and run
9 !MESSAGE
10 !MESSAGE NMAKE /f "minigzip.mak".
11 !MESSAGE
12 !MESSAGE You can specify a configuration when running NMAKE
13 !MESSAGE by defining the macro CFG on the command line. For example:
14 !MESSAGE
15 !MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"
16 !MESSAGE
17 !MESSAGE Possible choices for configuration are:
18 !MESSAGE
19 !MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")
20 !MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
21 !MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
22 !MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
23 !MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")
24 !MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
25 !MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
26 !MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
27 !MESSAGE
28
29 # Begin Project
30 # PROP AllowPerConfigDependencies 0
31 # PROP Scc_ProjName ""
32 # PROP Scc_LocalPath ""
33 CPP=cl.exe
34 RSC=rc.exe
35
36 !IF "$(CFG)" == "minigzip - Win32 DLL Release"
37
38 # PROP BASE Use_MFC 0
39 # PROP BASE Use_Debug_Libraries 0
40 # PROP BASE Output_Dir "minigzip___Win32_DLL_Release"
41 # PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"
42 # PROP BASE Target_Dir ""
43 # PROP Use_MFC 0
44 # PROP Use_Debug_Libraries 0
45 # PROP Output_Dir "Win32_DLL_Release"
46 # PROP Intermediate_Dir "Win32_DLL_Release"
47 # PROP Ignore_Export_Lib 0
48 # PROP Target_Dir ""
49 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
50 # SUBTRACT BASE CPP /YX
51 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
52 # SUBTRACT CPP /YX
53 # ADD BASE RSC /l 0x409 /d "NDEBUG"
54 # ADD RSC /l 0x409 /d "NDEBUG"
55 BSC32=bscmake.exe
56 # ADD BASE BSC32 /nologo
57 # ADD BSC32 /nologo
58 LINK32=link.exe
59 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
60 # ADD LINK32 /nologo /subsystem:console /machine:I386
61
62 !ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug"
63
64 # PROP BASE Use_MFC 0
65 # PROP BASE Use_Debug_Libraries 1
66 # PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"
67 # PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"
68 # PROP BASE Target_Dir ""
69 # PROP Use_MFC 0
70 # PROP Use_Debug_Libraries 1
71 # PROP Output_Dir "Win32_DLL_Debug"
72 # PROP Intermediate_Dir "Win32_DLL_Debug"
73 # PROP Ignore_Export_Lib 0
74 # PROP Target_Dir ""
75 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
76 # SUBTRACT BASE CPP /YX
77 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
78 # SUBTRACT CPP /YX
79 # ADD BASE RSC /l 0x409 /d "_DEBUG"
80 # ADD RSC /l 0x409 /d "_DEBUG"
81 BSC32=bscmake.exe
82 # ADD BASE BSC32 /nologo
83 # ADD BSC32 /nologo
84 LINK32=link.exe
85 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
86 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
87
88 !ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Release"
89
90 # PROP BASE Use_MFC 0
91 # PROP BASE Use_Debug_Libraries 0
92 # PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"
93 # PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"
94 # PROP BASE Target_Dir ""
95 # PROP Use_MFC 0
96 # PROP Use_Debug_Libraries 0
97 # PROP Output_Dir "Win32_DLL_ASM_Release"
98 # PROP Intermediate_Dir "Win32_DLL_ASM_Release"
99 # PROP Ignore_Export_Lib 0
100 # PROP Target_Dir ""
101 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
102 # SUBTRACT BASE CPP /YX
103 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
104 # SUBTRACT CPP /YX
105 # ADD BASE RSC /l 0x409 /d "NDEBUG"
106 # ADD RSC /l 0x409 /d "NDEBUG"
107 BSC32=bscmake.exe
108 # ADD BASE BSC32 /nologo
109 # ADD BSC32 /nologo
110 LINK32=link.exe
111 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
112 # ADD LINK32 /nologo /subsystem:console /machine:I386
113
114 !ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug"
115
116 # PROP BASE Use_MFC 0
117 # PROP BASE Use_Debug_Libraries 1
118 # PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"
119 # PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"
120 # PROP BASE Target_Dir ""
121 # PROP Use_MFC 0
122 # PROP Use_Debug_Libraries 1
123 # PROP Output_Dir "Win32_DLL_ASM_Debug"
124 # PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
125 # PROP Ignore_Export_Lib 0
126 # PROP Target_Dir ""
127 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
128 # SUBTRACT BASE CPP /YX
129 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
130 # SUBTRACT CPP /YX
131 # ADD BASE RSC /l 0x409 /d "_DEBUG"
132 # ADD RSC /l 0x409 /d "_DEBUG"
133 BSC32=bscmake.exe
134 # ADD BASE BSC32 /nologo
135 # ADD BSC32 /nologo
136 LINK32=link.exe
137 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
138 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
139
140 !ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release"
141
142 # PROP BASE Use_MFC 0
143 # PROP BASE Use_Debug_Libraries 0
144 # PROP BASE Output_Dir "minigzip___Win32_LIB_Release"
145 # PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"
146 # PROP BASE Target_Dir ""
147 # PROP Use_MFC 0
148 # PROP Use_Debug_Libraries 0
149 # PROP Output_Dir "Win32_LIB_Release"
150 # PROP Intermediate_Dir "Win32_LIB_Release"
151 # PROP Ignore_Export_Lib 0
152 # PROP Target_Dir ""
153 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
154 # SUBTRACT BASE CPP /YX
155 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
156 # SUBTRACT CPP /YX
157 # ADD BASE RSC /l 0x409 /d "NDEBUG"
158 # ADD RSC /l 0x409 /d "NDEBUG"
159 BSC32=bscmake.exe
160 # ADD BASE BSC32 /nologo
161 # ADD BSC32 /nologo
162 LINK32=link.exe
163 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
164 # ADD LINK32 /nologo /subsystem:console /machine:I386
165
166 !ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug"
167
168 # PROP BASE Use_MFC 0
169 # PROP BASE Use_Debug_Libraries 1
170 # PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"
171 # PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"
172 # PROP BASE Target_Dir ""
173 # PROP Use_MFC 0
174 # PROP Use_Debug_Libraries 1
175 # PROP Output_Dir "Win32_LIB_Debug"
176 # PROP Intermediate_Dir "Win32_LIB_Debug"
177 # PROP Ignore_Export_Lib 0
178 # PROP Target_Dir ""
179 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
180 # SUBTRACT BASE CPP /YX
181 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
182 # SUBTRACT CPP /YX
183 # ADD BASE RSC /l 0x409 /d "_DEBUG"
184 # ADD RSC /l 0x409 /d "_DEBUG"
185 BSC32=bscmake.exe
186 # ADD BASE BSC32 /nologo
187 # ADD BSC32 /nologo
188 LINK32=link.exe
189 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
190 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
191
192 !ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release"
193
194 # PROP BASE Use_MFC 0
195 # PROP BASE Use_Debug_Libraries 0
196 # PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"
197 # PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"
198 # PROP BASE Target_Dir ""
199 # PROP Use_MFC 0
200 # PROP Use_Debug_Libraries 0
201 # PROP Output_Dir "Win32_LIB_ASM_Release"
202 # PROP Intermediate_Dir "Win32_LIB_ASM_Release"
203 # PROP Ignore_Export_Lib 0
204 # PROP Target_Dir ""
205 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
206 # SUBTRACT BASE CPP /YX
207 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
208 # SUBTRACT CPP /YX
209 # ADD BASE RSC /l 0x409 /d "NDEBUG"
210 # ADD RSC /l 0x409 /d "NDEBUG"
211 BSC32=bscmake.exe
212 # ADD BASE BSC32 /nologo
213 # ADD BSC32 /nologo
214 LINK32=link.exe
215 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
216 # ADD LINK32 /nologo /subsystem:console /machine:I386
217
218 !ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug"
219
220 # PROP BASE Use_MFC 0
221 # PROP BASE Use_Debug_Libraries 1
222 # PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"
223 # PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"
224 # PROP BASE Target_Dir ""
225 # PROP Use_MFC 0
226 # PROP Use_Debug_Libraries 1
227 # PROP Output_Dir "Win32_LIB_ASM_Debug"
228 # PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
229 # PROP Ignore_Export_Lib 0
230 # PROP Target_Dir ""
231 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
232 # SUBTRACT BASE CPP /YX
233 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
234 # SUBTRACT CPP /YX
235 # ADD BASE RSC /l 0x409 /d "_DEBUG"
236 # ADD RSC /l 0x409 /d "_DEBUG"
237 BSC32=bscmake.exe
238 # ADD BASE BSC32 /nologo
239 # ADD BSC32 /nologo
240 LINK32=link.exe
241 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
242 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
243
244 !ENDIF
245
246 # Begin Target
247
248 # Name "minigzip - Win32 DLL Release"
249 # Name "minigzip - Win32 DLL Debug"
250 # Name "minigzip - Win32 DLL ASM Release"
251 # Name "minigzip - Win32 DLL ASM Debug"
252 # Name "minigzip - Win32 LIB Release"
253 # Name "minigzip - Win32 LIB Debug"
254 # Name "minigzip - Win32 LIB ASM Release"
255 # Name "minigzip - Win32 LIB ASM Debug"
256 # Begin Group "Source Files"
257
258 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
259 # Begin Source File
260
261 SOURCE=..\..\minigzip.c
262 # End Source File
263 # End Group
264 # Begin Group "Header Files"
265
266 # PROP Default_Filter "h;hpp;hxx;hm;inl"
267 # Begin Source File
268
269 SOURCE=..\..\zconf.h
270 # End Source File
271 # Begin Source File
272
273 SOURCE=..\..\zlib.h
274 # End Source File
275 # End Group
276 # End Target
277 # End Project
0 # Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
1 # Microsoft Developer Studio Generated Build File, Format Version 6.00
2 # ** DO NOT EDIT **
3
4 # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
5 # TARGTYPE "Win32 (x86) Static Library" 0x0104
6
7 CFG=zlib - Win32 LIB Debug
8 !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9 !MESSAGE use the Export Makefile command and run
10 !MESSAGE
11 !MESSAGE NMAKE /f "zlib.mak".
12 !MESSAGE
13 !MESSAGE You can specify a configuration when running NMAKE
14 !MESSAGE by defining the macro CFG on the command line. For example:
15 !MESSAGE
16 !MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"
17 !MESSAGE
18 !MESSAGE Possible choices for configuration are:
19 !MESSAGE
20 !MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
21 !MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
22 !MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")
23 !MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")
24 !MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")
25 !MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
26 !MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")
27 !MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")
28 !MESSAGE
29
30 # Begin Project
31 # PROP AllowPerConfigDependencies 0
32 # PROP Scc_ProjName ""
33 # PROP Scc_LocalPath ""
34
35 !IF "$(CFG)" == "zlib - Win32 DLL Release"
36
37 # PROP BASE Use_MFC 0
38 # PROP BASE Use_Debug_Libraries 0
39 # PROP BASE Output_Dir "zlib___Win32_DLL_Release"
40 # PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"
41 # PROP BASE Target_Dir ""
42 # PROP Use_MFC 0
43 # PROP Use_Debug_Libraries 0
44 # PROP Output_Dir "Win32_DLL_Release"
45 # PROP Intermediate_Dir "Win32_DLL_Release"
46 # PROP Ignore_Export_Lib 0
47 # PROP Target_Dir ""
48 CPP=cl.exe
49 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
50 # SUBTRACT BASE CPP /YX /Yc /Yu
51 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
52 # SUBTRACT CPP /YX /Yc /Yu
53 MTL=midl.exe
54 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
55 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
56 RSC=rc.exe
57 # ADD BASE RSC /l 0x409 /d "NDEBUG"
58 # ADD RSC /l 0x409 /d "NDEBUG"
59 BSC32=bscmake.exe
60 # ADD BASE BSC32 /nologo
61 # ADD BSC32 /nologo
62 LINK32=link.exe
63 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
64 # ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"
65
66 !ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
67
68 # PROP BASE Use_MFC 0
69 # PROP BASE Use_Debug_Libraries 1
70 # PROP BASE Output_Dir "zlib___Win32_DLL_Debug"
71 # PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"
72 # PROP BASE Target_Dir ""
73 # PROP Use_MFC 0
74 # PROP Use_Debug_Libraries 1
75 # PROP Output_Dir "Win32_DLL_Debug"
76 # PROP Intermediate_Dir "Win32_DLL_Debug"
77 # PROP Ignore_Export_Lib 0
78 # PROP Target_Dir ""
79 CPP=cl.exe
80 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
81 # SUBTRACT BASE CPP /YX /Yc /Yu
82 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
83 # SUBTRACT CPP /YX /Yc /Yu
84 MTL=midl.exe
85 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
86 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
87 RSC=rc.exe
88 # ADD BASE RSC /l 0x409 /d "_DEBUG"
89 # ADD RSC /l 0x409 /d "_DEBUG"
90 BSC32=bscmake.exe
91 # ADD BASE BSC32 /nologo
92 # ADD BSC32 /nologo
93 LINK32=link.exe
94 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
95 # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept
96
97 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
98
99 # PROP BASE Use_MFC 0
100 # PROP BASE Use_Debug_Libraries 0
101 # PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"
102 # PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"
103 # PROP BASE Target_Dir ""
104 # PROP Use_MFC 0
105 # PROP Use_Debug_Libraries 0
106 # PROP Output_Dir "Win32_DLL_ASM_Release"
107 # PROP Intermediate_Dir "Win32_DLL_ASM_Release"
108 # PROP Ignore_Export_Lib 0
109 # PROP Target_Dir ""
110 CPP=cl.exe
111 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
112 # SUBTRACT BASE CPP /YX /Yc /Yu
113 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
114 # SUBTRACT CPP /YX /Yc /Yu
115 MTL=midl.exe
116 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
117 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
118 RSC=rc.exe
119 # ADD BASE RSC /l 0x409 /d "NDEBUG"
120 # ADD RSC /l 0x409 /d "NDEBUG"
121 BSC32=bscmake.exe
122 # ADD BASE BSC32 /nologo
123 # ADD BSC32 /nologo
124 LINK32=link.exe
125 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
126 # ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"
127
128 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
129
130 # PROP BASE Use_MFC 0
131 # PROP BASE Use_Debug_Libraries 1
132 # PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"
133 # PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"
134 # PROP BASE Target_Dir ""
135 # PROP Use_MFC 0
136 # PROP Use_Debug_Libraries 1
137 # PROP Output_Dir "Win32_DLL_ASM_Debug"
138 # PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
139 # PROP Ignore_Export_Lib 0
140 # PROP Target_Dir ""
141 CPP=cl.exe
142 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
143 # SUBTRACT BASE CPP /YX /Yc /Yu
144 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
145 # SUBTRACT CPP /YX /Yc /Yu
146 MTL=midl.exe
147 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
148 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
149 RSC=rc.exe
150 # ADD BASE RSC /l 0x409 /d "_DEBUG"
151 # ADD RSC /l 0x409 /d "_DEBUG"
152 BSC32=bscmake.exe
153 # ADD BASE BSC32 /nologo
154 # ADD BSC32 /nologo
155 LINK32=link.exe
156 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
157 # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept
158
159 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
160
161 # PROP BASE Use_MFC 0
162 # PROP BASE Use_Debug_Libraries 0
163 # PROP BASE Output_Dir "zlib___Win32_LIB_Release"
164 # PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"
165 # PROP BASE Target_Dir ""
166 # PROP Use_MFC 0
167 # PROP Use_Debug_Libraries 0
168 # PROP Output_Dir "Win32_LIB_Release"
169 # PROP Intermediate_Dir "Win32_LIB_Release"
170 # PROP Target_Dir ""
171 CPP=cl.exe
172 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
173 # SUBTRACT BASE CPP /YX /Yc /Yu
174 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
175 # SUBTRACT CPP /YX /Yc /Yu
176 RSC=rc.exe
177 # ADD BASE RSC /l 0x409 /d "NDEBUG"
178 # ADD RSC /l 0x409 /d "NDEBUG"
179 BSC32=bscmake.exe
180 # ADD BASE BSC32 /nologo
181 # ADD BSC32 /nologo
182 LIB32=link.exe -lib
183 # ADD BASE LIB32 /nologo
184 # ADD LIB32 /nologo
185
186 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
187
188 # PROP BASE Use_MFC 0
189 # PROP BASE Use_Debug_Libraries 1
190 # PROP BASE Output_Dir "zlib___Win32_LIB_Debug"
191 # PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"
192 # PROP BASE Target_Dir ""
193 # PROP Use_MFC 0
194 # PROP Use_Debug_Libraries 1
195 # PROP Output_Dir "Win32_LIB_Debug"
196 # PROP Intermediate_Dir "Win32_LIB_Debug"
197 # PROP Target_Dir ""
198 CPP=cl.exe
199 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
200 # SUBTRACT BASE CPP /YX /Yc /Yu
201 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
202 # SUBTRACT CPP /YX /Yc /Yu
203 RSC=rc.exe
204 # ADD BASE RSC /l 0x409 /d "_DEBUG"
205 # ADD RSC /l 0x409 /d "_DEBUG"
206 BSC32=bscmake.exe
207 # ADD BASE BSC32 /nologo
208 # ADD BSC32 /nologo
209 LIB32=link.exe -lib
210 # ADD BASE LIB32 /nologo
211 # ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"
212
213 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
214
215 # PROP BASE Use_MFC 0
216 # PROP BASE Use_Debug_Libraries 0
217 # PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"
218 # PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"
219 # PROP BASE Target_Dir ""
220 # PROP Use_MFC 0
221 # PROP Use_Debug_Libraries 0
222 # PROP Output_Dir "Win32_LIB_ASM_Release"
223 # PROP Intermediate_Dir "Win32_LIB_ASM_Release"
224 # PROP Target_Dir ""
225 CPP=cl.exe
226 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
227 # SUBTRACT BASE CPP /YX /Yc /Yu
228 # ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
229 # SUBTRACT CPP /YX /Yc /Yu
230 RSC=rc.exe
231 # ADD BASE RSC /l 0x409 /d "NDEBUG"
232 # ADD RSC /l 0x409 /d "NDEBUG"
233 BSC32=bscmake.exe
234 # ADD BASE BSC32 /nologo
235 # ADD BSC32 /nologo
236 LIB32=link.exe -lib
237 # ADD BASE LIB32 /nologo
238 # ADD LIB32 /nologo
239
240 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
241
242 # PROP BASE Use_MFC 0
243 # PROP BASE Use_Debug_Libraries 1
244 # PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"
245 # PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"
246 # PROP BASE Target_Dir ""
247 # PROP Use_MFC 0
248 # PROP Use_Debug_Libraries 1
249 # PROP Output_Dir "Win32_LIB_ASM_Debug"
250 # PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
251 # PROP Target_Dir ""
252 CPP=cl.exe
253 # ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
254 # SUBTRACT BASE CPP /YX /Yc /Yu
255 # ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
256 # SUBTRACT CPP /YX /Yc /Yu
257 RSC=rc.exe
258 # ADD BASE RSC /l 0x409 /d "_DEBUG"
259 # ADD RSC /l 0x409 /d "_DEBUG"
260 BSC32=bscmake.exe
261 # ADD BASE BSC32 /nologo
262 # ADD BSC32 /nologo
263 LIB32=link.exe -lib
264 # ADD BASE LIB32 /nologo
265 # ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"
266
267 !ENDIF
268
269 # Begin Target
270
271 # Name "zlib - Win32 DLL Release"
272 # Name "zlib - Win32 DLL Debug"
273 # Name "zlib - Win32 DLL ASM Release"
274 # Name "zlib - Win32 DLL ASM Debug"
275 # Name "zlib - Win32 LIB Release"
276 # Name "zlib - Win32 LIB Debug"
277 # Name "zlib - Win32 LIB ASM Release"
278 # Name "zlib - Win32 LIB ASM Debug"
279 # Begin Group "Source Files"
280
281 # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
282 # Begin Source File
283
284 SOURCE=..\..\adler32.c
285 # End Source File
286 # Begin Source File
287
288 SOURCE=..\..\compress.c
289 # End Source File
290 # Begin Source File
291
292 SOURCE=..\..\crc32.c
293 # End Source File
294 # Begin Source File
295
296 SOURCE=..\..\deflate.c
297 # End Source File
298 # Begin Source File
299
300 SOURCE=..\..\gzio.c
301 # End Source File
302 # Begin Source File
303
304 SOURCE=..\..\infback.c
305 # End Source File
306 # Begin Source File
307
308 SOURCE=..\..\inffast.c
309 # End Source File
310 # Begin Source File
311
312 SOURCE=..\..\inflate.c
313 # End Source File
314 # Begin Source File
315
316 SOURCE=..\..\inftrees.c
317 # End Source File
318 # Begin Source File
319
320 SOURCE=..\..\trees.c
321 # End Source File
322 # Begin Source File
323
324 SOURCE=..\..\uncompr.c
325 # End Source File
326 # Begin Source File
327
328 SOURCE=..\..\win32\zlib.def
329
330 !IF "$(CFG)" == "zlib - Win32 DLL Release"
331
332 !ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
333
334 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
335
336 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
337
338 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
339
340 # PROP Exclude_From_Build 1
341
342 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
343
344 # PROP Exclude_From_Build 1
345
346 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
347
348 # PROP Exclude_From_Build 1
349
350 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
351
352 # PROP Exclude_From_Build 1
353
354 !ENDIF
355
356 # End Source File
357 # Begin Source File
358
359 SOURCE=..\..\zutil.c
360 # End Source File
361 # End Group
362 # Begin Group "Header Files"
363
364 # PROP Default_Filter "h;hpp;hxx;hm;inl"
365 # Begin Source File
366
367 SOURCE=..\..\crc32.h
368 # End Source File
369 # Begin Source File
370
371 SOURCE=..\..\deflate.h
372 # End Source File
373 # Begin Source File
374
375 SOURCE=..\..\inffast.h
376 # End Source File
377 # Begin Source File
378
379 SOURCE=..\..\inffixed.h
380 # End Source File
381 # Begin Source File
382
383 SOURCE=..\..\inflate.h
384 # End Source File
385 # Begin Source File
386
387 SOURCE=..\..\inftrees.h
388 # End Source File
389 # Begin Source File
390
391 SOURCE=..\..\trees.h
392 # End Source File
393 # Begin Source File
394
395 SOURCE=..\..\zconf.h
396 # End Source File
397 # Begin Source File
398
399 SOURCE=..\..\zlib.h
400 # End Source File
401 # Begin Source File
402
403 SOURCE=..\..\zutil.h
404 # End Source File
405 # End Group
406 # Begin Group "Resource Files"
407
408 # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
409 # Begin Source File
410
411 SOURCE=..\..\win32\zlib1.rc
412 # End Source File
413 # End Group
414 # Begin Group "Assembler Files (Unsupported)"
415
416 # PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"
417 # Begin Source File
418
419 SOURCE=..\..\contrib\masmx86\gvmat32.asm
420
421 !IF "$(CFG)" == "zlib - Win32 DLL Release"
422
423 # PROP Exclude_From_Build 1
424
425 !ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
426
427 # PROP Exclude_From_Build 1
428
429 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
430
431 # Begin Custom Build - Assembling...
432 IntDir=.\Win32_DLL_ASM_Release
433 InputPath=..\..\contrib\masmx86\gvmat32.asm
434 InputName=gvmat32
435
436 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
437 ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
438
439 # End Custom Build
440
441 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
442
443 # Begin Custom Build - Assembling...
444 IntDir=.\Win32_DLL_ASM_Debug
445 InputPath=..\..\contrib\masmx86\gvmat32.asm
446 InputName=gvmat32
447
448 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
449 ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
450
451 # End Custom Build
452
453 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
454
455 # PROP Exclude_From_Build 1
456
457 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
458
459 # PROP Exclude_From_Build 1
460
461 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
462
463 # Begin Custom Build - Assembling...
464 IntDir=.\Win32_LIB_ASM_Release
465 InputPath=..\..\contrib\masmx86\gvmat32.asm
466 InputName=gvmat32
467
468 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
469 ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
470
471 # End Custom Build
472
473 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
474
475 # Begin Custom Build - Assembling...
476 IntDir=.\Win32_LIB_ASM_Debug
477 InputPath=..\..\contrib\masmx86\gvmat32.asm
478 InputName=gvmat32
479
480 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
481 ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
482
483 # End Custom Build
484
485 !ENDIF
486
487 # End Source File
488 # Begin Source File
489
490 SOURCE=..\..\contrib\masmx86\gvmat32c.c
491
492 !IF "$(CFG)" == "zlib - Win32 DLL Release"
493
494 # PROP Exclude_From_Build 1
495 # ADD CPP /I "..\.."
496
497 !ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
498
499 # PROP Exclude_From_Build 1
500 # ADD CPP /I "..\.."
501
502 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
503
504 # ADD CPP /I "..\.."
505
506 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
507
508 # ADD CPP /I "..\.."
509
510 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
511
512 # PROP Exclude_From_Build 1
513 # ADD CPP /I "..\.."
514
515 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
516
517 # PROP Exclude_From_Build 1
518 # ADD CPP /I "..\.."
519
520 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
521
522 # ADD CPP /I "..\.."
523
524 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
525
526 # ADD CPP /I "..\.."
527
528 !ENDIF
529
530 # End Source File
531 # Begin Source File
532
533 SOURCE=..\..\contrib\masmx86\inffas32.asm
534
535 !IF "$(CFG)" == "zlib - Win32 DLL Release"
536
537 # PROP Exclude_From_Build 1
538
539 !ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
540
541 # PROP Exclude_From_Build 1
542
543 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
544
545 # Begin Custom Build - Assembling...
546 IntDir=.\Win32_DLL_ASM_Release
547 InputPath=..\..\contrib\masmx86\inffas32.asm
548 InputName=inffas32
549
550 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
551 ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
552
553 # End Custom Build
554
555 !ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
556
557 # Begin Custom Build - Assembling...
558 IntDir=.\Win32_DLL_ASM_Debug
559 InputPath=..\..\contrib\masmx86\inffas32.asm
560 InputName=inffas32
561
562 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
563 ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
564
565 # End Custom Build
566
567 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
568
569 # PROP Exclude_From_Build 1
570
571 !ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
572
573 # PROP Exclude_From_Build 1
574
575 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
576
577 # Begin Custom Build - Assembling...
578 IntDir=.\Win32_LIB_ASM_Release
579 InputPath=..\..\contrib\masmx86\inffas32.asm
580 InputName=inffas32
581
582 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
583 ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
584
585 # End Custom Build
586
587 !ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
588
589 # Begin Custom Build - Assembling...
590 IntDir=.\Win32_LIB_ASM_Debug
591 InputPath=..\..\contrib\masmx86\inffas32.asm
592 InputName=inffas32
593
594 "$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
595 ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
596
597 # End Custom Build
598
599 !ENDIF
600
601 # End Source File
602 # End Group
603 # Begin Source File
604
605 SOURCE=.\README.txt
606 # End Source File
607 # End Target
608 # End Project
0 Microsoft Developer Studio Workspace File, Format Version 6.00
1 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
2
3 ###############################################################################
4
5 Project: "example"=.\example.dsp - Package Owner=<4>
6
7 Package=<5>
8 {{{
9 }}}
10
11 Package=<4>
12 {{{
13 Begin Project Dependency
14 Project_Dep_Name zlib
15 End Project Dependency
16 }}}
17
18 ###############################################################################
19
20 Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>
21
22 Package=<5>
23 {{{
24 }}}
25
26 Package=<4>
27 {{{
28 Begin Project Dependency
29 Project_Dep_Name zlib
30 End Project Dependency
31 }}}
32
33 ###############################################################################
34
35 Project: "zlib"=.\zlib.dsp - Package Owner=<4>
36
37 Package=<5>
38 {{{
39 }}}
40
41 Package=<4>
42 {{{
43 }}}
44
45 ###############################################################################
46
47 Global:
48
49 Package=<5>
50 {{{
51 }}}
52
53 Package=<3>
54 {{{
55 }}}
56
57 ###############################################################################
58
0 <QPG:Generation>
1 <QPG:Options>
2 <QPG:User unattended="no" verbosity="2" listfiles="yes"/>
3 <QPG:Defaults type="qnx_package"/>
4 <QPG:Source></QPG:Source>
5 <QPG:Release number="+"/>
6 <QPG:Build></QPG:Build>
7 <QPG:FileSorting strip="yes"/>
8 <QPG:Package targets="combine"/>
9 <QPG:Repository generate="yes"/>
10 <QPG:FinalDir></QPG:FinalDir>
11 <QPG:Cleanup></QPG:Cleanup>
12 </QPG:Options>
13
14 <QPG:Responsible>
15 <QPG:Company></QPG:Company>
16 <QPG:Department></QPG:Department>
17 <QPG:Group></QPG:Group>
18 <QPG:Team></QPG:Team>
19 <QPG:Employee></QPG:Employee>
20 <QPG:EmailAddress></QPG:EmailAddress>
21 </QPG:Responsible>
22
23 <QPG:Values>
24 <QPG:Files>
25 <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
26 <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
27 <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" user="root:bin" permission="644"/>
28 <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.2"/>
29 <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.2"/>
30 <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" component="slib"/>
31 </QPG:Files>
32
33 <QPG:PackageFilter>
34 <QPM:PackageManifest>
35 <QPM:PackageDescription>
36 <QPM:PackageType>Library</QPM:PackageType>
37 <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
38 <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
39 <QPM:PackageRepository></QPM:PackageRepository>
40 <QPM:FileVersion>2.0</QPM:FileVersion>
41 </QPM:PackageDescription>
42
43 <QPM:ProductDescription>
44 <QPM:ProductName>zlib</QPM:ProductName>
45 <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
46 <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
47 <QPM:VendorName>Public</QPM:VendorName>
48 <QPM:VendorInstallName>public</QPM:VendorInstallName>
49 <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
50 <QPM:VendorEmbedURL></QPM:VendorEmbedURL>
51 <QPM:VendorEmail></QPM:VendorEmail>
52 <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
53 <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
54 <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
55 <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
56 <QPM:ProductIconSmall></QPM:ProductIconSmall>
57 <QPM:ProductIconLarge></QPM:ProductIconLarge>
58 <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
59 <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
60 <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
61 <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
62 </QPM:ProductDescription>
63
64 <QPM:ReleaseDescription>
65 <QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion>
66 <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
67 <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
68 <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
69 <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
70 <QPM:ExcludeCountries>
71 <QPM:Country></QPM:Country>
72 </QPM:ExcludeCountries>
73
74 <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
75 </QPM:ReleaseDescription>
76
77 <QPM:ContentDescription>
78 <QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
79 <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
80 <QPM:TargetOS>qnx6</QPM:TargetOS>
81 <QPM:HostOS>qnx6</QPM:HostOS>
82 <QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
83 <QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
84 </QPM:ContentDescription>
85 </QPM:PackageManifest>
86 </QPG:PackageFilter>
87
88 <QPG:PackageFilter proc="none" target="none">
89 <QPM:PackageManifest>
90 <QPM:ProductInstallationDependencies>
91 <QPM:ProductRequirements></QPM:ProductRequirements>
92 </QPM:ProductInstallationDependencies>
93
94 <QPM:ProductInstallationProcedure>
95 <QPM:Script xmlmultiple="true">
96 <QPM:ScriptName></QPM:ScriptName>
97 <QPM:ScriptType>Install</QPM:ScriptType>
98 <QPM:ScriptTiming>Post</QPM:ScriptTiming>
99 <QPM:ScriptBlocking>No</QPM:ScriptBlocking>
100 <QPM:ScriptResult>Ignore</QPM:ScriptResult>
101 <QPM:ShortDescription></QPM:ShortDescription>
102 <QPM:UseBinaries>No</QPM:UseBinaries>
103 <QPM:Priority>Optional</QPM:Priority>
104 </QPM:Script>
105 </QPM:ProductInstallationProcedure>
106 </QPM:PackageManifest>
107
108 <QPM:Launch>
109 </QPM:Launch>
110 </QPG:PackageFilter>
111
112 <QPG:PackageFilter type="core" component="none">
113 <QPM:PackageManifest>
114 <QPM:ProductInstallationProcedure>
115 <QPM:OrderDependency xmlmultiple="true">
116 <QPM:Order>InstallOver</QPM:Order>
117 <QPM:Product>zlib</QPM:Product>
118 </QPM:OrderDependency>
119 </QPM:ProductInstallationProcedure>
120 </QPM:PackageManifest>
121
122 <QPM:Launch>
123 </QPM:Launch>
124 </QPG:PackageFilter>
125
126 <QPG:PackageFilter type="core" component="dev">
127 <QPM:PackageManifest>
128 <QPM:ProductInstallationProcedure>
129 <QPM:OrderDependency xmlmultiple="true">
130 <QPM:Order>InstallOver</QPM:Order>
131 <QPM:Product>zlib-dev</QPM:Product>
132 </QPM:OrderDependency>
133 </QPM:ProductInstallationProcedure>
134 </QPM:PackageManifest>
135
136 <QPM:Launch>
137 </QPM:Launch>
138 </QPG:PackageFilter>
139 </QPG:Values>
140 </QPG:Generation>
0 /* trees.c -- output deflated data using Huffman coding
1 * Copyright (C) 1995-2004 Jean-loup Gailly
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /*
6 * ALGORITHM
7 *
8 * The "deflation" process uses several Huffman trees. The more
9 * common source values are represented by shorter bit sequences.
10 *
11 * Each code tree is stored in a compressed form which is itself
12 * a Huffman encoding of the lengths of all the code strings (in
13 * ascending order by source values). The actual code strings are
14 * reconstructed from the lengths in the inflate process, as described
15 * in the deflate specification.
16 *
17 * REFERENCES
18 *
19 * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
20 * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
21 *
22 * Storer, James A.
23 * Data Compression: Methods and Theory, pp. 49-50.
24 * Computer Science Press, 1988. ISBN 0-7167-8156-5.
25 *
26 * Sedgewick, R.
27 * Algorithms, p290.
28 * Addison-Wesley, 1983. ISBN 0-201-06672-6.
29 */
30
31 /* @(#) $Id$ */
32
33 /* #define GEN_TREES_H */
34
35 #include "deflate.h"
36
37 #ifdef DEBUG
38 # include <ctype.h>
39 #endif
40
41 /* ===========================================================================
42 * Constants
43 */
44
45 #define MAX_BL_BITS 7
46 /* Bit length codes must not exceed MAX_BL_BITS bits */
47
48 #define END_BLOCK 256
49 /* end of block literal code */
50
51 #define REP_3_6 16
52 /* repeat previous bit length 3-6 times (2 bits of repeat count) */
53
54 #define REPZ_3_10 17
55 /* repeat a zero length 3-10 times (3 bits of repeat count) */
56
57 #define REPZ_11_138 18
58 /* repeat a zero length 11-138 times (7 bits of repeat count) */
59
60 local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
61 = {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};
62
63 local const int extra_dbits[D_CODES] /* extra bits for each distance code */
64 = {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};
65
66 local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
67 = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
68
69 local const uch bl_order[BL_CODES]
70 = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
71 /* The lengths of the bit length codes are sent in order of decreasing
72 * probability, to avoid transmitting the lengths for unused bit length codes.
73 */
74
75 #define Buf_size (8 * 2*sizeof(char))
76 /* Number of bits used within bi_buf. (bi_buf might be implemented on
77 * more than 16 bits on some systems.)
78 */
79
80 /* ===========================================================================
81 * Local data. These are initialized only once.
82 */
83
84 #define DIST_CODE_LEN 512 /* see definition of array dist_code below */
85
86 #if defined(GEN_TREES_H) || !defined(STDC)
87 /* non ANSI compilers may not accept trees.h */
88
89 local ct_data static_ltree[L_CODES+2];
90 /* The static literal tree. Since the bit lengths are imposed, there is no
91 * need for the L_CODES extra codes used during heap construction. However
92 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
93 * below).
94 */
95
96 local ct_data static_dtree[D_CODES];
97 /* The static distance tree. (Actually a trivial tree since all codes use
98 * 5 bits.)
99 */
100
101 uch _dist_code[DIST_CODE_LEN];
102 /* Distance codes. The first 256 values correspond to the distances
103 * 3 .. 258, the last 256 values correspond to the top 8 bits of
104 * the 15 bit distances.
105 */
106
107 uch _length_code[MAX_MATCH-MIN_MATCH+1];
108 /* length code for each normalized match length (0 == MIN_MATCH) */
109
110 local int base_length[LENGTH_CODES];
111 /* First normalized length for each code (0 = MIN_MATCH) */
112
113 local int base_dist[D_CODES];
114 /* First normalized distance for each code (0 = distance of 1) */
115
116 #else
117 # include "trees.h"
118 #endif /* GEN_TREES_H */
119
120 struct static_tree_desc_s {
121 const ct_data *static_tree; /* static tree or NULL */
122 const intf *extra_bits; /* extra bits for each code or NULL */
123 int extra_base; /* base index for extra_bits */
124 int elems; /* max number of elements in the tree */
125 int max_length; /* max bit length for the codes */
126 };
127
128 local static_tree_desc static_l_desc =
129 {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
130
131 local static_tree_desc static_d_desc =
132 {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
133
134 local static_tree_desc static_bl_desc =
135 {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
136
137 /* ===========================================================================
138 * Local (static) routines in this file.
139 */
140
141 local void tr_static_init OF((void));
142 local void init_block OF((deflate_state *s));
143 local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
144 local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
145 local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
146 local void build_tree OF((deflate_state *s, tree_desc *desc));
147 local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
148 local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
149 local int build_bl_tree OF((deflate_state *s));
150 local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
151 int blcodes));
152 local void compress_block OF((deflate_state *s, ct_data *ltree,
153 ct_data *dtree));
154 local void set_data_type OF((deflate_state *s));
155 local unsigned bi_reverse OF((unsigned value, int length));
156 local void bi_windup OF((deflate_state *s));
157 local void bi_flush OF((deflate_state *s));
158 local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
159 int header));
160
161 #ifdef GEN_TREES_H
162 local void gen_trees_header OF((void));
163 #endif
164
165 #ifndef DEBUG
166 # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
167 /* Send a code of the given tree. c and tree must not have side effects */
168
169 #else /* DEBUG */
170 # define send_code(s, c, tree) \
171 { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
172 send_bits(s, tree[c].Code, tree[c].Len); }
173 #endif
174
175 /* ===========================================================================
176 * Output a short LSB first on the stream.
177 * IN assertion: there is enough room in pendingBuf.
178 */
179 #define put_short(s, w) { \
180 put_byte(s, (uch)((w) & 0xff)); \
181 put_byte(s, (uch)((ush)(w) >> 8)); \
182 }
183
184 /* ===========================================================================
185 * Send a value on a given number of bits.
186 * IN assertion: length <= 16 and value fits in length bits.
187 */
188 #ifdef DEBUG
189 local void send_bits OF((deflate_state *s, int value, int length));
190
191 local void send_bits(s, value, length)
192 deflate_state *s;
193 int value; /* value to send */
194 int length; /* number of bits */
195 {
196 Tracevv((stderr," l %2d v %4x ", length, value));
197 Assert(length > 0 && length <= 15, "invalid length");
198 s->bits_sent += (ulg)length;
199
200 /* If not enough room in bi_buf, use (valid) bits from bi_buf and
201 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
202 * unused bits in value.
203 */
204 if (s->bi_valid > (int)Buf_size - length) {
205 s->bi_buf |= (value << s->bi_valid);
206 put_short(s, s->bi_buf);
207 s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
208 s->bi_valid += length - Buf_size;
209 } else {
210 s->bi_buf |= value << s->bi_valid;
211 s->bi_valid += length;
212 }
213 }
214 #else /* !DEBUG */
215
216 #define send_bits(s, value, length) \
217 { int len = length;\
218 if (s->bi_valid > (int)Buf_size - len) {\
219 int val = value;\
220 s->bi_buf |= (val << s->bi_valid);\
221 put_short(s, s->bi_buf);\
222 s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
223 s->bi_valid += len - Buf_size;\
224 } else {\
225 s->bi_buf |= (value) << s->bi_valid;\
226 s->bi_valid += len;\
227 }\
228 }
229 #endif /* DEBUG */
230
231
232 /* the arguments must not have side effects */
233
234 /* ===========================================================================
235 * Initialize the various 'constant' tables.
236 */
237 local void tr_static_init()
238 {
239 #if defined(GEN_TREES_H) || !defined(STDC)
240 static int static_init_done = 0;
241 int n; /* iterates over tree elements */
242 int bits; /* bit counter */
243 int length; /* length value */
244 int code; /* code value */
245 int dist; /* distance index */
246 ush bl_count[MAX_BITS+1];
247 /* number of codes at each bit length for an optimal tree */
248
249 if (static_init_done) return;
250
251 /* For some embedded targets, global variables are not initialized: */
252 static_l_desc.static_tree = static_ltree;
253 static_l_desc.extra_bits = extra_lbits;
254 static_d_desc.static_tree = static_dtree;
255 static_d_desc.extra_bits = extra_dbits;
256 static_bl_desc.extra_bits = extra_blbits;
257
258 /* Initialize the mapping length (0..255) -> length code (0..28) */
259 length = 0;
260 for (code = 0; code < LENGTH_CODES-1; code++) {
261 base_length[code] = length;
262 for (n = 0; n < (1<<extra_lbits[code]); n++) {
263 _length_code[length++] = (uch)code;
264 }
265 }
266 Assert (length == 256, "tr_static_init: length != 256");
267 /* Note that the length 255 (match length 258) can be represented
268 * in two different ways: code 284 + 5 bits or code 285, so we
269 * overwrite length_code[255] to use the best encoding:
270 */
271 _length_code[length-1] = (uch)code;
272
273 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
274 dist = 0;
275 for (code = 0 ; code < 16; code++) {
276 base_dist[code] = dist;
277 for (n = 0; n < (1<<extra_dbits[code]); n++) {
278 _dist_code[dist++] = (uch)code;
279 }
280 }
281 Assert (dist == 256, "tr_static_init: dist != 256");
282 dist >>= 7; /* from now on, all distances are divided by 128 */
283 for ( ; code < D_CODES; code++) {
284 base_dist[code] = dist << 7;
285 for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
286 _dist_code[256 + dist++] = (uch)code;
287 }
288 }
289 Assert (dist == 256, "tr_static_init: 256+dist != 512");
290
291 /* Construct the codes of the static literal tree */
292 for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
293 n = 0;
294 while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
295 while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
296 while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
297 while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
298 /* Codes 286 and 287 do not exist, but we must include them in the
299 * tree construction to get a canonical Huffman tree (longest code
300 * all ones)
301 */
302 gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
303
304 /* The static distance tree is trivial: */
305 for (n = 0; n < D_CODES; n++) {
306 static_dtree[n].Len = 5;
307 static_dtree[n].Code = bi_reverse((unsigned)n, 5);
308 }
309 static_init_done = 1;
310
311 # ifdef GEN_TREES_H
312 gen_trees_header();
313 # endif
314 #endif /* defined(GEN_TREES_H) || !defined(STDC) */
315 }
316
317 /* ===========================================================================
318 * Genererate the file trees.h describing the static trees.
319 */
320 #ifdef GEN_TREES_H
321 # ifndef DEBUG
322 # include <stdio.h>
323 # endif
324
325 # define SEPARATOR(i, last, width) \
326 ((i) == (last)? "\n};\n\n" : \
327 ((i) % (width) == (width)-1 ? ",\n" : ", "))
328
329 void gen_trees_header()
330 {
331 FILE *header = fopen("trees.h", "w");
332 int i;
333
334 Assert (header != NULL, "Can't open trees.h");
335 fprintf(header,
336 "/* header created automatically with -DGEN_TREES_H */\n\n");
337
338 fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
339 for (i = 0; i < L_CODES+2; i++) {
340 fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
341 static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
342 }
343
344 fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
345 for (i = 0; i < D_CODES; i++) {
346 fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
347 static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
348 }
349
350 fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
351 for (i = 0; i < DIST_CODE_LEN; i++) {
352 fprintf(header, "%2u%s", _dist_code[i],
353 SEPARATOR(i, DIST_CODE_LEN-1, 20));
354 }
355
356 fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
357 for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
358 fprintf(header, "%2u%s", _length_code[i],
359 SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
360 }
361
362 fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
363 for (i = 0; i < LENGTH_CODES; i++) {
364 fprintf(header, "%1u%s", base_length[i],
365 SEPARATOR(i, LENGTH_CODES-1, 20));
366 }
367
368 fprintf(header, "local const int base_dist[D_CODES] = {\n");
369 for (i = 0; i < D_CODES; i++) {
370 fprintf(header, "%5u%s", base_dist[i],
371 SEPARATOR(i, D_CODES-1, 10));
372 }
373
374 fclose(header);
375 }
376 #endif /* GEN_TREES_H */
377
378 /* ===========================================================================
379 * Initialize the tree data structures for a new zlib stream.
380 */
381 void _tr_init(s)
382 deflate_state *s;
383 {
384 tr_static_init();
385
386 s->l_desc.dyn_tree = s->dyn_ltree;
387 s->l_desc.stat_desc = &static_l_desc;
388
389 s->d_desc.dyn_tree = s->dyn_dtree;
390 s->d_desc.stat_desc = &static_d_desc;
391
392 s->bl_desc.dyn_tree = s->bl_tree;
393 s->bl_desc.stat_desc = &static_bl_desc;
394
395 s->bi_buf = 0;
396 s->bi_valid = 0;
397 s->last_eob_len = 8; /* enough lookahead for inflate */
398 #ifdef DEBUG
399 s->compressed_len = 0L;
400 s->bits_sent = 0L;
401 #endif
402
403 /* Initialize the first block of the first file: */
404 init_block(s);
405 }
406
407 /* ===========================================================================
408 * Initialize a new block.
409 */
410 local void init_block(s)
411 deflate_state *s;
412 {
413 int n; /* iterates over tree elements */
414
415 /* Initialize the trees. */
416 for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
417 for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
418 for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
419
420 s->dyn_ltree[END_BLOCK].Freq = 1;
421 s->opt_len = s->static_len = 0L;
422 s->last_lit = s->matches = 0;
423 }
424
425 #define SMALLEST 1
426 /* Index within the heap array of least frequent node in the Huffman tree */
427
428
429 /* ===========================================================================
430 * Remove the smallest element from the heap and recreate the heap with
431 * one less element. Updates heap and heap_len.
432 */
433 #define pqremove(s, tree, top) \
434 {\
435 top = s->heap[SMALLEST]; \
436 s->heap[SMALLEST] = s->heap[s->heap_len--]; \
437 pqdownheap(s, tree, SMALLEST); \
438 }
439
440 /* ===========================================================================
441 * Compares to subtrees, using the tree depth as tie breaker when
442 * the subtrees have equal frequency. This minimizes the worst case length.
443 */
444 #define smaller(tree, n, m, depth) \
445 (tree[n].Freq < tree[m].Freq || \
446 (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
447
448 /* ===========================================================================
449 * Restore the heap property by moving down the tree starting at node k,
450 * exchanging a node with the smallest of its two sons if necessary, stopping
451 * when the heap property is re-established (each father smaller than its
452 * two sons).
453 */
454 local void pqdownheap(s, tree, k)
455 deflate_state *s;
456 ct_data *tree; /* the tree to restore */
457 int k; /* node to move down */
458 {
459 int v = s->heap[k];
460 int j = k << 1; /* left son of k */
461 while (j <= s->heap_len) {
462 /* Set j to the smallest of the two sons: */
463 if (j < s->heap_len &&
464 smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
465 j++;
466 }
467 /* Exit if v is smaller than both sons */
468 if (smaller(tree, v, s->heap[j], s->depth)) break;
469
470 /* Exchange v with the smallest son */
471 s->heap[k] = s->heap[j]; k = j;
472
473 /* And continue down the tree, setting j to the left son of k */
474 j <<= 1;
475 }
476 s->heap[k] = v;
477 }
478
479 /* ===========================================================================
480 * Compute the optimal bit lengths for a tree and update the total bit length
481 * for the current block.
482 * IN assertion: the fields freq and dad are set, heap[heap_max] and
483 * above are the tree nodes sorted by increasing frequency.
484 * OUT assertions: the field len is set to the optimal bit length, the
485 * array bl_count contains the frequencies for each bit length.
486 * The length opt_len is updated; static_len is also updated if stree is
487 * not null.
488 */
489 local void gen_bitlen(s, desc)
490 deflate_state *s;
491 tree_desc *desc; /* the tree descriptor */
492 {
493 ct_data *tree = desc->dyn_tree;
494 int max_code = desc->max_code;
495 const ct_data *stree = desc->stat_desc->static_tree;
496 const intf *extra = desc->stat_desc->extra_bits;
497 int base = desc->stat_desc->extra_base;
498 int max_length = desc->stat_desc->max_length;
499 int h; /* heap index */
500 int n, m; /* iterate over the tree elements */
501 int bits; /* bit length */
502 int xbits; /* extra bits */
503 ush f; /* frequency */
504 int overflow = 0; /* number of elements with bit length too large */
505
506 for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
507
508 /* In a first pass, compute the optimal bit lengths (which may
509 * overflow in the case of the bit length tree).
510 */
511 tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
512
513 for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
514 n = s->heap[h];
515 bits = tree[tree[n].Dad].Len + 1;
516 if (bits > max_length) bits = max_length, overflow++;
517 tree[n].Len = (ush)bits;
518 /* We overwrite tree[n].Dad which is no longer needed */
519
520 if (n > max_code) continue; /* not a leaf node */
521
522 s->bl_count[bits]++;
523 xbits = 0;
524 if (n >= base) xbits = extra[n-base];
525 f = tree[n].Freq;
526 s->opt_len += (ulg)f * (bits + xbits);
527 if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
528 }
529 if (overflow == 0) return;
530
531 Trace((stderr,"\nbit length overflow\n"));
532 /* This happens for example on obj2 and pic of the Calgary corpus */
533
534 /* Find the first bit length which could increase: */
535 do {
536 bits = max_length-1;
537 while (s->bl_count[bits] == 0) bits--;
538 s->bl_count[bits]--; /* move one leaf down the tree */
539 s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
540 s->bl_count[max_length]--;
541 /* The brother of the overflow item also moves one step up,
542 * but this does not affect bl_count[max_length]
543 */
544 overflow -= 2;
545 } while (overflow > 0);
546
547 /* Now recompute all bit lengths, scanning in increasing frequency.
548 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
549 * lengths instead of fixing only the wrong ones. This idea is taken
550 * from 'ar' written by Haruhiko Okumura.)
551 */
552 for (bits = max_length; bits != 0; bits--) {
553 n = s->bl_count[bits];
554 while (n != 0) {
555 m = s->heap[--h];
556 if (m > max_code) continue;
557 if (tree[m].Len != (unsigned) bits) {
558 Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
559 s->opt_len += ((long)bits - (long)tree[m].Len)
560 *(long)tree[m].Freq;
561 tree[m].Len = (ush)bits;
562 }
563 n--;
564 }
565 }
566 }
567
568 /* ===========================================================================
569 * Generate the codes for a given tree and bit counts (which need not be
570 * optimal).
571 * IN assertion: the array bl_count contains the bit length statistics for
572 * the given tree and the field len is set for all tree elements.
573 * OUT assertion: the field code is set for all tree elements of non
574 * zero code length.
575 */
576 local void gen_codes (tree, max_code, bl_count)
577 ct_data *tree; /* the tree to decorate */
578 int max_code; /* largest code with non zero frequency */
579 ushf *bl_count; /* number of codes at each bit length */
580 {
581 ush next_code[MAX_BITS+1]; /* next code value for each bit length */
582 ush code = 0; /* running code value */
583 int bits; /* bit index */
584 int n; /* code index */
585
586 /* The distribution counts are first used to generate the code values
587 * without bit reversal.
588 */
589 for (bits = 1; bits <= MAX_BITS; bits++) {
590 next_code[bits] = code = (code + bl_count[bits-1]) << 1;
591 }
592 /* Check that the bit counts in bl_count are consistent. The last code
593 * must be all ones.
594 */
595 Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
596 "inconsistent bit counts");
597 Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
598
599 for (n = 0; n <= max_code; n++) {
600 int len = tree[n].Len;
601 if (len == 0) continue;
602 /* Now reverse the bits */
603 tree[n].Code = bi_reverse(next_code[len]++, len);
604
605 Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
606 n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
607 }
608 }
609
610 /* ===========================================================================
611 * Construct one Huffman tree and assigns the code bit strings and lengths.
612 * Update the total bit length for the current block.
613 * IN assertion: the field freq is set for all tree elements.
614 * OUT assertions: the fields len and code are set to the optimal bit length
615 * and corresponding code. The length opt_len is updated; static_len is
616 * also updated if stree is not null. The field max_code is set.
617 */
618 local void build_tree(s, desc)
619 deflate_state *s;
620 tree_desc *desc; /* the tree descriptor */
621 {
622 ct_data *tree = desc->dyn_tree;
623 const ct_data *stree = desc->stat_desc->static_tree;
624 int elems = desc->stat_desc->elems;
625 int n, m; /* iterate over heap elements */
626 int max_code = -1; /* largest code with non zero frequency */
627 int node; /* new node being created */
628
629 /* Construct the initial heap, with least frequent element in
630 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
631 * heap[0] is not used.
632 */
633 s->heap_len = 0, s->heap_max = HEAP_SIZE;
634
635 for (n = 0; n < elems; n++) {
636 if (tree[n].Freq != 0) {
637 s->heap[++(s->heap_len)] = max_code = n;
638 s->depth[n] = 0;
639 } else {
640 tree[n].Len = 0;
641 }
642 }
643
644 /* The pkzip format requires that at least one distance code exists,
645 * and that at least one bit should be sent even if there is only one
646 * possible code. So to avoid special checks later on we force at least
647 * two codes of non zero frequency.
648 */
649 while (s->heap_len < 2) {
650 node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
651 tree[node].Freq = 1;
652 s->depth[node] = 0;
653 s->opt_len--; if (stree) s->static_len -= stree[node].Len;
654 /* node is 0 or 1 so it does not have extra bits */
655 }
656 desc->max_code = max_code;
657
658 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
659 * establish sub-heaps of increasing lengths:
660 */
661 for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
662
663 /* Construct the Huffman tree by repeatedly combining the least two
664 * frequent nodes.
665 */
666 node = elems; /* next internal node of the tree */
667 do {
668 pqremove(s, tree, n); /* n = node of least frequency */
669 m = s->heap[SMALLEST]; /* m = node of next least frequency */
670
671 s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
672 s->heap[--(s->heap_max)] = m;
673
674 /* Create a new node father of n and m */
675 tree[node].Freq = tree[n].Freq + tree[m].Freq;
676 s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
677 s->depth[n] : s->depth[m]) + 1);
678 tree[n].Dad = tree[m].Dad = (ush)node;
679 #ifdef DUMP_BL_TREE
680 if (tree == s->bl_tree) {
681 fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
682 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
683 }
684 #endif
685 /* and insert the new node in the heap */
686 s->heap[SMALLEST] = node++;
687 pqdownheap(s, tree, SMALLEST);
688
689 } while (s->heap_len >= 2);
690
691 s->heap[--(s->heap_max)] = s->heap[SMALLEST];
692
693 /* At this point, the fields freq and dad are set. We can now
694 * generate the bit lengths.
695 */
696 gen_bitlen(s, (tree_desc *)desc);
697
698 /* The field len is now set, we can generate the bit codes */
699 gen_codes ((ct_data *)tree, max_code, s->bl_count);
700 }
701
702 /* ===========================================================================
703 * Scan a literal or distance tree to determine the frequencies of the codes
704 * in the bit length tree.
705 */
706 local void scan_tree (s, tree, max_code)
707 deflate_state *s;
708 ct_data *tree; /* the tree to be scanned */
709 int max_code; /* and its largest code of non zero frequency */
710 {
711 int n; /* iterates over all tree elements */
712 int prevlen = -1; /* last emitted length */
713 int curlen; /* length of current code */
714 int nextlen = tree[0].Len; /* length of next code */
715 int count = 0; /* repeat count of the current code */
716 int max_count = 7; /* max repeat count */
717 int min_count = 4; /* min repeat count */
718
719 if (nextlen == 0) max_count = 138, min_count = 3;
720 tree[max_code+1].Len = (ush)0xffff; /* guard */
721
722 for (n = 0; n <= max_code; n++) {
723 curlen = nextlen; nextlen = tree[n+1].Len;
724 if (++count < max_count && curlen == nextlen) {
725 continue;
726 } else if (count < min_count) {
727 s->bl_tree[curlen].Freq += count;
728 } else if (curlen != 0) {
729 if (curlen != prevlen) s->bl_tree[curlen].Freq++;
730 s->bl_tree[REP_3_6].Freq++;
731 } else if (count <= 10) {
732 s->bl_tree[REPZ_3_10].Freq++;
733 } else {
734 s->bl_tree[REPZ_11_138].Freq++;
735 }
736 count = 0; prevlen = curlen;
737 if (nextlen == 0) {
738 max_count = 138, min_count = 3;
739 } else if (curlen == nextlen) {
740 max_count = 6, min_count = 3;
741 } else {
742 max_count = 7, min_count = 4;
743 }
744 }
745 }
746
747 /* ===========================================================================
748 * Send a literal or distance tree in compressed form, using the codes in
749 * bl_tree.
750 */
751 local void send_tree (s, tree, max_code)
752 deflate_state *s;
753 ct_data *tree; /* the tree to be scanned */
754 int max_code; /* and its largest code of non zero frequency */
755 {
756 int n; /* iterates over all tree elements */
757 int prevlen = -1; /* last emitted length */
758 int curlen; /* length of current code */
759 int nextlen = tree[0].Len; /* length of next code */
760 int count = 0; /* repeat count of the current code */
761 int max_count = 7; /* max repeat count */
762 int min_count = 4; /* min repeat count */
763
764 /* tree[max_code+1].Len = -1; */ /* guard already set */
765 if (nextlen == 0) max_count = 138, min_count = 3;
766
767 for (n = 0; n <= max_code; n++) {
768 curlen = nextlen; nextlen = tree[n+1].Len;
769 if (++count < max_count && curlen == nextlen) {
770 continue;
771 } else if (count < min_count) {
772 do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
773
774 } else if (curlen != 0) {
775 if (curlen != prevlen) {
776 send_code(s, curlen, s->bl_tree); count--;
777 }
778 Assert(count >= 3 && count <= 6, " 3_6?");
779 send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
780
781 } else if (count <= 10) {
782 send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
783
784 } else {
785 send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
786 }
787 count = 0; prevlen = curlen;
788 if (nextlen == 0) {
789 max_count = 138, min_count = 3;
790 } else if (curlen == nextlen) {
791 max_count = 6, min_count = 3;
792 } else {
793 max_count = 7, min_count = 4;
794 }
795 }
796 }
797
798 /* ===========================================================================
799 * Construct the Huffman tree for the bit lengths and return the index in
800 * bl_order of the last bit length code to send.
801 */
802 local int build_bl_tree(s)
803 deflate_state *s;
804 {
805 int max_blindex; /* index of last bit length code of non zero freq */
806
807 /* Determine the bit length frequencies for literal and distance trees */
808 scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
809 scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
810
811 /* Build the bit length tree: */
812 build_tree(s, (tree_desc *)(&(s->bl_desc)));
813 /* opt_len now includes the length of the tree representations, except
814 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
815 */
816
817 /* Determine the number of bit length codes to send. The pkzip format
818 * requires that at least 4 bit length codes be sent. (appnote.txt says
819 * 3 but the actual value used is 4.)
820 */
821 for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
822 if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
823 }
824 /* Update opt_len to include the bit length tree and counts */
825 s->opt_len += 3*(max_blindex+1) + 5+5+4;
826 Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
827 s->opt_len, s->static_len));
828
829 return max_blindex;
830 }
831
832 /* ===========================================================================
833 * Send the header for a block using dynamic Huffman trees: the counts, the
834 * lengths of the bit length codes, the literal tree and the distance tree.
835 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
836 */
837 local void send_all_trees(s, lcodes, dcodes, blcodes)
838 deflate_state *s;
839 int lcodes, dcodes, blcodes; /* number of codes for each tree */
840 {
841 int rank; /* index in bl_order */
842
843 Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
844 Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
845 "too many codes");
846 Tracev((stderr, "\nbl counts: "));
847 send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
848 send_bits(s, dcodes-1, 5);
849 send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
850 for (rank = 0; rank < blcodes; rank++) {
851 Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
852 send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
853 }
854 Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
855
856 send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
857 Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
858
859 send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
860 Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
861 }
862
863 /* ===========================================================================
864 * Send a stored block
865 */
866 void _tr_stored_block(s, buf, stored_len, eof)
867 deflate_state *s;
868 charf *buf; /* input block */
869 ulg stored_len; /* length of input block */
870 int eof; /* true if this is the last block for a file */
871 {
872 send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
873 #ifdef DEBUG
874 s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
875 s->compressed_len += (stored_len + 4) << 3;
876 #endif
877 copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
878 }
879
880 /* ===========================================================================
881 * Send one empty static block to give enough lookahead for inflate.
882 * This takes 10 bits, of which 7 may remain in the bit buffer.
883 * The current inflate code requires 9 bits of lookahead. If the
884 * last two codes for the previous block (real code plus EOB) were coded
885 * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
886 * the last real code. In this case we send two empty static blocks instead
887 * of one. (There are no problems if the previous block is stored or fixed.)
888 * To simplify the code, we assume the worst case of last real code encoded
889 * on one bit only.
890 */
891 void _tr_align(s)
892 deflate_state *s;
893 {
894 send_bits(s, STATIC_TREES<<1, 3);
895 send_code(s, END_BLOCK, static_ltree);
896 #ifdef DEBUG
897 s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
898 #endif
899 bi_flush(s);
900 /* Of the 10 bits for the empty block, we have already sent
901 * (10 - bi_valid) bits. The lookahead for the last real code (before
902 * the EOB of the previous block) was thus at least one plus the length
903 * of the EOB plus what we have just sent of the empty static block.
904 */
905 if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
906 send_bits(s, STATIC_TREES<<1, 3);
907 send_code(s, END_BLOCK, static_ltree);
908 #ifdef DEBUG
909 s->compressed_len += 10L;
910 #endif
911 bi_flush(s);
912 }
913 s->last_eob_len = 7;
914 }
915
916 /* ===========================================================================
917 * Determine the best encoding for the current block: dynamic trees, static
918 * trees or store, and output the encoded block to the zip file.
919 */
920 void _tr_flush_block(s, buf, stored_len, pad, eof)
921 deflate_state *s;
922 charf *buf; /* input block, or NULL if too old */
923 ulg stored_len; /* length of input block */
924 int pad; /* pad output to byte boundary */
925 int eof; /* true if this is the last block for a file */
926 {
927 ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
928 int max_blindex = 0; /* index of last bit length code of non zero freq */
929
930 /* Build the Huffman trees unless a stored block is forced */
931 if (s->level > 0) {
932
933 /* Check if the file is binary or text */
934 if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
935 set_data_type(s);
936
937 /* Construct the literal and distance trees */
938 build_tree(s, (tree_desc *)(&(s->l_desc)));
939 Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
940 s->static_len));
941
942 build_tree(s, (tree_desc *)(&(s->d_desc)));
943 Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
944 s->static_len));
945 /* At this point, opt_len and static_len are the total bit lengths of
946 * the compressed block data, excluding the tree representations.
947 */
948
949 /* Build the bit length tree for the above two trees, and get the index
950 * in bl_order of the last bit length code to send.
951 */
952 max_blindex = build_bl_tree(s);
953
954 /* Determine the best encoding. Compute the block lengths in bytes. */
955 opt_lenb = (s->opt_len+3+7)>>3;
956 static_lenb = (s->static_len+3+7)>>3;
957
958 Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
959 opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
960 s->last_lit));
961
962 if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
963
964 } else {
965 Assert(buf != (char*)0, "lost buf");
966 opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
967 }
968
969 #ifdef FORCE_STORED
970 if (buf != (char*)0) { /* force stored block */
971 #else
972 if (stored_len+4 <= opt_lenb && buf != (char*)0) {
973 /* 4: two words for the lengths */
974 #endif
975 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
976 * Otherwise we can't have processed more than WSIZE input bytes since
977 * the last block flush, because compression would have been
978 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
979 * transform a block into a stored block.
980 */
981 _tr_stored_block(s, buf, stored_len, eof);
982
983 #ifdef FORCE_STATIC
984 } else if (static_lenb >= 0) { /* force static trees */
985 #else
986 } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
987 #endif
988 send_bits(s, (STATIC_TREES<<1)+eof, 3);
989 compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
990 #ifdef DEBUG
991 s->compressed_len += 3 + s->static_len;
992 #endif
993 } else {
994 send_bits(s, (DYN_TREES<<1)+eof, 3);
995 send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
996 max_blindex+1);
997 compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
998 #ifdef DEBUG
999 s->compressed_len += 3 + s->opt_len;
1000 #endif
1001 }
1002 Assert (s->compressed_len == s->bits_sent, "bad compressed size");
1003 /* The above check is made mod 2^32, for files larger than 512 MB
1004 * and uLong implemented on 32 bits.
1005 */
1006 init_block(s);
1007
1008 if (eof) {
1009 bi_windup(s);
1010 #ifdef DEBUG
1011 s->compressed_len += 7; /* align on byte boundary */
1012 #endif
1013 #ifdef DEBUG
1014 } else if (pad && (s->compressed_len % 8) != 0) {
1015 #else
1016 } else if (pad) {
1017 #endif
1018 _tr_stored_block(s, buf, 0, eof);
1019 }
1020 Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
1021 s->compressed_len-7*eof));
1022 }
1023
1024 /* ===========================================================================
1025 * Save the match info and tally the frequency counts. Return true if
1026 * the current block must be flushed.
1027 */
1028 int _tr_tally (s, dist, lc)
1029 deflate_state *s;
1030 unsigned dist; /* distance of matched string */
1031 unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
1032 {
1033 s->d_buf[s->last_lit] = (ush)dist;
1034 s->l_buf[s->last_lit++] = (uch)lc;
1035 if (dist == 0) {
1036 /* lc is the unmatched char */
1037 s->dyn_ltree[lc].Freq++;
1038 } else {
1039 s->matches++;
1040 /* Here, lc is the match length - MIN_MATCH */
1041 dist--; /* dist = match distance - 1 */
1042 Assert((ush)dist < (ush)MAX_DIST(s) &&
1043 (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
1044 (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
1045
1046 s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
1047 s->dyn_dtree[d_code(dist)].Freq++;
1048 }
1049
1050 #ifdef TRUNCATE_BLOCK
1051 /* Try to guess if it is profitable to stop the current block here */
1052 if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
1053 /* Compute an upper bound for the compressed length */
1054 ulg out_length = (ulg)s->last_lit*8L;
1055 ulg in_length = (ulg)((long)s->strstart - s->block_start);
1056 int dcode;
1057 for (dcode = 0; dcode < D_CODES; dcode++) {
1058 out_length += (ulg)s->dyn_dtree[dcode].Freq *
1059 (5L+extra_dbits[dcode]);
1060 }
1061 out_length >>= 3;
1062 Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
1063 s->last_lit, in_length, out_length,
1064 100L - out_length*100L/in_length));
1065 if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
1066 }
1067 #endif
1068 return (s->last_lit == s->lit_bufsize-1);
1069 /* We avoid equality with lit_bufsize because of wraparound at 64K
1070 * on 16 bit machines and because stored blocks are restricted to
1071 * 64K-1 bytes.
1072 */
1073 }
1074
1075 /* ===========================================================================
1076 * Send the block data compressed using the given Huffman trees
1077 */
1078 local void compress_block(s, ltree, dtree)
1079 deflate_state *s;
1080 ct_data *ltree; /* literal tree */
1081 ct_data *dtree; /* distance tree */
1082 {
1083 unsigned dist; /* distance of matched string */
1084 int lc; /* match length or unmatched char (if dist == 0) */
1085 unsigned lx = 0; /* running index in l_buf */
1086 unsigned code; /* the code to send */
1087 int extra; /* number of extra bits to send */
1088
1089 if (s->last_lit != 0) do {
1090 dist = s->d_buf[lx];
1091 lc = s->l_buf[lx++];
1092 if (dist == 0) {
1093 send_code(s, lc, ltree); /* send a literal byte */
1094 Tracecv(isgraph(lc), (stderr," '%c' ", lc));
1095 } else {
1096 /* Here, lc is the match length - MIN_MATCH */
1097 code = _length_code[lc];
1098 send_code(s, code+LITERALS+1, ltree); /* send the length code */
1099 extra = extra_lbits[code];
1100 if (extra != 0) {
1101 lc -= base_length[code];
1102 send_bits(s, lc, extra); /* send the extra length bits */
1103 }
1104 dist--; /* dist is now the match distance - 1 */
1105 code = d_code(dist);
1106 Assert (code < D_CODES, "bad d_code");
1107
1108 send_code(s, code, dtree); /* send the distance code */
1109 extra = extra_dbits[code];
1110 if (extra != 0) {
1111 dist -= base_dist[code];
1112 send_bits(s, dist, extra); /* send the extra distance bits */
1113 }
1114 } /* literal or match pair ? */
1115
1116 /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
1117 Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
1118 "pendingBuf overflow");
1119
1120 } while (lx < s->last_lit);
1121
1122 send_code(s, END_BLOCK, ltree);
1123 s->last_eob_len = ltree[END_BLOCK].Len;
1124 }
1125
1126 /* ===========================================================================
1127 * Set the data type to BINARY or TEXT, using a crude approximation:
1128 * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
1129 * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
1130 * IN assertion: the fields Freq of dyn_ltree are set.
1131 */
1132 local void set_data_type(s)
1133 deflate_state *s;
1134 {
1135 int n;
1136
1137 for (n = 0; n < 9; n++)
1138 if (s->dyn_ltree[n].Freq != 0)
1139 break;
1140 if (n == 9)
1141 for (n = 14; n < 32; n++)
1142 if (s->dyn_ltree[n].Freq != 0)
1143 break;
1144 s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
1145 }
1146
1147 /* ===========================================================================
1148 * Reverse the first len bits of a code, using straightforward code (a faster
1149 * method would use a table)
1150 * IN assertion: 1 <= len <= 15
1151 */
1152 local unsigned bi_reverse(code, len)
1153 unsigned code; /* the value to invert */
1154 int len; /* its bit length */
1155 {
1156 register unsigned res = 0;
1157 do {
1158 res |= code & 1;
1159 code >>= 1, res <<= 1;
1160 } while (--len > 0);
1161 return res >> 1;
1162 }
1163
1164 /* ===========================================================================
1165 * Flush the bit buffer, keeping at most 7 bits in it.
1166 */
1167 local void bi_flush(s)
1168 deflate_state *s;
1169 {
1170 if (s->bi_valid == 16) {
1171 put_short(s, s->bi_buf);
1172 s->bi_buf = 0;
1173 s->bi_valid = 0;
1174 } else if (s->bi_valid >= 8) {
1175 put_byte(s, (Byte)s->bi_buf);
1176 s->bi_buf >>= 8;
1177 s->bi_valid -= 8;
1178 }
1179 }
1180
1181 /* ===========================================================================
1182 * Flush the bit buffer and align the output on a byte boundary
1183 */
1184 local void bi_windup(s)
1185 deflate_state *s;
1186 {
1187 if (s->bi_valid > 8) {
1188 put_short(s, s->bi_buf);
1189 } else if (s->bi_valid > 0) {
1190 put_byte(s, (Byte)s->bi_buf);
1191 }
1192 s->bi_buf = 0;
1193 s->bi_valid = 0;
1194 #ifdef DEBUG
1195 s->bits_sent = (s->bits_sent+7) & ~7;
1196 #endif
1197 }
1198
1199 /* ===========================================================================
1200 * Copy a stored block, storing first the length and its
1201 * one's complement if requested.
1202 */
1203 local void copy_block(s, buf, len, header)
1204 deflate_state *s;
1205 charf *buf; /* the input data */
1206 unsigned len; /* its length */
1207 int header; /* true if block header must be written */
1208 {
1209 bi_windup(s); /* align on byte boundary */
1210 s->last_eob_len = 8; /* enough lookahead for inflate */
1211
1212 if (header) {
1213 put_short(s, (ush)len);
1214 put_short(s, (ush)~len);
1215 #ifdef DEBUG
1216 s->bits_sent += 2*16;
1217 #endif
1218 }
1219 #ifdef DEBUG
1220 s->bits_sent += (ulg)len<<3;
1221 #endif
1222 while (len--) {
1223 put_byte(s, *buf++);
1224 }
1225 }
0 /* header created automatically with -DGEN_TREES_H */
1
2 local const ct_data static_ltree[L_CODES+2] = {
3 {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
4 {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
5 {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
6 {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
7 {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
8 {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
9 {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
10 {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
11 {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
12 {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
13 {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
14 {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
15 {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
16 {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
17 {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
18 {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
19 {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
20 {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
21 {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
22 {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
23 {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
24 {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
25 {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
26 {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
27 {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
28 {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
29 {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
30 {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
31 {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
32 {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
33 {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
34 {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
35 {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
36 {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
37 {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
38 {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
39 {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
40 {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
41 {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
42 {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
43 {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
44 {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
45 {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
46 {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
47 {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
48 {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
49 {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
50 {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
51 {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
52 {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
53 {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
54 {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
55 {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
56 {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
57 {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
58 {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
59 {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
60 {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
61 };
62
63 local const ct_data static_dtree[D_CODES] = {
64 {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
65 {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
66 {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
67 {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
68 {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
69 {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
70 };
71
72 const uch _dist_code[DIST_CODE_LEN] = {
73 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
74 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
75 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
76 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
77 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
78 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
79 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
80 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
81 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
82 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
83 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
84 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
85 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
86 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
87 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
88 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
89 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
90 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
91 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
92 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
93 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
94 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
95 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
96 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
97 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
98 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
99 };
100
101 const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
102 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
103 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
104 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
105 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
106 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
107 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
108 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
109 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
110 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
111 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
112 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
113 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
114 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
115 };
116
117 local const int base_length[LENGTH_CODES] = {
118 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
119 64, 80, 96, 112, 128, 160, 192, 224, 0
120 };
121
122 local const int base_dist[D_CODES] = {
123 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
124 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
125 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
126 };
127
0 /* uncompr.c -- decompress a memory buffer
1 * Copyright (C) 1995-2003 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #define ZLIB_INTERNAL
8 #include "zlib.h"
9
10 /* ===========================================================================
11 Decompresses the source buffer into the destination buffer. sourceLen is
12 the byte length of the source buffer. Upon entry, destLen is the total
13 size of the destination buffer, which must be large enough to hold the
14 entire uncompressed data. (The size of the uncompressed data must have
15 been saved previously by the compressor and transmitted to the decompressor
16 by some mechanism outside the scope of this compression library.)
17 Upon exit, destLen is the actual size of the compressed buffer.
18 This function can be used to decompress a whole file at once if the
19 input file is mmap'ed.
20
21 uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
22 enough memory, Z_BUF_ERROR if there was not enough room in the output
23 buffer, or Z_DATA_ERROR if the input data was corrupted.
24 */
25 int ZEXPORT uncompress (dest, destLen, source, sourceLen)
26 Bytef *dest;
27 uLongf *destLen;
28 const Bytef *source;
29 uLong sourceLen;
30 {
31 z_stream stream;
32 int err;
33
34 stream.next_in = (Bytef*)source;
35 stream.avail_in = (uInt)sourceLen;
36 /* Check for source > 64K on 16-bit machine: */
37 if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
38
39 stream.next_out = dest;
40 stream.avail_out = (uInt)*destLen;
41 if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
42
43 stream.zalloc = (alloc_func)0;
44 stream.zfree = (free_func)0;
45
46 err = inflateInit(&stream);
47 if (err != Z_OK) return err;
48
49 err = inflate(&stream, Z_FINISH);
50 if (err != Z_STREAM_END) {
51 inflateEnd(&stream);
52 if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
53 return Z_DATA_ERROR;
54 return err;
55 }
56 *destLen = stream.total_out;
57
58 err = inflateEnd(&stream);
59 return err;
60 }
0
1 Frequently Asked Questions about ZLIB1.DLL
2
3
4 This document describes the design, the rationale, and the usage
5 of the official DLL build of zlib, named ZLIB1.DLL. If you have
6 general questions about zlib, you should see the file "FAQ" found
7 in the zlib distribution, or at the following location:
8 http://www.gzip.org/zlib/zlib_faq.html
9
10
11 1. What is ZLIB1.DLL, and how can I get it?
12
13 - ZLIB1.DLL is the official build of zlib as a DLL.
14 (Please remark the character '1' in the name.)
15
16 Pointers to a precompiled ZLIB1.DLL can be found in the zlib
17 web site at:
18 http://www.zlib.org/
19
20 Applications that link to ZLIB1.DLL can rely on the following
21 specification:
22
23 * The exported symbols are exclusively defined in the source
24 files "zlib.h" and "zlib.def", found in an official zlib
25 source distribution.
26 * The symbols are exported by name, not by ordinal.
27 * The exported names are undecorated.
28 * The calling convention of functions is "C" (CDECL).
29 * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
30
31 The archive in which ZLIB1.DLL is bundled contains compiled
32 test programs that must run with a valid build of ZLIB1.DLL.
33 It is recommended to download the prebuilt DLL from the zlib
34 web site, instead of building it yourself, to avoid potential
35 incompatibilities that could be introduced by your compiler
36 and build settings. If you do build the DLL yourself, please
37 make sure that it complies with all the above requirements,
38 and it runs with the precompiled test programs, bundled with
39 the original ZLIB1.DLL distribution.
40
41 If, for any reason, you need to build an incompatible DLL,
42 please use a different file name.
43
44
45 2. Why did you change the name of the DLL to ZLIB1.DLL?
46 What happened to the old ZLIB.DLL?
47
48 - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
49 compilation settings that were incompatible to those used by
50 a static build. The DLL settings were supposed to be enabled
51 by defining the macro ZLIB_DLL, before including "zlib.h".
52 Incorrect handling of this macro was silently accepted at
53 build time, resulting in two major problems:
54
55 * ZLIB_DLL was missing from the old makefile. When building
56 the DLL, not all people added it to the build options. In
57 consequence, incompatible incarnations of ZLIB.DLL started
58 to circulate around the net.
59
60 * When switching from using the static library to using the
61 DLL, applications had to define the ZLIB_DLL macro and
62 to recompile all the sources that contained calls to zlib
63 functions. Failure to do so resulted in creating binaries
64 that were unable to run with the official ZLIB.DLL build.
65
66 The only possible solution that we could foresee was to make
67 a binary-incompatible change in the DLL interface, in order to
68 remove the dependency on the ZLIB_DLL macro, and to release
69 the new DLL under a different name.
70
71 We chose the name ZLIB1.DLL, where '1' indicates the major
72 zlib version number. We hope that we will not have to break
73 the binary compatibility again, at least not as long as the
74 zlib-1.x series will last.
75
76 There is still a ZLIB_DLL macro, that can trigger a more
77 efficient build and use of the DLL, but compatibility no
78 longer dependents on it.
79
80
81 3. Can I build ZLIB.DLL from the new zlib sources, and replace
82 an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
83
84 - In principle, you can do it by assigning calling convention
85 keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
86 it depends on what you mean by "an old ZLIB.DLL", because the
87 old DLL exists in several mutually-incompatible versions.
88 You have to find out first what kind of calling convention is
89 being used in your particular ZLIB.DLL build, and to use the
90 same one in the new build. If you don't know what this is all
91 about, you might be better off if you would just leave the old
92 DLL intact.
93
94
95 4. Can I compile my application using the new zlib interface, and
96 link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
97 earlier?
98
99 - The official answer is "no"; the real answer depends again on
100 what kind of ZLIB.DLL you have. Even if you are lucky, this
101 course of action is unreliable.
102
103 If you rebuild your application and you intend to use a newer
104 version of zlib (post- 1.1.4), it is strongly recommended to
105 link it to the new ZLIB1.DLL.
106
107
108 5. Why are the zlib symbols exported by name, and not by ordinal?
109
110 - Although exporting symbols by ordinal is a little faster, it
111 is risky. Any single glitch in the maintenance or use of the
112 DEF file that contains the ordinals can result in incompatible
113 builds and frustrating crashes. Simply put, the benefits of
114 exporting symbols by ordinal do not justify the risks.
115
116 Technically, it should be possible to maintain ordinals in
117 the DEF file, and still export the symbols by name. Ordinals
118 exist in every DLL, and even if the dynamic linking performed
119 at the DLL startup is searching for names, ordinals serve as
120 hints, for a faster name lookup. However, if the DEF file
121 contains ordinals, the Microsoft linker automatically builds
122 an implib that will cause the executables linked to it to use
123 those ordinals, and not the names. It is interesting to
124 notice that the GNU linker for Win32 does not suffer from this
125 problem.
126
127 It is possible to avoid the DEF file if the exported symbols
128 are accompanied by a "__declspec(dllexport)" attribute in the
129 source files. You can do this in zlib by predefining the
130 ZLIB_DLL macro.
131
132
133 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
134 convention. Why not use the STDCALL convention?
135 STDCALL is the standard convention in Win32, and I need it in
136 my Visual Basic project!
137
138 (For readability, we use CDECL to refer to the convention
139 triggered by the "__cdecl" keyword, STDCALL to refer to
140 the convention triggered by "__stdcall", and FASTCALL to
141 refer to the convention triggered by "__fastcall".)
142
143 - Most of the native Windows API functions (without varargs) use
144 indeed the WINAPI convention (which translates to STDCALL in
145 Win32), but the standard C functions use CDECL. If a user
146 application is intrinsically tied to the Windows API (e.g.
147 it calls native Windows API functions such as CreateFile()),
148 sometimes it makes sense to decorate its own functions with
149 WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
150 it calls standard C functions such as fopen()), it is not a
151 sound decision to request the inclusion of <windows.h>, or to
152 use non-ANSI constructs, for the sole purpose to make the user
153 functions STDCALL-able.
154
155 The functionality offered by zlib is not in the category of
156 "Windows functionality", but is more like "C functionality".
157
158 Technically, STDCALL is not bad; in fact, it is slightly
159 faster than CDECL, and it works with variable-argument
160 functions, just like CDECL. It is unfortunate that, in spite
161 of using STDCALL in the Windows API, it is not the default
162 convention used by the C compilers that run under Windows.
163 The roots of the problem reside deep inside the unsafety of
164 the K&R-style function prototypes, where the argument types
165 are not specified; but that is another story for another day.
166
167 The remaining fact is that CDECL is the default convention.
168 Even if an explicit convention is hard-coded into the function
169 prototypes inside C headers, problems may appear. The
170 necessity to expose the convention in users' callbacks is one
171 of these problems.
172
173 The calling convention issues are also important when using
174 zlib in other programming languages. Some of them, like Ada
175 (GNAT) and Fortran (GNU G77), have C bindings implemented
176 initially on Unix, and relying on the C calling convention.
177 On the other hand, the pre- .NET versions of Microsoft Visual
178 Basic require STDCALL, while Borland Delphi prefers, although
179 it does not require, FASTCALL.
180
181 In fairness to all possible uses of zlib outside the C
182 programming language, we choose the default "C" convention.
183 Anyone interested in different bindings or conventions is
184 encouraged to maintain specialized projects. The "contrib/"
185 directory from the zlib distribution already holds a couple
186 of foreign bindings, such as Ada, C++, and Delphi.
187
188
189 7. I need a DLL for my Visual Basic project. What can I do?
190
191 - Define the ZLIB_WINAPI macro before including "zlib.h", when
192 building both the DLL and the user application (except that
193 you don't need to define anything when using the DLL in Visual
194 Basic). The ZLIB_WINAPI macro will switch on the WINAPI
195 (STDCALL) convention. The name of this DLL must be different
196 than the official ZLIB1.DLL.
197
198 Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
199 with the ZLIB_WINAPI macro turned on, and with the minizip
200 functionality built in. For more information, please read
201 the notes inside "contrib/vstudio/readme.txt", found in the
202 zlib distribution.
203
204
205 8. I need to use zlib in my Microsoft .NET project. What can I
206 do?
207
208 - Henrik Ravn has contributed a .NET wrapper around zlib. Look
209 into contrib/dotzlib/, inside the zlib distribution.
210
211
212 9. If my application uses ZLIB1.DLL, should I link it to
213 MSVCRT.DLL? Why?
214
215 - It is not required, but it is recommended to link your
216 application to MSVCRT.DLL, if it uses ZLIB1.DLL.
217
218 The executables (.EXE, .DLL, etc.) that are involved in the
219 same process and are using the C run-time library (i.e. they
220 are calling standard C functions), must link to the same
221 library. There are several libraries in the Win32 system:
222 CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
223 Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
224 depend on it should also be linked to MSVCRT.DLL.
225
226
227 10. Why are you saying that ZLIB1.DLL and my application should
228 be linked to the same C run-time (CRT) library? I linked my
229 application and my DLLs to different C libraries (e.g. my
230 application to a static library, and my DLLs to MSVCRT.DLL),
231 and everything works fine.
232
233 - If a user library invokes only pure Win32 API (accessible via
234 <windows.h> and the related headers), its DLL build will work
235 in any context. But if this library invokes standard C API,
236 things get more complicated.
237
238 There is a single Win32 library in a Win32 system. Every
239 function in this library resides in a single DLL module, that
240 is safe to call from anywhere. On the other hand, there are
241 multiple versions of the C library, and each of them has its
242 own separate internal state. Standalone executables and user
243 DLLs that call standard C functions must link to a C run-time
244 (CRT) library, be it static or shared (DLL). Intermixing
245 occurs when an executable (not necessarily standalone) and a
246 DLL are linked to different CRTs, and both are running in the
247 same process.
248
249 Intermixing multiple CRTs is possible, as long as their
250 internal states are kept intact. The Microsoft Knowledge Base
251 articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
252 "HOWTO: Link with the Correct C Run-Time (CRT) Library"
253 mention the potential problems raised by intermixing.
254
255 If intermixing works for you, it's because your application
256 and DLLs are avoiding the corruption of each of the CRTs'
257 internal states, maybe by careful design, or maybe by fortune.
258
259 Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
260 as those provided by Borland, raises similar problems.
261
262
263 11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
264
265 - MSVCRT.DLL exists on every Windows 95 with a new service pack
266 installed, or with Microsoft Internet Explorer 4 or later, and
267 on all other Windows 4.x or later (Windows 98, Windows NT 4,
268 or later). It is freely distributable; if not present in the
269 system, it can be downloaded from Microsoft or from other
270 software provider for free.
271
272 The fact that MSVCRT.DLL does not exist on a virgin Windows 95
273 is not so problematic. Windows 95 is scarcely found nowadays,
274 Microsoft ended its support a long time ago, and many recent
275 applications from various vendors, including Microsoft, do not
276 even run on it. Furthermore, no serious user should run
277 Windows 95 without a proper update installed.
278
279
280 12. Why are you not linking ZLIB1.DLL to
281 <<my favorite C run-time library>> ?
282
283 - We considered and abandoned the following alternatives:
284
285 * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
286 LIBCMT.LIB) is not a good option. People are using the DLL
287 mainly to save disk space. If you are linking your program
288 to a static C library, you may as well consider linking zlib
289 in statically, too.
290
291 * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
292 CRTDLL.DLL is present on every Win32 installation.
293 Unfortunately, it has a series of problems: it does not
294 work properly with Microsoft's C++ libraries, it does not
295 provide support for 64-bit file offsets, (and so on...),
296 and Microsoft discontinued its support a long time ago.
297
298 * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
299 with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
300 raises problems related to the status of ZLIB1.DLL as a
301 system component. According to the Microsoft Knowledge Base
302 article KB326922 "INFO: Redistribution of the Shared C
303 Runtime Component in Visual C++ .NET", MSVCR70.DLL and
304 MSVCR71.DLL are not supposed to function as system DLLs,
305 because they may clash with MSVCRT.DLL. Instead, the
306 application's installer is supposed to put these DLLs
307 (if needed) in the application's private directory.
308 If ZLIB1.DLL depends on a non-system runtime, it cannot
309 function as a redistributable system component.
310
311 * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
312 Borland's, or Cygwin's, raises problems related to the
313 reliable presence of these runtimes on Win32 systems.
314 It's easier to let the DLL build of zlib up to the people
315 who distribute these runtimes, and who may proceed as
316 explained in the answer to Question 14.
317
318
319 13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
320 how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
321 (Visual Studio .NET) or newer?
322
323 - Due to the problems explained in the Microsoft Knowledge Base
324 article KB326922 (see the previous answer), the C runtime that
325 comes with the VC7 environment is no longer considered a
326 system component. That is, it should not be assumed that this
327 runtime exists, or may be installed in a system directory.
328 Since ZLIB1.DLL is supposed to be a system component, it may
329 not depend on a non-system component.
330
331 In order to link ZLIB1.DLL and your application to MSVCRT.DLL
332 in VC7, you need the library of Visual C++ 6.0 or older. If
333 you don't have this library at hand, it's probably best not to
334 use ZLIB1.DLL.
335
336 We are hoping that, in the future, Microsoft will provide a
337 way to build applications linked to a proper system runtime,
338 from the Visual C++ environment. Until then, you have a
339 couple of alternatives, such as linking zlib in statically.
340 If your application requires dynamic linking, you may proceed
341 as explained in the answer to Question 14.
342
343
344 14. I need to link my own DLL build to a CRT different than
345 MSVCRT.DLL. What can I do?
346
347 - Feel free to rebuild the DLL from the zlib sources, and link
348 it the way you want. You should, however, clearly state that
349 your build is unofficial. You should give it a different file
350 name, and/or install it in a private directory that can be
351 accessed by your application only, and is not visible to the
352 others (e.g. it's not in the SYSTEM or the SYSTEM32 directory,
353 and it's not in the PATH). Otherwise, your build may clash
354 with applications that link to the official build.
355
356 For example, in Cygwin, zlib is linked to the Cygwin runtime
357 CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
358
359
360 15. May I include additional pieces of code that I find useful,
361 link them in ZLIB1.DLL, and export them?
362
363 - No. A legitimate build of ZLIB1.DLL must not include code
364 that does not originate from the official zlib source code.
365 But you can make your own private DLL build, under a different
366 file name, as suggested in the previous answer.
367
368 For example, zlib is a part of the VCL library, distributed
369 with Borland Delphi and C++ Builder. The DLL build of VCL
370 is a redistributable file, named VCLxx.DLL.
371
372
373 16. May I remove some functionality out of ZLIB1.DLL, by enabling
374 macros like NO_GZCOMPRESS or NO_GZIP at compile time?
375
376 - No. A legitimate build of ZLIB1.DLL must provide the complete
377 zlib functionality, as implemented in the official zlib source
378 code. But you can make your own private DLL build, under a
379 different file name, as suggested in the previous answer.
380
381
382 17. I made my own ZLIB1.DLL build. Can I test it for compliance?
383
384 - We prefer that you download the official DLL from the zlib
385 web site. If you need something peculiar from this DLL, you
386 can send your suggestion to the zlib mailing list.
387
388 However, in case you do rebuild the DLL yourself, you can run
389 it with the test programs found in the DLL distribution.
390 Running these test programs is not a guarantee of compliance,
391 but a failure can imply a detected problem.
392
393 **
394
395 This document is written and maintained by
396 Cosmin Truta <cosmint@cs.ubbcluj.ro>
0 # Makefile for zlib
1 # Borland C++ for Win32
2 #
3 # Updated for zlib 1.2.x by Cosmin Truta, 11-Mar-2003
4 # Last updated: 28-Aug-2003
5 #
6 # Usage:
7 # make -f win32/Makefile.bor
8 # make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
9
10 # ------------ Borland C++ ------------
11
12 # Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
13 # should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
14 # added to the declaration of LOC here:
15 LOC = $(LOCAL_ZLIB)
16
17 CC = bcc32
18 AS = bcc32
19 LD = bcc32
20 AR = tlib
21 CFLAGS = -a -d -k- -O2 $(LOC)
22 ASFLAGS = $(LOC)
23 LDFLAGS = $(LOC)
24
25
26 # variables
27 ZLIB_LIB = zlib.lib
28
29 OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
30 OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
31 #OBJA =
32 OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
33 OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
34 #OBJPA=
35
36
37 # targets
38 all: $(ZLIB_LIB) example.exe minigzip.exe
39
40 .c.obj:
41 $(CC) -c $(CFLAGS) $<
42
43 .asm.obj:
44 $(AS) -c $(ASFLAGS) $<
45
46 adler32.obj: adler32.c zlib.h zconf.h
47
48 compress.obj: compress.c zlib.h zconf.h
49
50 crc32.obj: crc32.c zlib.h zconf.h crc32.h
51
52 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
53
54 gzio.obj: gzio.c zutil.h zlib.h zconf.h
55
56 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
57 inffast.h inffixed.h
58
59 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
60 inffast.h
61
62 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
63 inffast.h inffixed.h
64
65 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
66
67 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
68
69 uncompr.obj: uncompr.c zlib.h zconf.h
70
71 zutil.obj: zutil.c zutil.h zlib.h zconf.h
72
73 example.obj: example.c zlib.h zconf.h
74
75 minigzip.obj: minigzip.c zlib.h zconf.h
76
77
78 # For the sake of the old Borland make,
79 # the command line is cut to fit in the MS-DOS 128 byte limit:
80 $(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
81 -del $(ZLIB_LIB)
82 $(AR) $(ZLIB_LIB) $(OBJP1)
83 $(AR) $(ZLIB_LIB) $(OBJP2)
84 $(AR) $(ZLIB_LIB) $(OBJPA)
85
86
87 # testing
88 test: example.exe minigzip.exe
89 example
90 echo hello world | minigzip | minigzip -d
91
92 example.exe: example.obj $(ZLIB_LIB)
93 $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
94
95 minigzip.exe: minigzip.obj $(ZLIB_LIB)
96 $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
97
98
99 # cleanup
100 clean:
101 -del *.obj
102 -del *.lib
103 -del *.exe
104 -del *.tds
105 -del zlib.bak
106 -del foo.gz
0 # Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
1 # Copyright (C) 1995-1998 Jean-loup Gailly.
2 # For conditions of distribution and use, see copyright notice in zlib.h
3
4 # To compile, or to compile and test, type:
5 #
6 # make -fmakefile.emx; make test -fmakefile.emx
7 #
8
9 CC=gcc -Zwin32
10
11 #CFLAGS=-MMD -O
12 #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
13 #CFLAGS=-MMD -g -DDEBUG
14 CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
15 -Wstrict-prototypes -Wmissing-prototypes
16
17 # If cp.exe is available, replace "copy /Y" with "cp -fp" .
18 CP=copy /Y
19 # If gnu install.exe is available, replace $(CP) with ginstall.
20 INSTALL=$(CP)
21 # The default value of RM is "rm -f." If "rm.exe" is found, comment out:
22 RM=del
23 LDLIBS=-L. -lzlib
24 LD=$(CC) -s -o
25 LDSHARED=$(CC)
26
27 INCL=zlib.h zconf.h
28 LIBS=zlib.a
29
30 AR=ar rcs
31
32 prefix=/usr/local
33 exec_prefix = $(prefix)
34
35 OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
36 zutil.o inflate.o infback.o inftrees.o inffast.o
37
38 TEST_OBJS = example.o minigzip.o
39
40 all: example.exe minigzip.exe
41
42 test: all
43 ./example
44 echo hello world | .\minigzip | .\minigzip -d
45
46 %.o : %.c
47 $(CC) $(CFLAGS) -c $< -o $@
48
49 zlib.a: $(OBJS)
50 $(AR) $@ $(OBJS)
51
52 %.exe : %.o $(LIBS)
53 $(LD) $@ $< $(LDLIBS)
54
55
56 .PHONY : clean
57
58 clean:
59 $(RM) *.d
60 $(RM) *.o
61 $(RM) *.exe
62 $(RM) zlib.a
63 $(RM) foo.gz
64
65 DEPS := $(wildcard *.d)
66 ifneq ($(DEPS),)
67 include $(DEPS)
68 endif
0 # Makefile for zlib, derived from Makefile.dj2.
1 # Modified for mingw32 by C. Spieler, 6/16/98.
2 # Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
3 # Last updated: 1-Aug-2003.
4 # Tested under Cygwin and MinGW.
5
6 # Copyright (C) 1995-2003 Jean-loup Gailly.
7 # For conditions of distribution and use, see copyright notice in zlib.h
8
9 # To compile, or to compile and test, type:
10 #
11 # make -fmakefile.gcc; make test testdll -fmakefile.gcc
12 #
13 # To use the asm code, type:
14 # cp contrib/asm?86/match.S ./match.S
15 # make LOC=-DASMV OBJA=match.o -fmakefile.gcc
16 #
17 # To install libz.a, zconf.h and zlib.h in the system directories, type:
18 #
19 # make install -fmakefile.gcc
20
21 # Note:
22 # If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
23 # the DLL name should be changed from "zlib1.dll".
24
25 STATICLIB = libz.a
26 SHAREDLIB = zlib1.dll
27 IMPLIB = libzdll.a
28
29 #LOC = -DASMV
30 #LOC = -DDEBUG -g
31
32 CC = gcc
33 CFLAGS = $(LOC) -O3 -Wall
34
35 AS = $(CC)
36 ASFLAGS = $(LOC) -Wall
37
38 LD = $(CC)
39 LDFLAGS = $(LOC) -s
40
41 AR = ar
42 ARFLAGS = rcs
43
44 RC = windres
45 RCFLAGS = --define GCC_WINDRES
46
47 CP = cp -fp
48 # If GNU install is available, replace $(CP) with install.
49 INSTALL = $(CP)
50 RM = rm -f
51
52 prefix = /usr/local
53 exec_prefix = $(prefix)
54
55 OBJS = adler32.o compress.o crc32.o deflate.o gzio.o infback.o \
56 inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
57 OBJA =
58
59 all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example minigzip example_d minigzip_d
60
61 test: example minigzip
62 ./example
63 echo hello world | ./minigzip | ./minigzip -d
64
65 testdll: example_d minigzip_d
66 ./example_d
67 echo hello world | ./minigzip_d | ./minigzip_d -d
68
69 .c.o:
70 $(CC) $(CFLAGS) -c -o $@ $<
71
72 .S.o:
73 $(AS) $(ASFLAGS) -c -o $@ $<
74
75 $(STATICLIB): $(OBJS) $(OBJA)
76 $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
77
78 $(IMPLIB): $(SHAREDLIB)
79
80 $(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
81 dllwrap --driver-name $(CC) --def win32/zlib.def \
82 --implib $(IMPLIB) -o $@ $(OBJS) $(OBJA) zlibrc.o
83 strip $@
84
85 example: example.o $(STATICLIB)
86 $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
87
88 minigzip: minigzip.o $(STATICLIB)
89 $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
90
91 example_d: example.o $(IMPLIB)
92 $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
93
94 minigzip_d: minigzip.o $(IMPLIB)
95 $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
96
97 zlibrc.o: win32/zlib1.rc
98 $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
99
100
101 # INCLUDE_PATH and LIBRARY_PATH must be set.
102
103 .PHONY: install uninstall clean
104
105 install: zlib.h zconf.h $(LIB)
106 -@if not exist $(INCLUDE_PATH)/nul mkdir $(INCLUDE_PATH)
107 -@if not exist $(LIBRARY_PATH)/nul mkdir $(LIBRARY_PATH)
108 -$(INSTALL) zlib.h $(INCLUDE_PATH)
109 -$(INSTALL) zconf.h $(INCLUDE_PATH)
110 -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH)
111 -$(INSTALL) $(IMPLIB) $(LIBRARY_PATH)
112
113 uninstall:
114 -$(RM) $(INCLUDE_PATH)/zlib.h
115 -$(RM) $(INCLUDE_PATH)/zconf.h
116 -$(RM) $(LIBRARY_PATH)/$(STATICLIB)
117 -$(RM) $(LIBRARY_PATH)/$(IMPLIB)
118
119 clean:
120 -$(RM) $(STATICLIB)
121 -$(RM) $(SHAREDLIB)
122 -$(RM) $(IMPLIB)
123 -$(RM) *.o
124 -$(RM) *.exe
125 -$(RM) foo.gz
126
127 adler32.o: zlib.h zconf.h
128 compress.o: zlib.h zconf.h
129 crc32.o: crc32.h zlib.h zconf.h
130 deflate.o: deflate.h zutil.h zlib.h zconf.h
131 example.o: zlib.h zconf.h
132 gzio.o: zutil.h zlib.h zconf.h
133 inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
134 inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
135 infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
136 inftrees.o: zutil.h zlib.h zconf.h inftrees.h
137 minigzip.o: zlib.h zconf.h
138 trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
139 uncompr.o: zlib.h zconf.h
140 zutil.o: zutil.h zlib.h zconf.h
0 # Makefile for zlib -- Microsoft (Visual) C
1 #
2 # Authors:
3 # Cosmin Truta, 11-Mar-2003
4 # Christian Spieler, 19-Mar-2003
5 #
6 # Last updated:
7 # Cosmin Truta, 27-Aug-2003
8 #
9 # Usage:
10 # nmake -f win32/Makefile.msc (standard build)
11 # nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
12 # nmake -f win32/Makefile.msc LOC=-DASMV OBJA=match.obj (use ASM code)
13
14
15 # optional build flags
16 LOC =
17
18
19 # variables
20 STATICLIB = zlib.lib
21 SHAREDLIB = zlib1.dll
22 IMPLIB = zdll.lib
23
24 CC = cl
25 AS = ml
26 LD = link
27 AR = lib
28 RC = rc
29 CFLAGS = -nologo -MD -O2 $(LOC)
30 ASFLAGS = -coff
31 LDFLAGS = -nologo -release
32 ARFLAGS = -nologo
33 RCFLAGS = /dWIN32 /r
34
35 OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj \
36 inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
37 OBJA =
38
39
40 # targets
41 all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
42 example.exe minigzip.exe example_d.exe minigzip_d.exe
43
44 $(STATICLIB): $(OBJS) $(OBJA)
45 $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
46
47 $(IMPLIB): $(SHAREDLIB)
48
49 $(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res
50 $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \
51 -out:$@ $(OBJS) $(OBJA) zlib1.res
52
53 example.exe: example.obj $(STATICLIB)
54 $(LD) $(LDFLAGS) example.obj $(STATICLIB)
55
56 minigzip.exe: minigzip.obj $(STATICLIB)
57 $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
58
59 example_d.exe: example.obj $(IMPLIB)
60 $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
61
62 minigzip_d.exe: minigzip.obj $(IMPLIB)
63 $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
64
65 .c.obj:
66 $(CC) -c $(CFLAGS) $<
67
68 .asm.obj:
69 $(AS) -c $(ASFLAGS) $<
70
71 adler32.obj: adler32.c zlib.h zconf.h
72
73 compress.obj: compress.c zlib.h zconf.h
74
75 crc32.obj: crc32.c zlib.h zconf.h crc32.h
76
77 deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
78
79 gzio.obj: gzio.c zutil.h zlib.h zconf.h
80
81 infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
82 inffast.h inffixed.h
83
84 inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
85 inffast.h
86
87 inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
88 inffast.h inffixed.h
89
90 inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
91
92 trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
93
94 uncompr.obj: uncompr.c zlib.h zconf.h
95
96 zutil.obj: zutil.c zutil.h zlib.h zconf.h
97
98 example.obj: example.c zlib.h zconf.h
99
100 minigzip.obj: minigzip.c zlib.h zconf.h
101
102 zlib1.res: win32/zlib1.rc
103 $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc
104
105
106 # testing
107 test: example.exe minigzip.exe
108 example
109 echo hello world | minigzip | minigzip -d
110
111 testdll: example_d.exe minigzip_d.exe
112 example_d
113 echo hello world | minigzip_d | minigzip_d -d
114
115
116 # cleanup
117 clean:
118 -del $(STATICLIB)
119 -del $(SHAREDLIB)
120 -del $(IMPLIB)
121 -del *.obj
122 -del *.res
123 -del *.exp
124 -del *.exe
125 -del foo.gz
0
1 To build zlib using the Microsoft Visual C++ environment,
2 use the appropriate project from the projects/ directory.
0 LIBRARY
1 ; zlib data compression library
2
3 EXPORTS
4 ; basic functions
5 zlibVersion
6 deflate
7 deflateEnd
8 inflate
9 inflateEnd
10 ; advanced functions
11 deflateSetDictionary
12 deflateCopy
13 deflateReset
14 deflateParams
15 deflateBound
16 deflatePrime
17 inflateSetDictionary
18 inflateSync
19 inflateCopy
20 inflateReset
21 inflateBack
22 inflateBackEnd
23 zlibCompileFlags
24 ; utility functions
25 compress
26 compress2
27 compressBound
28 uncompress
29 gzopen
30 gzdopen
31 gzsetparams
32 gzread
33 gzwrite
34 gzprintf
35 gzputs
36 gzgets
37 gzputc
38 gzgetc
39 gzungetc
40 gzflush
41 gzseek
42 gzrewind
43 gztell
44 gzeof
45 gzclose
46 gzerror
47 gzclearerr
48 ; checksum functions
49 adler32
50 crc32
51 ; various hacks, don't look :)
52 deflateInit_
53 deflateInit2_
54 inflateInit_
55 inflateInit2_
56 inflateBackInit_
57 inflateSyncPoint
58 get_crc_table
59 zError
0 #include <windows.h>
1
2 #ifdef GCC_WINDRES
3 VS_VERSION_INFO VERSIONINFO
4 #else
5 VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
6 #endif
7 FILEVERSION 1,2,2,2
8 PRODUCTVERSION 1,2,2,2
9 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
10 #ifdef _DEBUG
11 FILEFLAGS 1
12 #else
13 FILEFLAGS 0
14 #endif
15 FILEOS VOS_DOS_WINDOWS32
16 FILETYPE VFT_DLL
17 FILESUBTYPE 0 // not used
18 BEGIN
19 BLOCK "StringFileInfo"
20 BEGIN
21 BLOCK "040904E4"
22 //language ID = U.S. English, char set = Windows, Multilingual
23 BEGIN
24 VALUE "FileDescription", "zlib data compression library\0"
25 VALUE "FileVersion", "1.2.2.2\0"
26 VALUE "InternalName", "zlib1.dll\0"
27 VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
28 VALUE "OriginalFilename", "zlib1.dll\0"
29 VALUE "ProductName", "zlib\0"
30 VALUE "ProductVersion", "1.2.2.2\0"
31 VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
32 END
33 END
34 BLOCK "VarFileInfo"
35 BEGIN
36 VALUE "Translation", 0x0409, 1252
37 END
38 END
0 /* zconf.h -- configuration of the zlib compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #ifndef ZCONF_H
8 #define ZCONF_H
9
10 /*
11 * If you *really* need a unique prefix for all types and library functions,
12 * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
13 */
14 #ifdef Z_PREFIX
15 # define deflateInit_ z_deflateInit_
16 # define deflate z_deflate
17 # define deflateEnd z_deflateEnd
18 # define inflateInit_ z_inflateInit_
19 # define inflate z_inflate
20 # define inflateEnd z_inflateEnd
21 # define deflateInit2_ z_deflateInit2_
22 # define deflateSetDictionary z_deflateSetDictionary
23 # define deflateCopy z_deflateCopy
24 # define deflateReset z_deflateReset
25 # define deflateParams z_deflateParams
26 # define deflateBound z_deflateBound
27 # define deflatePrime z_deflatePrime
28 # define inflateInit2_ z_inflateInit2_
29 # define inflateSetDictionary z_inflateSetDictionary
30 # define inflateSync z_inflateSync
31 # define inflateSyncPoint z_inflateSyncPoint
32 # define inflateCopy z_inflateCopy
33 # define inflateReset z_inflateReset
34 # define inflateBack z_inflateBack
35 # define inflateBackEnd z_inflateBackEnd
36 # define compress z_compress
37 # define compress2 z_compress2
38 # define compressBound z_compressBound
39 # define uncompress z_uncompress
40 # define adler32 z_adler32
41 # define crc32 z_crc32
42 # define get_crc_table z_get_crc_table
43 # define zError z_zError
44
45 # define alloc_func z_alloc_func
46 # define free_func z_free_func
47 # define in_func z_in_func
48 # define out_func z_out_func
49 # define Byte z_Byte
50 # define uInt z_uInt
51 # define uLong z_uLong
52 # define Bytef z_Bytef
53 # define charf z_charf
54 # define intf z_intf
55 # define uIntf z_uIntf
56 # define uLongf z_uLongf
57 # define voidpf z_voidpf
58 # define voidp z_voidp
59 #endif
60
61 #if defined(__MSDOS__) && !defined(MSDOS)
62 # define MSDOS
63 #endif
64 #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
65 # define OS2
66 #endif
67 #if defined(_WINDOWS) && !defined(WINDOWS)
68 # define WINDOWS
69 #endif
70 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
71 # define WIN32
72 #endif
73 #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
74 # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
75 # ifndef SYS16BIT
76 # define SYS16BIT
77 # endif
78 # endif
79 #endif
80
81 /*
82 * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
83 * than 64k bytes at a time (needed on systems with 16-bit int).
84 */
85 #ifdef SYS16BIT
86 # define MAXSEG_64K
87 #endif
88 #ifdef MSDOS
89 # define UNALIGNED_OK
90 #endif
91
92 #ifdef __STDC_VERSION__
93 # ifndef STDC
94 # define STDC
95 # endif
96 # if __STDC_VERSION__ >= 199901L
97 # ifndef STDC99
98 # define STDC99
99 # endif
100 # endif
101 #endif
102 #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
103 # define STDC
104 #endif
105 #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
106 # define STDC
107 #endif
108 #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
109 # define STDC
110 #endif
111 #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
112 # define STDC
113 #endif
114
115 #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
116 # define STDC
117 #endif
118
119 #ifndef STDC
120 # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
121 # define const /* note: need a more gentle solution here */
122 # endif
123 #endif
124
125 /* Some Mac compilers merge all .h files incorrectly: */
126 #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
127 # define NO_DUMMY_DECL
128 #endif
129
130 /* Maximum value for memLevel in deflateInit2 */
131 #ifndef MAX_MEM_LEVEL
132 # ifdef MAXSEG_64K
133 # define MAX_MEM_LEVEL 8
134 # else
135 # define MAX_MEM_LEVEL 9
136 # endif
137 #endif
138
139 /* Maximum value for windowBits in deflateInit2 and inflateInit2.
140 * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
141 * created by gzip. (Files created by minigzip can still be extracted by
142 * gzip.)
143 */
144 #ifndef MAX_WBITS
145 # define MAX_WBITS 15 /* 32K LZ77 window */
146 #endif
147
148 /* The memory requirements for deflate are (in bytes):
149 (1 << (windowBits+2)) + (1 << (memLevel+9))
150 that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
151 plus a few kilobytes for small objects. For example, if you want to reduce
152 the default memory requirements from 256K to 128K, compile with
153 make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
154 Of course this will generally degrade compression (there's no free lunch).
155
156 The memory requirements for inflate are (in bytes) 1 << windowBits
157 that is, 32K for windowBits=15 (default value) plus a few kilobytes
158 for small objects.
159 */
160
161 /* Type declarations */
162
163 #ifndef OF /* function prototypes */
164 # ifdef STDC
165 # define OF(args) args
166 # else
167 # define OF(args) ()
168 # endif
169 #endif
170
171 /* The following definitions for FAR are needed only for MSDOS mixed
172 * model programming (small or medium model with some far allocations).
173 * This was tested only with MSC; for other MSDOS compilers you may have
174 * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
175 * just define FAR to be empty.
176 */
177 #ifdef SYS16BIT
178 # if defined(M_I86SM) || defined(M_I86MM)
179 /* MSC small or medium model */
180 # define SMALL_MEDIUM
181 # ifdef _MSC_VER
182 # define FAR _far
183 # else
184 # define FAR far
185 # endif
186 # endif
187 # if (defined(__SMALL__) || defined(__MEDIUM__))
188 /* Turbo C small or medium model */
189 # define SMALL_MEDIUM
190 # ifdef __BORLANDC__
191 # define FAR _far
192 # else
193 # define FAR far
194 # endif
195 # endif
196 #endif
197
198 #if defined(WINDOWS) || defined(WIN32)
199 /* If building or using zlib as a DLL, define ZLIB_DLL.
200 * This is not mandatory, but it offers a little performance increase.
201 */
202 # ifdef ZLIB_DLL
203 # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
204 # ifdef ZLIB_INTERNAL
205 # define ZEXTERN extern __declspec(dllexport)
206 # else
207 # define ZEXTERN extern __declspec(dllimport)
208 # endif
209 # endif
210 # endif /* ZLIB_DLL */
211 /* If building or using zlib with the WINAPI/WINAPIV calling convention,
212 * define ZLIB_WINAPI.
213 * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
214 */
215 # ifdef ZLIB_WINAPI
216 # ifdef FAR
217 # undef FAR
218 # endif
219 # include <windows.h>
220 /* No need for _export, use ZLIB.DEF instead. */
221 /* For complete Windows compatibility, use WINAPI, not __stdcall. */
222 # define ZEXPORT WINAPI
223 # ifdef WIN32
224 # define ZEXPORTVA WINAPIV
225 # else
226 # define ZEXPORTVA FAR CDECL
227 # endif
228 # endif
229 #endif
230
231 #if defined (__BEOS__)
232 # ifdef ZLIB_DLL
233 # ifdef ZLIB_INTERNAL
234 # define ZEXPORT __declspec(dllexport)
235 # define ZEXPORTVA __declspec(dllexport)
236 # else
237 # define ZEXPORT __declspec(dllimport)
238 # define ZEXPORTVA __declspec(dllimport)
239 # endif
240 # endif
241 #endif
242
243 #ifndef ZEXTERN
244 # define ZEXTERN extern
245 #endif
246 #ifndef ZEXPORT
247 # define ZEXPORT
248 #endif
249 #ifndef ZEXPORTVA
250 # define ZEXPORTVA
251 #endif
252
253 #ifndef FAR
254 # define FAR
255 #endif
256
257 #if !defined(__MACTYPES__)
258 typedef unsigned char Byte; /* 8 bits */
259 #endif
260 typedef unsigned int uInt; /* 16 bits or more */
261 typedef unsigned long uLong; /* 32 bits or more */
262
263 #ifdef SMALL_MEDIUM
264 /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
265 # define Bytef Byte FAR
266 #else
267 typedef Byte FAR Bytef;
268 #endif
269 typedef char FAR charf;
270 typedef int FAR intf;
271 typedef uInt FAR uIntf;
272 typedef uLong FAR uLongf;
273
274 #ifdef STDC
275 typedef void const *voidpc;
276 typedef void FAR *voidpf;
277 typedef void *voidp;
278 #else
279 typedef Byte const *voidpc;
280 typedef Byte FAR *voidpf;
281 typedef Byte *voidp;
282 #endif
283
284 #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
285 # include <sys/types.h> /* for off_t */
286 # include <unistd.h> /* for SEEK_* and off_t */
287 # ifdef VMS
288 # include <unixio.h> /* for off_t */
289 # endif
290 # define z_off_t off_t
291 #endif
292 #ifndef SEEK_SET
293 # define SEEK_SET 0 /* Seek from beginning of file. */
294 # define SEEK_CUR 1 /* Seek from current position. */
295 # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
296 #endif
297 #ifndef z_off_t
298 # define z_off_t long
299 #endif
300
301 #if defined(__OS400__)
302 # define NO_vsnprintf
303 #endif
304
305 #if defined(__MVS__)
306 # define NO_vsnprintf
307 # ifdef FAR
308 # undef FAR
309 # endif
310 #endif
311
312 /* MVS linker does not support external names larger than 8 bytes */
313 #if defined(__MVS__)
314 # pragma map(deflateInit_,"DEIN")
315 # pragma map(deflateInit2_,"DEIN2")
316 # pragma map(deflateEnd,"DEEND")
317 # pragma map(deflateBound,"DEBND")
318 # pragma map(inflateInit_,"ININ")
319 # pragma map(inflateInit2_,"ININ2")
320 # pragma map(inflateEnd,"INEND")
321 # pragma map(inflateSync,"INSY")
322 # pragma map(inflateSetDictionary,"INSEDI")
323 # pragma map(compressBound,"CMBND")
324 # pragma map(inflate_table,"INTABL")
325 # pragma map(inflate_fast,"INFA")
326 # pragma map(inflate_copyright,"INCOPY")
327 #endif
328
329 #endif /* ZCONF_H */
0 /* zconf.h -- configuration of the zlib compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #ifndef ZCONF_H
8 #define ZCONF_H
9
10 /*
11 * If you *really* need a unique prefix for all types and library functions,
12 * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
13 */
14 #ifdef Z_PREFIX
15 # define deflateInit_ z_deflateInit_
16 # define deflate z_deflate
17 # define deflateEnd z_deflateEnd
18 # define inflateInit_ z_inflateInit_
19 # define inflate z_inflate
20 # define inflateEnd z_inflateEnd
21 # define deflateInit2_ z_deflateInit2_
22 # define deflateSetDictionary z_deflateSetDictionary
23 # define deflateCopy z_deflateCopy
24 # define deflateReset z_deflateReset
25 # define deflateParams z_deflateParams
26 # define deflateBound z_deflateBound
27 # define deflatePrime z_deflatePrime
28 # define inflateInit2_ z_inflateInit2_
29 # define inflateSetDictionary z_inflateSetDictionary
30 # define inflateSync z_inflateSync
31 # define inflateSyncPoint z_inflateSyncPoint
32 # define inflateCopy z_inflateCopy
33 # define inflateReset z_inflateReset
34 # define inflateBack z_inflateBack
35 # define inflateBackEnd z_inflateBackEnd
36 # define compress z_compress
37 # define compress2 z_compress2
38 # define compressBound z_compressBound
39 # define uncompress z_uncompress
40 # define adler32 z_adler32
41 # define crc32 z_crc32
42 # define get_crc_table z_get_crc_table
43 # define zError z_zError
44
45 # define alloc_func z_alloc_func
46 # define free_func z_free_func
47 # define in_func z_in_func
48 # define out_func z_out_func
49 # define Byte z_Byte
50 # define uInt z_uInt
51 # define uLong z_uLong
52 # define Bytef z_Bytef
53 # define charf z_charf
54 # define intf z_intf
55 # define uIntf z_uIntf
56 # define uLongf z_uLongf
57 # define voidpf z_voidpf
58 # define voidp z_voidp
59 #endif
60
61 #if defined(__MSDOS__) && !defined(MSDOS)
62 # define MSDOS
63 #endif
64 #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
65 # define OS2
66 #endif
67 #if defined(_WINDOWS) && !defined(WINDOWS)
68 # define WINDOWS
69 #endif
70 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
71 # define WIN32
72 #endif
73 #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
74 # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
75 # ifndef SYS16BIT
76 # define SYS16BIT
77 # endif
78 # endif
79 #endif
80
81 /*
82 * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
83 * than 64k bytes at a time (needed on systems with 16-bit int).
84 */
85 #ifdef SYS16BIT
86 # define MAXSEG_64K
87 #endif
88 #ifdef MSDOS
89 # define UNALIGNED_OK
90 #endif
91
92 #ifdef __STDC_VERSION__
93 # ifndef STDC
94 # define STDC
95 # endif
96 # if __STDC_VERSION__ >= 199901L
97 # ifndef STDC99
98 # define STDC99
99 # endif
100 # endif
101 #endif
102 #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
103 # define STDC
104 #endif
105 #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
106 # define STDC
107 #endif
108 #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
109 # define STDC
110 #endif
111 #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
112 # define STDC
113 #endif
114
115 #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
116 # define STDC
117 #endif
118
119 #ifndef STDC
120 # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
121 # define const /* note: need a more gentle solution here */
122 # endif
123 #endif
124
125 /* Some Mac compilers merge all .h files incorrectly: */
126 #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
127 # define NO_DUMMY_DECL
128 #endif
129
130 /* Maximum value for memLevel in deflateInit2 */
131 #ifndef MAX_MEM_LEVEL
132 # ifdef MAXSEG_64K
133 # define MAX_MEM_LEVEL 8
134 # else
135 # define MAX_MEM_LEVEL 9
136 # endif
137 #endif
138
139 /* Maximum value for windowBits in deflateInit2 and inflateInit2.
140 * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
141 * created by gzip. (Files created by minigzip can still be extracted by
142 * gzip.)
143 */
144 #ifndef MAX_WBITS
145 # define MAX_WBITS 15 /* 32K LZ77 window */
146 #endif
147
148 /* The memory requirements for deflate are (in bytes):
149 (1 << (windowBits+2)) + (1 << (memLevel+9))
150 that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
151 plus a few kilobytes for small objects. For example, if you want to reduce
152 the default memory requirements from 256K to 128K, compile with
153 make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
154 Of course this will generally degrade compression (there's no free lunch).
155
156 The memory requirements for inflate are (in bytes) 1 << windowBits
157 that is, 32K for windowBits=15 (default value) plus a few kilobytes
158 for small objects.
159 */
160
161 /* Type declarations */
162
163 #ifndef OF /* function prototypes */
164 # ifdef STDC
165 # define OF(args) args
166 # else
167 # define OF(args) ()
168 # endif
169 #endif
170
171 /* The following definitions for FAR are needed only for MSDOS mixed
172 * model programming (small or medium model with some far allocations).
173 * This was tested only with MSC; for other MSDOS compilers you may have
174 * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
175 * just define FAR to be empty.
176 */
177 #ifdef SYS16BIT
178 # if defined(M_I86SM) || defined(M_I86MM)
179 /* MSC small or medium model */
180 # define SMALL_MEDIUM
181 # ifdef _MSC_VER
182 # define FAR _far
183 # else
184 # define FAR far
185 # endif
186 # endif
187 # if (defined(__SMALL__) || defined(__MEDIUM__))
188 /* Turbo C small or medium model */
189 # define SMALL_MEDIUM
190 # ifdef __BORLANDC__
191 # define FAR _far
192 # else
193 # define FAR far
194 # endif
195 # endif
196 #endif
197
198 #if defined(WINDOWS) || defined(WIN32)
199 /* If building or using zlib as a DLL, define ZLIB_DLL.
200 * This is not mandatory, but it offers a little performance increase.
201 */
202 # ifdef ZLIB_DLL
203 # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
204 # ifdef ZLIB_INTERNAL
205 # define ZEXTERN extern __declspec(dllexport)
206 # else
207 # define ZEXTERN extern __declspec(dllimport)
208 # endif
209 # endif
210 # endif /* ZLIB_DLL */
211 /* If building or using zlib with the WINAPI/WINAPIV calling convention,
212 * define ZLIB_WINAPI.
213 * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
214 */
215 # ifdef ZLIB_WINAPI
216 # ifdef FAR
217 # undef FAR
218 # endif
219 # include <windows.h>
220 /* No need for _export, use ZLIB.DEF instead. */
221 /* For complete Windows compatibility, use WINAPI, not __stdcall. */
222 # define ZEXPORT WINAPI
223 # ifdef WIN32
224 # define ZEXPORTVA WINAPIV
225 # else
226 # define ZEXPORTVA FAR CDECL
227 # endif
228 # endif
229 #endif
230
231 #if defined (__BEOS__)
232 # ifdef ZLIB_DLL
233 # ifdef ZLIB_INTERNAL
234 # define ZEXPORT __declspec(dllexport)
235 # define ZEXPORTVA __declspec(dllexport)
236 # else
237 # define ZEXPORT __declspec(dllimport)
238 # define ZEXPORTVA __declspec(dllimport)
239 # endif
240 # endif
241 #endif
242
243 #ifndef ZEXTERN
244 # define ZEXTERN extern
245 #endif
246 #ifndef ZEXPORT
247 # define ZEXPORT
248 #endif
249 #ifndef ZEXPORTVA
250 # define ZEXPORTVA
251 #endif
252
253 #ifndef FAR
254 # define FAR
255 #endif
256
257 #if !defined(__MACTYPES__)
258 typedef unsigned char Byte; /* 8 bits */
259 #endif
260 typedef unsigned int uInt; /* 16 bits or more */
261 typedef unsigned long uLong; /* 32 bits or more */
262
263 #ifdef SMALL_MEDIUM
264 /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
265 # define Bytef Byte FAR
266 #else
267 typedef Byte FAR Bytef;
268 #endif
269 typedef char FAR charf;
270 typedef int FAR intf;
271 typedef uInt FAR uIntf;
272 typedef uLong FAR uLongf;
273
274 #ifdef STDC
275 typedef void const *voidpc;
276 typedef void FAR *voidpf;
277 typedef void *voidp;
278 #else
279 typedef Byte const *voidpc;
280 typedef Byte FAR *voidpf;
281 typedef Byte *voidp;
282 #endif
283
284 #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
285 # include <sys/types.h> /* for off_t */
286 # include <unistd.h> /* for SEEK_* and off_t */
287 # ifdef VMS
288 # include <unixio.h> /* for off_t */
289 # endif
290 # define z_off_t off_t
291 #endif
292 #ifndef SEEK_SET
293 # define SEEK_SET 0 /* Seek from beginning of file. */
294 # define SEEK_CUR 1 /* Seek from current position. */
295 # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
296 #endif
297 #ifndef z_off_t
298 # define z_off_t long
299 #endif
300
301 #if defined(__OS400__)
302 # define NO_vsnprintf
303 #endif
304
305 #if defined(__MVS__)
306 # define NO_vsnprintf
307 # ifdef FAR
308 # undef FAR
309 # endif
310 #endif
311
312 /* MVS linker does not support external names larger than 8 bytes */
313 #if defined(__MVS__)
314 # pragma map(deflateInit_,"DEIN")
315 # pragma map(deflateInit2_,"DEIN2")
316 # pragma map(deflateEnd,"DEEND")
317 # pragma map(deflateBound,"DEBND")
318 # pragma map(inflateInit_,"ININ")
319 # pragma map(inflateInit2_,"ININ2")
320 # pragma map(inflateEnd,"INEND")
321 # pragma map(inflateSync,"INSY")
322 # pragma map(inflateSetDictionary,"INSEDI")
323 # pragma map(compressBound,"CMBND")
324 # pragma map(inflate_table,"INTABL")
325 # pragma map(inflate_fast,"INFA")
326 # pragma map(inflate_copyright,"INCOPY")
327 #endif
328
329 #endif /* ZCONF_H */
0 .TH ZLIB 3 "30 December 2004"
1 .SH NAME
2 zlib \- compression/decompression library
3 .SH SYNOPSIS
4 [see
5 .I zlib.h
6 for full description]
7 .SH DESCRIPTION
8 The
9 .I zlib
10 library is a general purpose data compression library.
11 The code is thread safe.
12 It provides in-memory compression and decompression functions,
13 including integrity checks of the uncompressed data.
14 This version of the library supports only one compression method (deflation)
15 but other algorithms will be added later
16 and will have the same stream interface.
17 .LP
18 Compression can be done in a single step if the buffers are large enough
19 (for example if an input file is mmap'ed),
20 or can be done by repeated calls of the compression function.
21 In the latter case,
22 the application must provide more input and/or consume the output
23 (providing more output space) before each call.
24 .LP
25 The library also supports reading and writing files in
26 .IR gzip (1)
27 (.gz) format
28 with an interface similar to that of stdio.
29 .LP
30 The library does not install any signal handler.
31 The decoder checks the consistency of the compressed data,
32 so the library should never crash even in case of corrupted input.
33 .LP
34 All functions of the compression library are documented in the file
35 .IR zlib.h .
36 The distribution source includes examples of use of the library
37 in the files
38 .I example.c
39 and
40 .IR minigzip.c .
41 .LP
42 Changes to this version are documented in the file
43 .I ChangeLog
44 that accompanies the source,
45 and are concerned primarily with bug fixes and portability enhancements.
46 .LP
47 A Java implementation of
48 .I zlib
49 is available in the Java Development Kit 1.1:
50 .IP
51 http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
52 .LP
53 A Perl interface to
54 .IR zlib ,
55 written by Paul Marquess (pmqs@cpan.org),
56 is available at CPAN (Comprehensive Perl Archive Network) sites,
57 including:
58 .IP
59 http://www.cpan.org/modules/by-module/Compress/
60 .LP
61 A Python interface to
62 .IR zlib ,
63 written by A.M. Kuchling (amk@magnet.com),
64 is available in Python 1.5 and later versions:
65 .IP
66 http://www.python.org/doc/lib/module-zlib.html
67 .LP
68 A
69 .I zlib
70 binding for
71 .IR tcl (1),
72 written by Andreas Kupries (a.kupries@westend.com),
73 is availlable at:
74 .IP
75 http://www.westend.com/~kupries/doc/trf/man/man.html
76 .LP
77 An experimental package to read and write files in .zip format,
78 written on top of
79 .I zlib
80 by Gilles Vollant (info@winimage.com),
81 is available at:
82 .IP
83 http://www.winimage.com/zLibDll/unzip.html
84 and also in the
85 .I contrib/minizip
86 directory of the main
87 .I zlib
88 web site.
89 .SH "SEE ALSO"
90 The
91 .I zlib
92 web site can be found at either of these locations:
93 .IP
94 http://www.zlib.org
95 .br
96 http://www.gzip.org/zlib/
97 .LP
98 The data format used by the zlib library is described by RFC
99 (Request for Comments) 1950 to 1952 in the files:
100 .IP
101 http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
102 .br
103 http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
104 .br
105 http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
106 .LP
107 These documents are also available in other formats from:
108 .IP
109 ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
110 .LP
111 Mark Nelson (markn@ieee.org) wrote an article about
112 .I zlib
113 for the Jan. 1997 issue of Dr. Dobb's Journal;
114 a copy of the article is available at:
115 .IP
116 http://dogma.net/markn/articles/zlibtool/zlibtool.htm
117 .SH "REPORTING PROBLEMS"
118 Before reporting a problem,
119 please check the
120 .I zlib
121 web site to verify that you have the latest version of
122 .IR zlib ;
123 otherwise,
124 obtain the latest version and see if the problem still exists.
125 Please read the
126 .I zlib
127 FAQ at:
128 .IP
129 http://www.gzip.org/zlib/zlib_faq.html
130 .LP
131 before asking for help.
132 Send questions and/or comments to zlib@gzip.org,
133 or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
134 .SH AUTHORS
135 Version 1.2.2.2
136 Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
137 and Mark Adler (madler@alumni.caltech.edu).
138 .LP
139 This software is provided "as-is,"
140 without any express or implied warranty.
141 In no event will the authors be held liable for any damages
142 arising from the use of this software.
143 See the distribution directory with respect to requirements
144 governing redistribution.
145 The deflate format used by
146 .I zlib
147 was defined by Phil Katz.
148 The deflate and
149 .I zlib
150 specifications were written by L. Peter Deutsch.
151 Thanks to all the people who reported problems and suggested various
152 improvements in
153 .IR zlib ;
154 who are too numerous to cite here.
155 .LP
156 UNIX manual page by R. P. C. Rodgers,
157 U.S. National Library of Medicine (rodgers@nlm.nih.gov).
158 .\" end of man page
0 /* zlib.h -- interface of the 'zlib' general purpose compression library
1 version 1.2.2.2, December 30th, 2004
2
3 Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21 Jean-loup Gailly Mark Adler
22 jloup@gzip.org madler@alumni.caltech.edu
23
24
25 The data format used by the zlib library is described by RFCs (Request for
26 Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
27 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
28 */
29
30 #ifndef ZLIB_H
31 #define ZLIB_H
32
33 #include "zconf.h"
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 #define ZLIB_VERSION "1.2.2.f-rsyncable"
40 #define ZLIB_VERNUM 0x122f
41
42 /*
43 The 'zlib' compression library provides in-memory compression and
44 decompression functions, including integrity checks of the uncompressed
45 data. This version of the library supports only one compression method
46 (deflation) but other algorithms will be added later and will have the same
47 stream interface.
48
49 Compression can be done in a single step if the buffers are large
50 enough (for example if an input file is mmap'ed), or can be done by
51 repeated calls of the compression function. In the latter case, the
52 application must provide more input and/or consume the output
53 (providing more output space) before each call.
54
55 The compressed data format used by default by the in-memory functions is
56 the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
57 around a deflate stream, which is itself documented in RFC 1951.
58
59 The library also supports reading and writing files in gzip (.gz) format
60 with an interface similar to that of stdio using the functions that start
61 with "gz". The gzip format is different from the zlib format. gzip is a
62 gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
63
64 This library can optionally read and write gzip streams in memory as well.
65
66 The zlib format was designed to be compact and fast for use in memory
67 and on communications channels. The gzip format was designed for single-
68 file compression on file systems, has a larger header than zlib to maintain
69 directory information, and uses a different, slower check method than zlib.
70
71 The library does not install any signal handler. The decoder checks
72 the consistency of the compressed data, so the library should never
73 crash even in case of corrupted input.
74 */
75
76 typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
77 typedef void (*free_func) OF((voidpf opaque, voidpf address));
78
79 struct internal_state;
80
81 typedef struct z_stream_s {
82 Bytef *next_in; /* next input byte */
83 uInt avail_in; /* number of bytes available at next_in */
84 uLong total_in; /* total nb of input bytes read so far */
85
86 Bytef *next_out; /* next output byte should be put there */
87 uInt avail_out; /* remaining free space at next_out */
88 uLong total_out; /* total nb of bytes output so far */
89
90 char *msg; /* last error message, NULL if no error */
91 struct internal_state FAR *state; /* not visible by applications */
92
93 alloc_func zalloc; /* used to allocate the internal state */
94 free_func zfree; /* used to free the internal state */
95 voidpf opaque; /* private data object passed to zalloc and zfree */
96
97 int data_type; /* best guess about the data type: binary or text */
98 uLong adler; /* adler32 value of the uncompressed data */
99 uLong reserved; /* reserved for future use */
100 } z_stream;
101
102 typedef z_stream FAR *z_streamp;
103
104 /*
105 gzip header information passed to and from zlib routines. See RFC 1952
106 for more details on the meanings of these fields.
107 */
108 typedef struct gz_header_s {
109 int text; /* true if compressed data believed to be text */
110 uLong time; /* modification time */
111 int xflags; /* extra flags (not used when writing a gzip file) */
112 int os; /* operating system */
113 Bytef *extra; /* pointer to extra field or Z_NULL if none */
114 uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
115 uInt extra_max; /* space at extra (only when reading header) */
116 Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
117 uInt name_max; /* space at name (only when reading header) */
118 Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
119 uInt comm_max; /* space at comment (only when reading header) */
120 int hcrc; /* true if there was or will be a header crc */
121 int done; /* true when done reading gzip header (not used
122 when writing a gzip file) */
123 } gz_header;
124
125 typedef gz_header FAR *gz_headerp;
126
127 /*
128 The application must update next_in and avail_in when avail_in has
129 dropped to zero. It must update next_out and avail_out when avail_out
130 has dropped to zero. The application must initialize zalloc, zfree and
131 opaque before calling the init function. All other fields are set by the
132 compression library and must not be updated by the application.
133
134 The opaque value provided by the application will be passed as the first
135 parameter for calls of zalloc and zfree. This can be useful for custom
136 memory management. The compression library attaches no meaning to the
137 opaque value.
138
139 zalloc must return Z_NULL if there is not enough memory for the object.
140 If zlib is used in a multi-threaded application, zalloc and zfree must be
141 thread safe.
142
143 On 16-bit systems, the functions zalloc and zfree must be able to allocate
144 exactly 65536 bytes, but will not be required to allocate more than this
145 if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
146 pointers returned by zalloc for objects of exactly 65536 bytes *must*
147 have their offset normalized to zero. The default allocation function
148 provided by this library ensures this (see zutil.c). To reduce memory
149 requirements and avoid any allocation of 64K objects, at the expense of
150 compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
151
152 The fields total_in and total_out can be used for statistics or
153 progress reports. After compression, total_in holds the total size of
154 the uncompressed data and may be saved for use in the decompressor
155 (particularly if the decompressor wants to decompress everything in
156 a single step).
157 */
158
159 /* constants */
160
161 #define Z_NO_FLUSH 0
162 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
163 #define Z_SYNC_FLUSH 2
164 #define Z_FULL_FLUSH 3
165 #define Z_FINISH 4
166 #define Z_BLOCK 5
167 /* Allowed flush values; see deflate() and inflate() below for details */
168
169 #define Z_OK 0
170 #define Z_STREAM_END 1
171 #define Z_NEED_DICT 2
172 #define Z_ERRNO (-1)
173 #define Z_STREAM_ERROR (-2)
174 #define Z_DATA_ERROR (-3)
175 #define Z_MEM_ERROR (-4)
176 #define Z_BUF_ERROR (-5)
177 #define Z_VERSION_ERROR (-6)
178 /* Return codes for the compression/decompression functions. Negative
179 * values are errors, positive values are used for special but normal events.
180 */
181
182 #define Z_NO_COMPRESSION 0
183 #define Z_BEST_SPEED 1
184 #define Z_BEST_COMPRESSION 9
185 #define Z_DEFAULT_COMPRESSION (-1)
186 /* compression levels */
187
188 #define Z_FILTERED 1
189 #define Z_HUFFMAN_ONLY 2
190 #define Z_RLE 3
191 #define Z_FIXED 4
192 #define Z_DEFAULT_STRATEGY 0
193 #define Z_RSYNCABLE 0x4000
194 /* compression strategy; see deflateInit2() below for details */
195
196 #define Z_BINARY 0
197 #define Z_TEXT 1
198 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
199 #define Z_UNKNOWN 2
200 /* Possible values of the data_type field (though see inflate()) */
201
202 #define Z_DEFLATED 8
203 /* The deflate compression method (the only one supported in this version) */
204
205 #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
206
207 #define zlib_version zlibVersion()
208 /* for compatibility with versions < 1.0.2 */
209
210 /* basic functions */
211
212 ZEXTERN const char * ZEXPORT zlibVersion OF((void));
213 /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
214 If the first character differs, the library code actually used is
215 not compatible with the zlib.h header file used by the application.
216 This check is automatically made by deflateInit and inflateInit.
217 */
218
219 /*
220 ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
221
222 Initializes the internal stream state for compression. The fields
223 zalloc, zfree and opaque must be initialized before by the caller.
224 If zalloc and zfree are set to Z_NULL, deflateInit updates them to
225 use default allocation functions.
226
227 The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
228 1 gives best speed, 9 gives best compression, 0 gives no compression at
229 all (the input data is simply copied a block at a time).
230 Z_DEFAULT_COMPRESSION requests a default compromise between speed and
231 compression (currently equivalent to level 6).
232
233 deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
234 enough memory, Z_STREAM_ERROR if level is not a valid compression level,
235 Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
236 with the version assumed by the caller (ZLIB_VERSION).
237 msg is set to null if there is no error message. deflateInit does not
238 perform any compression: this will be done by deflate().
239 */
240
241
242 ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
243 /*
244 deflate compresses as much data as possible, and stops when the input
245 buffer becomes empty or the output buffer becomes full. It may introduce some
246 output latency (reading input without producing any output) except when
247 forced to flush.
248
249 The detailed semantics are as follows. deflate performs one or both of the
250 following actions:
251
252 - Compress more input starting at next_in and update next_in and avail_in
253 accordingly. If not all input can be processed (because there is not
254 enough room in the output buffer), next_in and avail_in are updated and
255 processing will resume at this point for the next call of deflate().
256
257 - Provide more output starting at next_out and update next_out and avail_out
258 accordingly. This action is forced if the parameter flush is non zero.
259 Forcing flush frequently degrades the compression ratio, so this parameter
260 should be set only when necessary (in interactive applications).
261 Some output may be provided even if flush is not set.
262
263 Before the call of deflate(), the application should ensure that at least
264 one of the actions is possible, by providing more input and/or consuming
265 more output, and updating avail_in or avail_out accordingly; avail_out
266 should never be zero before the call. The application can consume the
267 compressed output when it wants, for example when the output buffer is full
268 (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
269 and with zero avail_out, it must be called again after making room in the
270 output buffer because there might be more output pending.
271
272 Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
273 decide how much data to accumualte before producing output, in order to
274 maximize compression.
275
276 If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
277 flushed to the output buffer and the output is aligned on a byte boundary, so
278 that the decompressor can get all input data available so far. (In particular
279 avail_in is zero after the call if enough output space has been provided
280 before the call.) Flushing may degrade compression for some compression
281 algorithms and so it should be used only when necessary.
282
283 If flush is set to Z_FULL_FLUSH, all output is flushed as with
284 Z_SYNC_FLUSH, and the compression state is reset so that decompression can
285 restart from this point if previous compressed data has been damaged or if
286 random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
287 compression.
288
289 If deflate returns with avail_out == 0, this function must be called again
290 with the same value of the flush parameter and more output space (updated
291 avail_out), until the flush is complete (deflate returns with non-zero
292 avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
293 avail_out is greater than six to avoid repeated flush markers due to
294 avail_out == 0 on return.
295
296 If the parameter flush is set to Z_FINISH, pending input is processed,
297 pending output is flushed and deflate returns with Z_STREAM_END if there
298 was enough output space; if deflate returns with Z_OK, this function must be
299 called again with Z_FINISH and more output space (updated avail_out) but no
300 more input data, until it returns with Z_STREAM_END or an error. After
301 deflate has returned Z_STREAM_END, the only possible operations on the
302 stream are deflateReset or deflateEnd.
303
304 Z_FINISH can be used immediately after deflateInit if all the compression
305 is to be done in a single step. In this case, avail_out must be at least
306 the value returned by deflateBound (see below). If deflate does not return
307 Z_STREAM_END, then it must be called again as described above.
308
309 deflate() sets strm->adler to the adler32 checksum of all input read
310 so far (that is, total_in bytes).
311
312 deflate() may update strm->data_type if it can make a good guess about
313 the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
314 binary. This field is only for information purposes and does not affect
315 the compression algorithm in any manner.
316
317 deflate() returns Z_OK if some progress has been made (more input
318 processed or more output produced), Z_STREAM_END if all input has been
319 consumed and all output has been produced (only when flush is set to
320 Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
321 if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
322 (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
323 fatal, and deflate() can be called again with more input and more output
324 space to continue compressing.
325 */
326
327
328 ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
329 /*
330 All dynamically allocated data structures for this stream are freed.
331 This function discards any unprocessed input and does not flush any
332 pending output.
333
334 deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
335 stream state was inconsistent, Z_DATA_ERROR if the stream was freed
336 prematurely (some input or output was discarded). In the error case,
337 msg may be set but then points to a static string (which must not be
338 deallocated).
339 */
340
341
342 /*
343 ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
344
345 Initializes the internal stream state for decompression. The fields
346 next_in, avail_in, zalloc, zfree and opaque must be initialized before by
347 the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
348 value depends on the compression method), inflateInit determines the
349 compression method from the zlib header and allocates all data structures
350 accordingly; otherwise the allocation will be deferred to the first call of
351 inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
352 use default allocation functions.
353
354 inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
355 memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
356 version assumed by the caller. msg is set to null if there is no error
357 message. inflateInit does not perform any decompression apart from reading
358 the zlib header if present: this will be done by inflate(). (So next_in and
359 avail_in may be modified, but next_out and avail_out are unchanged.)
360 */
361
362
363 ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
364 /*
365 inflate decompresses as much data as possible, and stops when the input
366 buffer becomes empty or the output buffer becomes full. It may introduce
367 some output latency (reading input without producing any output) except when
368 forced to flush.
369
370 The detailed semantics are as follows. inflate performs one or both of the
371 following actions:
372
373 - Decompress more input starting at next_in and update next_in and avail_in
374 accordingly. If not all input can be processed (because there is not
375 enough room in the output buffer), next_in is updated and processing
376 will resume at this point for the next call of inflate().
377
378 - Provide more output starting at next_out and update next_out and avail_out
379 accordingly. inflate() provides as much output as possible, until there
380 is no more input data or no more space in the output buffer (see below
381 about the flush parameter).
382
383 Before the call of inflate(), the application should ensure that at least
384 one of the actions is possible, by providing more input and/or consuming
385 more output, and updating the next_* and avail_* values accordingly.
386 The application can consume the uncompressed output when it wants, for
387 example when the output buffer is full (avail_out == 0), or after each
388 call of inflate(). If inflate returns Z_OK and with zero avail_out, it
389 must be called again after making room in the output buffer because there
390 might be more output pending.
391
392 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
393 Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
394 output as possible to the output buffer. Z_BLOCK requests that inflate() stop
395 if and when it gets to the next deflate block boundary. When decoding the
396 zlib or gzip format, this will cause inflate() to return immediately after
397 the header and before the first block. When doing a raw inflate, inflate()
398 will go ahead and process the first block, and will return when it gets to
399 the end of that block, or when it runs out of data.
400
401 The Z_BLOCK option assists in appending to or combining deflate streams.
402 Also to assist in this, on return inflate() will set strm->data_type to the
403 number of unused bits in the last byte taken from strm->next_in, plus 64
404 if inflate() is currently decoding the last block in the deflate stream,
405 plus 128 if inflate() returned immediately after decoding an end-of-block
406 code or decoding the complete header up to just before the first byte of the
407 deflate stream. The end-of-block will not be indicated until all of the
408 uncompressed data from that block has been written to strm->next_out. The
409 number of unused bits may in general be greater than seven, except when
410 bit 7 of data_type is set, in which case the number of unused bits will be
411 less than eight.
412
413 inflate() should normally be called until it returns Z_STREAM_END or an
414 error. However if all decompression is to be performed in a single step
415 (a single call of inflate), the parameter flush should be set to
416 Z_FINISH. In this case all pending input is processed and all pending
417 output is flushed; avail_out must be large enough to hold all the
418 uncompressed data. (The size of the uncompressed data may have been saved
419 by the compressor for this purpose.) The next operation on this stream must
420 be inflateEnd to deallocate the decompression state. The use of Z_FINISH
421 is never required, but can be used to inform inflate that a faster approach
422 may be used for the single inflate() call.
423
424 In this implementation, inflate() always flushes as much output as
425 possible to the output buffer, and always uses the faster approach on the
426 first call. So the only effect of the flush parameter in this implementation
427 is on the return value of inflate(), as noted below, or when it returns early
428 because Z_BLOCK is used.
429
430 If a preset dictionary is needed after this call (see inflateSetDictionary
431 below), inflate sets strm->adler to the adler32 checksum of the dictionary
432 chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
433 strm->adler to the adler32 checksum of all output produced so far (that is,
434 total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
435 below. At the end of the stream, inflate() checks that its computed adler32
436 checksum is equal to that saved by the compressor and returns Z_STREAM_END
437 only if the checksum is correct.
438
439 inflate() will decompress and check either zlib-wrapped or gzip-wrapped
440 deflate data. The header type is detected automatically. Any information
441 contained in the gzip header is not retained, so applications that need that
442 information should instead use raw inflate, see inflateInit2() below, or
443 inflateBack() and perform their own processing of the gzip header and
444 trailer.
445
446 inflate() returns Z_OK if some progress has been made (more input processed
447 or more output produced), Z_STREAM_END if the end of the compressed data has
448 been reached and all uncompressed output has been produced, Z_NEED_DICT if a
449 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
450 corrupted (input stream not conforming to the zlib format or incorrect check
451 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
452 if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
453 Z_BUF_ERROR if no progress is possible or if there was not enough room in the
454 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
455 inflate() can be called again with more input and more output space to
456 continue decompressing. If Z_DATA_ERROR is returned, the application may then
457 call inflateSync() to look for a good compression block if a partial recovery
458 of the data is desired.
459 */
460
461
462 ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
463 /*
464 All dynamically allocated data structures for this stream are freed.
465 This function discards any unprocessed input and does not flush any
466 pending output.
467
468 inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
469 was inconsistent. In the error case, msg may be set but then points to a
470 static string (which must not be deallocated).
471 */
472
473 /* Advanced functions */
474
475 /*
476 The following functions are needed only in some special applications.
477 */
478
479 /*
480 ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
481 int level,
482 int method,
483 int windowBits,
484 int memLevel,
485 int strategy));
486
487 This is another version of deflateInit with more compression options. The
488 fields next_in, zalloc, zfree and opaque must be initialized before by
489 the caller.
490
491 The method parameter is the compression method. It must be Z_DEFLATED in
492 this version of the library.
493
494 The windowBits parameter is the base two logarithm of the window size
495 (the size of the history buffer). It should be in the range 8..15 for this
496 version of the library. Larger values of this parameter result in better
497 compression at the expense of memory usage. The default value is 15 if
498 deflateInit is used instead.
499
500 windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
501 determines the window size. deflate() will then generate raw deflate data
502 with no zlib header or trailer, and will not compute an adler32 check value.
503
504 windowBits can also be greater than 15 for optional gzip encoding. Add
505 16 to windowBits to write a simple gzip header and trailer around the
506 compressed data instead of a zlib wrapper. The gzip header will have no
507 file name, no extra data, no comment, no modification time (set to zero),
508 no header crc, and the operating system will be set to 255 (unknown). If a
509 gzip stream is being written, strm->adler is a crc32 instead of an adler32.
510
511 The memLevel parameter specifies how much memory should be allocated
512 for the internal compression state. memLevel=1 uses minimum memory but
513 is slow and reduces compression ratio; memLevel=9 uses maximum memory
514 for optimal speed. The default value is 8. See zconf.h for total memory
515 usage as a function of windowBits and memLevel.
516
517 The strategy parameter is used to tune the compression algorithm. Use the
518 value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
519 filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
520 string match), or Z_RLE to limit match distances to one (run-length
521 encoding). Filtered data consists mostly of small values with a somewhat
522 random distribution. In this case, the compression algorithm is tuned to
523 compress them better. The effect of Z_FILTERED is to force more Huffman
524 coding and less string matching; it is somewhat intermediate between
525 Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
526 Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
527 parameter only affects the compression ratio but not the correctness of the
528 compressed output even if it is not set appropriately. Z_FIXED prevents the
529 use of dynamic Huffman codes, allowing for a simpler decoder for special
530 applications.
531
532 deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
533 memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
534 method). msg is set to null if there is no error message. deflateInit2 does
535 not perform any compression: this will be done by deflate().
536 */
537
538 ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
539 const Bytef *dictionary,
540 uInt dictLength));
541 /*
542 Initializes the compression dictionary from the given byte sequence
543 without producing any compressed output. This function must be called
544 immediately after deflateInit, deflateInit2 or deflateReset, before any
545 call of deflate. The compressor and decompressor must use exactly the same
546 dictionary (see inflateSetDictionary).
547
548 The dictionary should consist of strings (byte sequences) that are likely
549 to be encountered later in the data to be compressed, with the most commonly
550 used strings preferably put towards the end of the dictionary. Using a
551 dictionary is most useful when the data to be compressed is short and can be
552 predicted with good accuracy; the data can then be compressed better than
553 with the default empty dictionary.
554
555 Depending on the size of the compression data structures selected by
556 deflateInit or deflateInit2, a part of the dictionary may in effect be
557 discarded, for example if the dictionary is larger than the window size in
558 deflate or deflate2. Thus the strings most likely to be useful should be
559 put at the end of the dictionary, not at the front.
560
561 Upon return of this function, strm->adler is set to the adler32 value
562 of the dictionary; the decompressor may later use this value to determine
563 which dictionary has been used by the compressor. (The adler32 value
564 applies to the whole dictionary even if only a subset of the dictionary is
565 actually used by the compressor.) If a raw deflate was requested, then the
566 adler32 value is not computed and strm->adler is not set.
567
568 deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
569 parameter is invalid (such as NULL dictionary) or the stream state is
570 inconsistent (for example if deflate has already been called for this stream
571 or if the compression method is bsort). deflateSetDictionary does not
572 perform any compression: this will be done by deflate().
573 */
574
575 ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
576 z_streamp source));
577 /*
578 Sets the destination stream as a complete copy of the source stream.
579
580 This function can be useful when several compression strategies will be
581 tried, for example when there are several ways of pre-processing the input
582 data with a filter. The streams that will be discarded should then be freed
583 by calling deflateEnd. Note that deflateCopy duplicates the internal
584 compression state which can be quite large, so this strategy is slow and
585 can consume lots of memory.
586
587 deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
588 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
589 (such as zalloc being NULL). msg is left unchanged in both source and
590 destination.
591 */
592
593 ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
594 /*
595 This function is equivalent to deflateEnd followed by deflateInit,
596 but does not free and reallocate all the internal compression state.
597 The stream will keep the same compression level and any other attributes
598 that may have been set by deflateInit2.
599
600 deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
601 stream state was inconsistent (such as zalloc or state being NULL).
602 */
603
604 ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
605 int level,
606 int strategy));
607 /*
608 Dynamically update the compression level and compression strategy. The
609 interpretation of level and strategy is as in deflateInit2. This can be
610 used to switch between compression and straight copy of the input data, or
611 to switch to a different kind of input data requiring a different
612 strategy. If the compression level is changed, the input available so far
613 is compressed with the old level (and may be flushed); the new level will
614 take effect only at the next call of deflate().
615
616 Before the call of deflateParams, the stream state must be set as for
617 a call of deflate(), since the currently available input may have to
618 be compressed and flushed. In particular, strm->avail_out must be non-zero.
619
620 deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
621 stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
622 if strm->avail_out was zero.
623 */
624
625 ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
626 uLong sourceLen));
627 /*
628 deflateBound() returns an upper bound on the compressed size after
629 deflation of sourceLen bytes. It must be called after deflateInit()
630 or deflateInit2(). This would be used to allocate an output buffer
631 for deflation in a single pass, and so would be called before deflate().
632 */
633
634 ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
635 int bits,
636 int value));
637 /*
638 deflatePrime() inserts bits in the deflate output stream. The intent
639 is that this function is used to start off the deflate output with the
640 bits leftover from a previous deflate stream when appending to it. As such,
641 this function can only be used for raw deflate, and must be used before the
642 first deflate() call after a deflateInit2() or deflateReset(). bits must be
643 less than or equal to 16, and that many of the least significant bits of
644 value will be inserted in the output.
645
646 deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
647 stream state was inconsistent.
648 */
649
650 ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
651 gz_headerp head));
652 /*
653 deflateSetHeader() provides gzip header information for when a gzip
654 stream is requested by deflateInit2(). deflateSetHeader() may be called
655 after deflateInit2() or deflateReset() and before the first call of
656 deflate(). The text, time, os, extra field, name, and comment information
657 in the provided gz_header structure are written to the gzip header (xflag is
658 ignored -- the extra flags are set according to the compression level). The
659 caller must assure that, if not Z_NULL, name and comment are terminated with
660 a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
661 available there. If hcrc is true, a gzip header crc is included. Note that
662 the current versions of the command-line version of gzip (up through version
663 1.3.x) do not support header crc's, and will report that it is a "multi-part
664 gzip file" and give up.
665
666 If deflateSetHeader is not used, the default gzip header has text false,
667 the time set to zero, and os set to 255, with no extra, name, or comment
668 fields. The gzip header is returned to the default state by deflateReset().
669
670 deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
671 stream state was inconsistent.
672 */
673
674 /*
675 ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
676 int windowBits));
677
678 This is another version of inflateInit with an extra parameter. The
679 fields next_in, avail_in, zalloc, zfree and opaque must be initialized
680 before by the caller.
681
682 The windowBits parameter is the base two logarithm of the maximum window
683 size (the size of the history buffer). It should be in the range 8..15 for
684 this version of the library. The default value is 15 if inflateInit is used
685 instead. windowBits must be greater than or equal to the windowBits value
686 provided to deflateInit2() while compressing, or it must be equal to 15 if
687 deflateInit2() was not used. If a compressed stream with a larger window
688 size is given as input, inflate() will return with the error code
689 Z_DATA_ERROR instead of trying to allocate a larger window.
690
691 windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
692 determines the window size. inflate() will then process raw deflate data,
693 not looking for a zlib or gzip header, not generating a check value, and not
694 looking for any check values for comparison at the end of the stream. This
695 is for use with other formats that use the deflate compressed data format
696 such as zip. Those formats provide their own check values. If a custom
697 format is developed using the raw deflate format for compressed data, it is
698 recommended that a check value such as an adler32 or a crc32 be applied to
699 the uncompressed data as is done in the zlib, gzip, and zip formats. For
700 most applications, the zlib format should be used as is. Note that comments
701 above on the use in deflateInit2() applies to the magnitude of windowBits.
702
703 windowBits can also be greater than 15 for optional gzip decoding. Add
704 32 to windowBits to enable zlib and gzip decoding with automatic header
705 detection, or add 16 to decode only the gzip format (the zlib format will
706 return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is
707 a crc32 instead of an adler32.
708
709 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
710 memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
711 memLevel). msg is set to null if there is no error message. inflateInit2
712 does not perform any decompression apart from reading the zlib header if
713 present: this will be done by inflate(). (So next_in and avail_in may be
714 modified, but next_out and avail_out are unchanged.)
715 */
716
717 ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
718 const Bytef *dictionary,
719 uInt dictLength));
720 /*
721 Initializes the decompression dictionary from the given uncompressed byte
722 sequence. This function must be called immediately after a call of inflate,
723 if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
724 can be determined from the adler32 value returned by that call of inflate.
725 The compressor and decompressor must use exactly the same dictionary (see
726 deflateSetDictionary). For raw inflate, this function can be called
727 immediately after inflateInit2() or inflateReset() and before any call of
728 inflate() to set the dictionary. The application must insure that the
729 dictionary that was used for compression is provided.
730
731 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
732 parameter is invalid (such as NULL dictionary) or the stream state is
733 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
734 expected one (incorrect adler32 value). inflateSetDictionary does not
735 perform any decompression: this will be done by subsequent calls of
736 inflate().
737 */
738
739 ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
740 /*
741 Skips invalid compressed data until a full flush point (see above the
742 description of deflate with Z_FULL_FLUSH) can be found, or until all
743 available input is skipped. No output is provided.
744
745 inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
746 if no more input was provided, Z_DATA_ERROR if no flush point has been found,
747 or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
748 case, the application may save the current current value of total_in which
749 indicates where valid compressed data was found. In the error case, the
750 application may repeatedly call inflateSync, providing more input each time,
751 until success or end of the input data.
752 */
753
754 ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
755 z_streamp source));
756 /*
757 Sets the destination stream as a complete copy of the source stream.
758
759 This function can be useful when randomly accessing a large stream. The
760 first pass through the stream can periodically record the inflate state,
761 allowing restarting inflate at those points when randomly accessing the
762 stream.
763
764 inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
765 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
766 (such as zalloc being NULL). msg is left unchanged in both source and
767 destination.
768 */
769
770 ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
771 /*
772 This function is equivalent to inflateEnd followed by inflateInit,
773 but does not free and reallocate all the internal decompression state.
774 The stream will keep attributes that may have been set by inflateInit2.
775
776 inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
777 stream state was inconsistent (such as zalloc or state being NULL).
778 */
779
780 ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
781 gz_headerp head));
782 /*
783 inflateGetHeader() requests that gzip header information be stored in the
784 provided gz_header structure. inflateGetHeader() may be called after
785 inflateInit2() or inflateReset(), and before the first call of inflate().
786 As inflate() processes the gzip stream, head->done is zero until the header
787 is completed, at which time head->done is set to one. If a zlib stream is
788 being decoded, then head->done is set to -1 to indicate that there will be
789 no gzip header information forthcoming. Note that Z_BLOCK can be used to
790 force inflate() to return immediately after header processing is complete
791 and before any actual data is decompressed.
792
793 The text, time, xflags, and os fields are filled in with the gzip header
794 contents. hcrc is set to true if there is a header CRC. (The header CRC
795 was valid if done is set to one.) If extra is not Z_NULL, then extra_max
796 contains the maximum number of bytes to write to extra. Once done is true,
797 extra_len contains the actual extra field length, and extra contains the
798 extra field, or that field truncated if extra_max is less than extra_len.
799 If name is not Z_NULL, then up to name_max characters are written there,
800 terminated with a zero unless the length is greater than name_max. If
801 comment is not Z_NULL, then up to comm_max characters are written there,
802 terminated with a zero unless the length is greater than comm_max. When
803 any of extra, name, or comment are not Z_NULL and the respective field is
804 not present in the header, then that field is set to Z_NULL to signal its
805 absence. This allows the use of deflateSetHeader() with the returned
806 structure to duplicate the header. However if those fields are set to
807 allocated memory, then the application will need to save those pointers
808 elsewhere so that they can be eventually freed.
809
810 If inflateGetHeader is not used, then the header information is simply
811 discarded. The header is always checked for validity, including the header
812 CRC if present. inflateReset() will reset the process to discard the header
813 information. The application would need to call inflateGetHeader() again to
814 retrieve the header from the next gzip stream.
815
816 inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
817 stream state was inconsistent.
818 */
819
820 /*
821 ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
822 unsigned char FAR *window));
823
824 Initialize the internal stream state for decompression using inflateBack()
825 calls. The fields zalloc, zfree and opaque in strm must be initialized
826 before the call. If zalloc and zfree are Z_NULL, then the default library-
827 derived memory allocation routines are used. windowBits is the base two
828 logarithm of the window size, in the range 8..15. window is a caller
829 supplied buffer of that size. Except for special applications where it is
830 assured that deflate was used with small window sizes, windowBits must be 15
831 and a 32K byte window must be supplied to be able to decompress general
832 deflate streams.
833
834 See inflateBack() for the usage of these routines.
835
836 inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
837 the paramaters are invalid, Z_MEM_ERROR if the internal state could not
838 be allocated, or Z_VERSION_ERROR if the version of the library does not
839 match the version of the header file.
840 */
841
842 typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
843 typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
844
845 ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
846 in_func in, void FAR *in_desc,
847 out_func out, void FAR *out_desc));
848 /*
849 inflateBack() does a raw inflate with a single call using a call-back
850 interface for input and output. This is more efficient than inflate() for
851 file i/o applications in that it avoids copying between the output and the
852 sliding window by simply making the window itself the output buffer. This
853 function trusts the application to not change the output buffer passed by
854 the output function, at least until inflateBack() returns.
855
856 inflateBackInit() must be called first to allocate the internal state
857 and to initialize the state with the user-provided window buffer.
858 inflateBack() may then be used multiple times to inflate a complete, raw
859 deflate stream with each call. inflateBackEnd() is then called to free
860 the allocated state.
861
862 A raw deflate stream is one with no zlib or gzip header or trailer.
863 This routine would normally be used in a utility that reads zip or gzip
864 files and writes out uncompressed files. The utility would decode the
865 header and process the trailer on its own, hence this routine expects
866 only the raw deflate stream to decompress. This is different from the
867 normal behavior of inflate(), which expects either a zlib or gzip header and
868 trailer around the deflate stream.
869
870 inflateBack() uses two subroutines supplied by the caller that are then
871 called by inflateBack() for input and output. inflateBack() calls those
872 routines until it reads a complete deflate stream and writes out all of the
873 uncompressed data, or until it encounters an error. The function's
874 parameters and return types are defined above in the in_func and out_func
875 typedefs. inflateBack() will call in(in_desc, &buf) which should return the
876 number of bytes of provided input, and a pointer to that input in buf. If
877 there is no input available, in() must return zero--buf is ignored in that
878 case--and inflateBack() will return a buffer error. inflateBack() will call
879 out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
880 should return zero on success, or non-zero on failure. If out() returns
881 non-zero, inflateBack() will return with an error. Neither in() nor out()
882 are permitted to change the contents of the window provided to
883 inflateBackInit(), which is also the buffer that out() uses to write from.
884 The length written by out() will be at most the window size. Any non-zero
885 amount of input may be provided by in().
886
887 For convenience, inflateBack() can be provided input on the first call by
888 setting strm->next_in and strm->avail_in. If that input is exhausted, then
889 in() will be called. Therefore strm->next_in must be initialized before
890 calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
891 immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
892 must also be initialized, and then if strm->avail_in is not zero, input will
893 initially be taken from strm->next_in[0 .. strm->avail_in - 1].
894
895 The in_desc and out_desc parameters of inflateBack() is passed as the
896 first parameter of in() and out() respectively when they are called. These
897 descriptors can be optionally used to pass any information that the caller-
898 supplied in() and out() functions need to do their job.
899
900 On return, inflateBack() will set strm->next_in and strm->avail_in to
901 pass back any unused input that was provided by the last in() call. The
902 return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
903 if in() or out() returned an error, Z_DATA_ERROR if there was a format
904 error in the deflate stream (in which case strm->msg is set to indicate the
905 nature of the error), or Z_STREAM_ERROR if the stream was not properly
906 initialized. In the case of Z_BUF_ERROR, an input or output error can be
907 distinguished using strm->next_in which will be Z_NULL only if in() returned
908 an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
909 out() returning non-zero. (in() will always be called before out(), so
910 strm->next_in is assured to be defined if out() returns non-zero.) Note
911 that inflateBack() cannot return Z_OK.
912 */
913
914 ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
915 /*
916 All memory allocated by inflateBackInit() is freed.
917
918 inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
919 state was inconsistent.
920 */
921
922 ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
923 /* Return flags indicating compile-time options.
924
925 Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
926 1.0: size of uInt
927 3.2: size of uLong
928 5.4: size of voidpf (pointer)
929 7.6: size of z_off_t
930
931 Compiler, assembler, and debug options:
932 8: DEBUG
933 9: ASMV or ASMINF -- use ASM code
934 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
935 11: 0 (reserved)
936
937 One-time table building (smaller code, but not thread-safe if true):
938 12: BUILDFIXED -- build static block decoding tables when needed
939 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
940 14,15: 0 (reserved)
941
942 Library content (indicates missing functionality):
943 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
944 deflate code when not needed)
945 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
946 and decode gzip streams (to avoid linking crc code)
947 18-19: 0 (reserved)
948
949 Operation variations (changes in library functionality):
950 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
951 21: FASTEST -- deflate algorithm with only one, lowest compression level
952 22,23: 0 (reserved)
953
954 The sprintf variant used by gzprintf (zero is best):
955 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
956 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
957 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
958
959 Remainder:
960 27-31: 0 (reserved)
961 */
962
963
964 /* utility functions */
965
966 /*
967 The following utility functions are implemented on top of the
968 basic stream-oriented functions. To simplify the interface, some
969 default options are assumed (compression level and memory usage,
970 standard memory allocation functions). The source code of these
971 utility functions can easily be modified if you need special options.
972 */
973
974 ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
975 const Bytef *source, uLong sourceLen));
976 /*
977 Compresses the source buffer into the destination buffer. sourceLen is
978 the byte length of the source buffer. Upon entry, destLen is the total
979 size of the destination buffer, which must be at least the value returned
980 by compressBound(sourceLen). Upon exit, destLen is the actual size of the
981 compressed buffer.
982 This function can be used to compress a whole file at once if the
983 input file is mmap'ed.
984 compress returns Z_OK if success, Z_MEM_ERROR if there was not
985 enough memory, Z_BUF_ERROR if there was not enough room in the output
986 buffer.
987 */
988
989 ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
990 const Bytef *source, uLong sourceLen,
991 int level));
992 /*
993 Compresses the source buffer into the destination buffer. The level
994 parameter has the same meaning as in deflateInit. sourceLen is the byte
995 length of the source buffer. Upon entry, destLen is the total size of the
996 destination buffer, which must be at least the value returned by
997 compressBound(sourceLen). Upon exit, destLen is the actual size of the
998 compressed buffer.
999
1000 compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
1001 memory, Z_BUF_ERROR if there was not enough room in the output buffer,
1002 Z_STREAM_ERROR if the level parameter is invalid.
1003 */
1004
1005 ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
1006 /*
1007 compressBound() returns an upper bound on the compressed size after
1008 compress() or compress2() on sourceLen bytes. It would be used before
1009 a compress() or compress2() call to allocate the destination buffer.
1010 */
1011
1012 ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
1013 const Bytef *source, uLong sourceLen));
1014 /*
1015 Decompresses the source buffer into the destination buffer. sourceLen is
1016 the byte length of the source buffer. Upon entry, destLen is the total
1017 size of the destination buffer, which must be large enough to hold the
1018 entire uncompressed data. (The size of the uncompressed data must have
1019 been saved previously by the compressor and transmitted to the decompressor
1020 by some mechanism outside the scope of this compression library.)
1021 Upon exit, destLen is the actual size of the compressed buffer.
1022 This function can be used to decompress a whole file at once if the
1023 input file is mmap'ed.
1024
1025 uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
1026 enough memory, Z_BUF_ERROR if there was not enough room in the output
1027 buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
1028 */
1029
1030
1031 typedef voidp gzFile;
1032
1033 ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
1034 /*
1035 Opens a gzip (.gz) file for reading or writing. The mode parameter
1036 is as in fopen ("rb" or "wb") but can also include a compression level
1037 ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
1038 Huffman only compression as in "wb1h", or 'R' for run-length encoding
1039 as in "wb1R". (See the description of deflateInit2 for more information
1040 about the strategy parameter.)
1041
1042 gzopen can be used to read a file which is not in gzip format; in this
1043 case gzread will directly read from the file without decompression.
1044
1045 gzopen returns NULL if the file could not be opened or if there was
1046 insufficient memory to allocate the (de)compression state; errno
1047 can be checked to distinguish the two cases (if errno is zero, the
1048 zlib error is Z_MEM_ERROR). */
1049
1050 ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
1051 /*
1052 gzdopen() associates a gzFile with the file descriptor fd. File
1053 descriptors are obtained from calls like open, dup, creat, pipe or
1054 fileno (in the file has been previously opened with fopen).
1055 The mode parameter is as in gzopen.
1056 The next call of gzclose on the returned gzFile will also close the
1057 file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
1058 descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
1059 gzdopen returns NULL if there was insufficient memory to allocate
1060 the (de)compression state.
1061 */
1062
1063 ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
1064 /*
1065 Dynamically update the compression level or strategy. See the description
1066 of deflateInit2 for the meaning of these parameters.
1067 gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
1068 opened for writing.
1069 */
1070
1071 ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
1072 /*
1073 Reads the given number of uncompressed bytes from the compressed file.
1074 If the input file was not in gzip format, gzread copies the given number
1075 of bytes into the buffer.
1076 gzread returns the number of uncompressed bytes actually read (0 for
1077 end of file, -1 for error). */
1078
1079 ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
1080 voidpc buf, unsigned len));
1081 /*
1082 Writes the given number of uncompressed bytes into the compressed file.
1083 gzwrite returns the number of uncompressed bytes actually written
1084 (0 in case of error).
1085 */
1086
1087 ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
1088 /*
1089 Converts, formats, and writes the args to the compressed file under
1090 control of the format string, as in fprintf. gzprintf returns the number of
1091 uncompressed bytes actually written (0 in case of error). The number of
1092 uncompressed bytes written is limited to 4095. The caller should assure that
1093 this limit is not exceeded. If it is exceeded, then gzprintf() will return
1094 return an error (0) with nothing written. In this case, there may also be a
1095 buffer overflow with unpredictable consequences, which is possible only if
1096 zlib was compiled with the insecure functions sprintf() or vsprintf()
1097 because the secure snprintf() or vsnprintf() functions were not available.
1098 */
1099
1100 ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
1101 /*
1102 Writes the given null-terminated string to the compressed file, excluding
1103 the terminating null character.
1104 gzputs returns the number of characters written, or -1 in case of error.
1105 */
1106
1107 ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
1108 /*
1109 Reads bytes from the compressed file until len-1 characters are read, or
1110 a newline character is read and transferred to buf, or an end-of-file
1111 condition is encountered. The string is then terminated with a null
1112 character.
1113 gzgets returns buf, or Z_NULL in case of error.
1114 */
1115
1116 ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
1117 /*
1118 Writes c, converted to an unsigned char, into the compressed file.
1119 gzputc returns the value that was written, or -1 in case of error.
1120 */
1121
1122 ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
1123 /*
1124 Reads one byte from the compressed file. gzgetc returns this byte
1125 or -1 in case of end of file or error.
1126 */
1127
1128 ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
1129 /*
1130 Push one character back onto the stream to be read again later.
1131 Only one character of push-back is allowed. gzungetc() returns the
1132 character pushed, or -1 on failure. gzungetc() will fail if a
1133 character has been pushed but not read yet, or if c is -1. The pushed
1134 character will be discarded if the stream is repositioned with gzseek()
1135 or gzrewind().
1136 */
1137
1138 ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
1139 /*
1140 Flushes all pending output into the compressed file. The parameter
1141 flush is as in the deflate() function. The return value is the zlib
1142 error number (see function gzerror below). gzflush returns Z_OK if
1143 the flush parameter is Z_FINISH and all output could be flushed.
1144 gzflush should be called only when strictly necessary because it can
1145 degrade compression.
1146 */
1147
1148 ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
1149 z_off_t offset, int whence));
1150 /*
1151 Sets the starting position for the next gzread or gzwrite on the
1152 given compressed file. The offset represents a number of bytes in the
1153 uncompressed data stream. The whence parameter is defined as in lseek(2);
1154 the value SEEK_END is not supported.
1155 If the file is opened for reading, this function is emulated but can be
1156 extremely slow. If the file is opened for writing, only forward seeks are
1157 supported; gzseek then compresses a sequence of zeroes up to the new
1158 starting position.
1159
1160 gzseek returns the resulting offset location as measured in bytes from
1161 the beginning of the uncompressed stream, or -1 in case of error, in
1162 particular if the file is opened for writing and the new starting position
1163 would be before the current position.
1164 */
1165
1166 ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
1167 /*
1168 Rewinds the given file. This function is supported only for reading.
1169
1170 gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
1171 */
1172
1173 ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
1174 /*
1175 Returns the starting position for the next gzread or gzwrite on the
1176 given compressed file. This position represents a number of bytes in the
1177 uncompressed data stream.
1178
1179 gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
1180 */
1181
1182 ZEXTERN int ZEXPORT gzeof OF((gzFile file));
1183 /*
1184 Returns 1 when EOF has previously been detected reading the given
1185 input stream, otherwise zero.
1186 */
1187
1188 ZEXTERN int ZEXPORT gzclose OF((gzFile file));
1189 /*
1190 Flushes all pending output if necessary, closes the compressed file
1191 and deallocates all the (de)compression state. The return value is the zlib
1192 error number (see function gzerror below).
1193 */
1194
1195 ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
1196 /*
1197 Returns the error message for the last error which occurred on the
1198 given compressed file. errnum is set to zlib error number. If an
1199 error occurred in the file system and not in the compression library,
1200 errnum is set to Z_ERRNO and the application may consult errno
1201 to get the exact error code.
1202 */
1203
1204 ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
1205 /*
1206 Clears the error and end-of-file flags for file. This is analogous to the
1207 clearerr() function in stdio. This is useful for continuing to read a gzip
1208 file that is being written concurrently.
1209 */
1210
1211 /* checksum functions */
1212
1213 /*
1214 These functions are not related to compression but are exported
1215 anyway because they might be useful in applications using the
1216 compression library.
1217 */
1218
1219 ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
1220 /*
1221 Update a running Adler-32 checksum with the bytes buf[0..len-1] and
1222 return the updated checksum. If buf is NULL, this function returns
1223 the required initial value for the checksum.
1224 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
1225 much faster. Usage example:
1226
1227 uLong adler = adler32(0L, Z_NULL, 0);
1228
1229 while (read_buffer(buffer, length) != EOF) {
1230 adler = adler32(adler, buffer, length);
1231 }
1232 if (adler != original_adler) error();
1233 */
1234
1235 ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
1236 z_off_t len2));
1237 /*
1238 Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
1239 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
1240 each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
1241 seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
1242 */
1243
1244 ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
1245 /*
1246 Update a running CRC-32 with the bytes buf[0..len-1] and return the
1247 updated CRC-32. If buf is NULL, this function returns the required initial
1248 value for the for the crc. Pre- and post-conditioning (one's complement) is
1249 performed within this function so it shouldn't be done by the application.
1250 Usage example:
1251
1252 uLong crc = crc32(0L, Z_NULL, 0);
1253
1254 while (read_buffer(buffer, length) != EOF) {
1255 crc = crc32(crc, buffer, length);
1256 }
1257 if (crc != original_crc) error();
1258 */
1259
1260 ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
1261
1262 /*
1263 Combine two CRC-32 check values into one. For two sequences of bytes,
1264 seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
1265 calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
1266 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
1267 len2.
1268 */
1269
1270
1271 /* various hacks, don't look :) */
1272
1273 /* deflateInit and inflateInit are macros to allow checking the zlib version
1274 * and the compiler's view of z_stream:
1275 */
1276 ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
1277 const char *version, int stream_size));
1278 ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
1279 const char *version, int stream_size));
1280 ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
1281 int windowBits, int memLevel,
1282 int strategy, const char *version,
1283 int stream_size));
1284 ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
1285 const char *version, int stream_size));
1286 ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
1287 unsigned char FAR *window,
1288 const char *version,
1289 int stream_size));
1290 #define deflateInit(strm, level) \
1291 deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
1292 #define inflateInit(strm) \
1293 inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
1294 #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
1295 deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
1296 (strategy), ZLIB_VERSION, sizeof(z_stream))
1297 #define inflateInit2(strm, windowBits) \
1298 inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
1299 #define inflateBackInit(strm, windowBits, window) \
1300 inflateBackInit_((strm), (windowBits), (window), \
1301 ZLIB_VERSION, sizeof(z_stream))
1302
1303
1304 #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
1305 struct internal_state {int dummy;}; /* hack for buggy compilers */
1306 #endif
1307
1308 ZEXTERN const char * ZEXPORT zError OF((int));
1309 ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
1310 ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
1311
1312 #ifdef __cplusplus
1313 }
1314 #endif
1315
1316 #endif /* ZLIB_H */
0 /* zutil.c -- target dependent utility functions for the compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* @(#) $Id$ */
6
7 #include "zutil.h"
8
9 #ifndef NO_DUMMY_DECL
10 struct internal_state {int dummy;}; /* for buggy compilers */
11 #endif
12
13 const char * const z_errmsg[10] = {
14 "need dictionary", /* Z_NEED_DICT 2 */
15 "stream end", /* Z_STREAM_END 1 */
16 "", /* Z_OK 0 */
17 "file error", /* Z_ERRNO (-1) */
18 "stream error", /* Z_STREAM_ERROR (-2) */
19 "data error", /* Z_DATA_ERROR (-3) */
20 "insufficient memory", /* Z_MEM_ERROR (-4) */
21 "buffer error", /* Z_BUF_ERROR (-5) */
22 "incompatible version",/* Z_VERSION_ERROR (-6) */
23 ""};
24
25
26 const char * ZEXPORT zlibVersion()
27 {
28 return ZLIB_VERSION;
29 }
30
31 uLong ZEXPORT zlibCompileFlags()
32 {
33 uLong flags;
34
35 flags = 0;
36 switch (sizeof(uInt)) {
37 case 2: break;
38 case 4: flags += 1; break;
39 case 8: flags += 2; break;
40 default: flags += 3;
41 }
42 switch (sizeof(uLong)) {
43 case 2: break;
44 case 4: flags += 1 << 2; break;
45 case 8: flags += 2 << 2; break;
46 default: flags += 3 << 2;
47 }
48 switch (sizeof(voidpf)) {
49 case 2: break;
50 case 4: flags += 1 << 4; break;
51 case 8: flags += 2 << 4; break;
52 default: flags += 3 << 4;
53 }
54 switch (sizeof(z_off_t)) {
55 case 2: break;
56 case 4: flags += 1 << 6; break;
57 case 8: flags += 2 << 6; break;
58 default: flags += 3 << 6;
59 }
60 #ifdef DEBUG
61 flags += 1 << 8;
62 #endif
63 #if defined(ASMV) || defined(ASMINF)
64 flags += 1 << 9;
65 #endif
66 #ifdef ZLIB_WINAPI
67 flags += 1 << 10;
68 #endif
69 #ifdef BUILDFIXED
70 flags += 1 << 12;
71 #endif
72 #ifdef DYNAMIC_CRC_TABLE
73 flags += 1 << 13;
74 #endif
75 #ifdef NO_GZCOMPRESS
76 flags += 1 << 16;
77 #endif
78 #ifdef NO_GZIP
79 flags += 1 << 17;
80 #endif
81 #ifdef PKZIP_BUG_WORKAROUND
82 flags += 1 << 20;
83 #endif
84 #ifdef FASTEST
85 flags += 1 << 21;
86 #endif
87 #ifdef STDC
88 # ifdef NO_vsnprintf
89 flags += 1 << 25;
90 # ifdef HAS_vsprintf_void
91 flags += 1 << 26;
92 # endif
93 # else
94 # ifdef HAS_vsnprintf_void
95 flags += 1 << 26;
96 # endif
97 # endif
98 #else
99 flags += 1 << 24;
100 # ifdef NO_snprintf
101 flags += 1 << 25;
102 # ifdef HAS_sprintf_void
103 flags += 1 << 26;
104 # endif
105 # else
106 # ifdef HAS_snprintf_void
107 flags += 1 << 26;
108 # endif
109 # endif
110 #endif
111 return flags;
112 }
113
114 #ifdef DEBUG
115
116 # ifndef verbose
117 # define verbose 0
118 # endif
119 int z_verbose = verbose;
120
121 void z_error (m)
122 char *m;
123 {
124 fprintf(stderr, "%s\n", m);
125 exit(1);
126 }
127 #endif
128
129 /* exported to allow conversion of error code to string for compress() and
130 * uncompress()
131 */
132 const char * ZEXPORT zError(err)
133 int err;
134 {
135 return ERR_MSG(err);
136 }
137
138 #if defined(_WIN32_WCE)
139 /* The Microsoft C Run-Time Library for Windows CE doesn't have
140 * errno. We define it as a global variable to simplify porting.
141 * Its value is always 0 and should not be used.
142 */
143 int errno = 0;
144 #endif
145
146 #ifndef HAVE_MEMCPY
147
148 void zmemcpy(dest, source, len)
149 Bytef* dest;
150 const Bytef* source;
151 uInt len;
152 {
153 if (len == 0) return;
154 do {
155 *dest++ = *source++; /* ??? to be unrolled */
156 } while (--len != 0);
157 }
158
159 int zmemcmp(s1, s2, len)
160 const Bytef* s1;
161 const Bytef* s2;
162 uInt len;
163 {
164 uInt j;
165
166 for (j = 0; j < len; j++) {
167 if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
168 }
169 return 0;
170 }
171
172 void zmemzero(dest, len)
173 Bytef* dest;
174 uInt len;
175 {
176 if (len == 0) return;
177 do {
178 *dest++ = 0; /* ??? to be unrolled */
179 } while (--len != 0);
180 }
181 #endif
182
183
184 #ifdef SYS16BIT
185
186 #ifdef __TURBOC__
187 /* Turbo C in 16-bit mode */
188
189 # define MY_ZCALLOC
190
191 /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
192 * and farmalloc(64K) returns a pointer with an offset of 8, so we
193 * must fix the pointer. Warning: the pointer must be put back to its
194 * original form in order to free it, use zcfree().
195 */
196
197 #define MAX_PTR 10
198 /* 10*64K = 640K */
199
200 local int next_ptr = 0;
201
202 typedef struct ptr_table_s {
203 voidpf org_ptr;
204 voidpf new_ptr;
205 } ptr_table;
206
207 local ptr_table table[MAX_PTR];
208 /* This table is used to remember the original form of pointers
209 * to large buffers (64K). Such pointers are normalized with a zero offset.
210 * Since MSDOS is not a preemptive multitasking OS, this table is not
211 * protected from concurrent access. This hack doesn't work anyway on
212 * a protected system like OS/2. Use Microsoft C instead.
213 */
214
215 voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
216 {
217 voidpf buf = opaque; /* just to make some compilers happy */
218 ulg bsize = (ulg)items*size;
219
220 /* If we allocate less than 65520 bytes, we assume that farmalloc
221 * will return a usable pointer which doesn't have to be normalized.
222 */
223 if (bsize < 65520L) {
224 buf = farmalloc(bsize);
225 if (*(ush*)&buf != 0) return buf;
226 } else {
227 buf = farmalloc(bsize + 16L);
228 }
229 if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
230 table[next_ptr].org_ptr = buf;
231
232 /* Normalize the pointer to seg:0 */
233 *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
234 *(ush*)&buf = 0;
235 table[next_ptr++].new_ptr = buf;
236 return buf;
237 }
238
239 void zcfree (voidpf opaque, voidpf ptr)
240 {
241 int n;
242 if (*(ush*)&ptr != 0) { /* object < 64K */
243 farfree(ptr);
244 return;
245 }
246 /* Find the original pointer */
247 for (n = 0; n < next_ptr; n++) {
248 if (ptr != table[n].new_ptr) continue;
249
250 farfree(table[n].org_ptr);
251 while (++n < next_ptr) {
252 table[n-1] = table[n];
253 }
254 next_ptr--;
255 return;
256 }
257 ptr = opaque; /* just to make some compilers happy */
258 Assert(0, "zcfree: ptr not found");
259 }
260
261 #endif /* __TURBOC__ */
262
263
264 #ifdef M_I86
265 /* Microsoft C in 16-bit mode */
266
267 # define MY_ZCALLOC
268
269 #if (!defined(_MSC_VER) || (_MSC_VER <= 600))
270 # define _halloc halloc
271 # define _hfree hfree
272 #endif
273
274 voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
275 {
276 if (opaque) opaque = 0; /* to make compiler happy */
277 return _halloc((long)items, size);
278 }
279
280 void zcfree (voidpf opaque, voidpf ptr)
281 {
282 if (opaque) opaque = 0; /* to make compiler happy */
283 _hfree(ptr);
284 }
285
286 #endif /* M_I86 */
287
288 #endif /* SYS16BIT */
289
290
291 #ifndef MY_ZCALLOC /* Any system without a special alloc function */
292
293 #ifndef STDC
294 extern voidp malloc OF((uInt size));
295 extern voidp calloc OF((uInt items, uInt size));
296 extern void free OF((voidpf ptr));
297 #endif
298
299 voidpf zcalloc (opaque, items, size)
300 voidpf opaque;
301 unsigned items;
302 unsigned size;
303 {
304 if (opaque) items += size - size; /* make compiler happy */
305 return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
306 (voidpf)calloc(items, size);
307 }
308
309 void zcfree (opaque, ptr)
310 voidpf opaque;
311 voidpf ptr;
312 {
313 free(ptr);
314 if (opaque) return; /* make compiler happy */
315 }
316
317 #endif /* MY_ZCALLOC */
0 /* zutil.h -- internal interface and configuration of the compression library
1 * Copyright (C) 1995-2004 Jean-loup Gailly.
2 * For conditions of distribution and use, see copyright notice in zlib.h
3 */
4
5 /* WARNING: this file should *not* be used by applications. It is
6 part of the implementation of the compression library and is
7 subject to change. Applications should only use zlib.h.
8 */
9
10 /* @(#) $Id$ */
11
12 #ifndef ZUTIL_H
13 #define ZUTIL_H
14
15 #define ZLIB_INTERNAL
16 #include "zlib.h"
17
18 #ifdef STDC
19 # include <stddef.h>
20 # include <string.h>
21 # include <stdlib.h>
22 #endif
23 #ifdef NO_ERRNO_H
24 # ifdef _WIN32_WCE
25 /* The Microsoft C Run-Time Library for Windows CE doesn't have
26 * errno. We define it as a global variable to simplify porting.
27 * Its value is always 0 and should not be used. We rename it to
28 * avoid conflict with other libraries that use the same workaround.
29 */
30 # define errno z_errno
31 # endif
32 extern int errno;
33 #else
34 # include <errno.h>
35 #endif
36
37 #ifndef local
38 # define local static
39 #endif
40 /* compile with -Dlocal if your debugger can't find static symbols */
41
42 typedef unsigned char uch;
43 typedef uch FAR uchf;
44 typedef unsigned short ush;
45 typedef ush FAR ushf;
46 typedef unsigned long ulg;
47
48 extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
49 /* (size given to avoid silly warnings with Visual C++) */
50
51 #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
52
53 #define ERR_RETURN(strm,err) \
54 return (strm->msg = (char*)ERR_MSG(err), (err))
55 /* To be used only when the state is known to be valid */
56
57 /* common constants */
58
59 #ifndef DEF_WBITS
60 # define DEF_WBITS MAX_WBITS
61 #endif
62 /* default windowBits for decompression. MAX_WBITS is for compression only */
63
64 #if MAX_MEM_LEVEL >= 8
65 # define DEF_MEM_LEVEL 8
66 #else
67 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
68 #endif
69 /* default memLevel */
70
71 #define STORED_BLOCK 0
72 #define STATIC_TREES 1
73 #define DYN_TREES 2
74 /* The three kinds of block type */
75
76 #define MIN_MATCH 3
77 #define MAX_MATCH 258
78 /* The minimum and maximum match lengths */
79
80 #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
81
82 /* target dependencies */
83
84 #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
85 # define OS_CODE 0x00
86 # if defined(__TURBOC__) || defined(__BORLANDC__)
87 # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
88 /* Allow compilation with ANSI keywords only enabled */
89 void _Cdecl farfree( void *block );
90 void *_Cdecl farmalloc( unsigned long nbytes );
91 # else
92 # include <alloc.h>
93 # endif
94 # else /* MSC or DJGPP */
95 # include <malloc.h>
96 # endif
97 #endif
98
99 #ifdef AMIGA
100 # define OS_CODE 0x01
101 #endif
102
103 #if defined(VAXC) || defined(VMS)
104 # define OS_CODE 0x02
105 # define F_OPEN(name, mode) \
106 fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
107 #endif
108
109 #if defined(ATARI) || defined(atarist)
110 # define OS_CODE 0x05
111 #endif
112
113 #ifdef OS2
114 # define OS_CODE 0x06
115 #endif
116
117 #if defined(MACOS) || defined(TARGET_OS_MAC)
118 # define OS_CODE 0x07
119 # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
120 # include <unix.h> /* for fdopen */
121 # else
122 # ifndef fdopen
123 # define fdopen(fd,mode) NULL /* No fdopen() */
124 # endif
125 # endif
126 #endif
127
128 #ifdef TOPS20
129 # define OS_CODE 0x0a
130 #endif
131
132 #ifdef WIN32
133 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
134 # define OS_CODE 0x0b
135 # endif
136 #endif
137
138 #ifdef __50SERIES /* Prime/PRIMOS */
139 # define OS_CODE 0x0f
140 #endif
141
142 #if defined(_BEOS_) || defined(RISCOS)
143 # define fdopen(fd,mode) NULL /* No fdopen() */
144 #endif
145
146 #if (defined(_MSC_VER) && (_MSC_VER > 600))
147 # if defined(_WIN32_WCE)
148 # define fdopen(fd,mode) NULL /* No fdopen() */
149 # ifndef _PTRDIFF_T_DEFINED
150 typedef int ptrdiff_t;
151 # define _PTRDIFF_T_DEFINED
152 # endif
153 # else
154 # define fdopen(fd,type) _fdopen(fd,type)
155 # endif
156 #endif
157
158 /* common defaults */
159
160 #ifndef OS_CODE
161 # define OS_CODE 0x03 /* assume Unix */
162 #endif
163
164 #ifndef F_OPEN
165 # define F_OPEN(name, mode) fopen((name), (mode))
166 #endif
167
168 /* functions */
169
170 #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
171 # ifndef HAVE_VSNPRINTF
172 # define HAVE_VSNPRINTF
173 # endif
174 #endif
175 #if defined(__CYGWIN__)
176 # ifndef HAVE_VSNPRINTF
177 # define HAVE_VSNPRINTF
178 # endif
179 #endif
180 #ifndef HAVE_VSNPRINTF
181 # ifdef MSDOS
182 /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
183 but for now we just assume it doesn't. */
184 # define NO_vsnprintf
185 # endif
186 # ifdef __TURBOC__
187 # define NO_vsnprintf
188 # endif
189 # ifdef WIN32
190 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
191 # if !defined(vsnprintf) && !defined(NO_vsnprintf)
192 # define vsnprintf _vsnprintf
193 # endif
194 # endif
195 # ifdef __SASC
196 # define NO_vsnprintf
197 # endif
198 #endif
199 #ifdef VMS
200 # define NO_vsnprintf
201 #endif
202
203 #if defined(pyr)
204 # define NO_MEMCPY
205 #endif
206 #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
207 /* Use our own functions for small and medium model with MSC <= 5.0.
208 * You may have to use the same strategy for Borland C (untested).
209 * The __SC__ check is for Symantec.
210 */
211 # define NO_MEMCPY
212 #endif
213 #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
214 # define HAVE_MEMCPY
215 #endif
216 #ifdef HAVE_MEMCPY
217 # ifdef SMALL_MEDIUM /* MSDOS small or medium model */
218 # define zmemcpy _fmemcpy
219 # define zmemcmp _fmemcmp
220 # define zmemzero(dest, len) _fmemset(dest, 0, len)
221 # else
222 # define zmemcpy memcpy
223 # define zmemcmp memcmp
224 # define zmemzero(dest, len) memset(dest, 0, len)
225 # endif
226 #else
227 extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
228 extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
229 extern void zmemzero OF((Bytef* dest, uInt len));
230 #endif
231
232 /* Diagnostic functions */
233 #ifdef DEBUG
234 # include <stdio.h>
235 extern int z_verbose;
236 extern void z_error OF((char *m));
237 # define Assert(cond,msg) {if(!(cond)) z_error(msg);}
238 # define Trace(x) {if (z_verbose>=0) fprintf x ;}
239 # define Tracev(x) {if (z_verbose>0) fprintf x ;}
240 # define Tracevv(x) {if (z_verbose>1) fprintf x ;}
241 # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
242 # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
243 #else
244 # define Assert(cond,msg)
245 # define Trace(x)
246 # define Tracev(x)
247 # define Tracevv(x)
248 # define Tracec(c,x)
249 # define Tracecv(c,x)
250 #endif
251
252
253 voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
254 void zcfree OF((voidpf opaque, voidpf ptr));
255
256 #define ZALLOC(strm, items, size) \
257 (*((strm)->zalloc))((strm)->opaque, (items), (size))
258 #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
259 #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
260
261 #endif /* ZUTIL_H */