Compare commits

...

6 Commits

Author SHA1 Message Date
Mark Adler
0484693e17 zlib 1.2.2.2 2011-09-09 23:24:33 -07:00
Mark Adler
9811b53dd9 zlib 1.2.2.1 2011-09-09 23:24:24 -07:00
Mark Adler
79fbcdc939 zlib 1.2.2 2011-09-09 23:24:02 -07:00
Mark Adler
7a6955760b zlib 1.2.1.2 2011-09-09 23:23:45 -07:00
Mark Adler
f0e76a6634 zlib 1.2.1.1 2011-09-09 23:23:38 -07:00
Mark Adler
7a33a861d1 zlib 1.2.1 2011-09-09 23:23:27 -07:00
107 changed files with 7886 additions and 1002 deletions

View File

@@ -1,6 +1,97 @@
ChangeLog file for zlib ChangeLog file for zlib
Changes in 1.2.2.2 (30 December 2004)
- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
avoid implicit memcpy calls (portability for no-library compilation)
- Increase sprintf() buffer size in gzdopen() to allow for large numbers
- Add INFLATE_STRICT to check distances against zlib header
- Improve WinCE errno handling and comments [Chang]
- Remove comment about no gzip header processing in FAQ
- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
- Add updated make_vms.com [Coghlan], update README
- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
- Add FAQ entry and comments in deflate.c on uninitialized memory access
- Add Solaris 9 make options in configure [Gilbert]
- Allow strerror() usage in gzio.c for STDC
- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
- Use z_off_t for adler32_combine() and crc32_combine() lengths
- Make adler32() much faster for small len
- Use OS_CODE in deflate() default gzip header
Changes in 1.2.2.1 (31 October 2004)
- Allow inflateSetDictionary() call for raw inflate
- Fix inflate header crc check bug for file names and comments
- Add deflateSetHeader() and gz_header structure for custom gzip headers
- Add inflateGetheader() to retrieve gzip headers
- Add crc32_combine() and adler32_combine() functions
- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
- Use zstreamp consistently in zlib.h (inflate_back functions)
- Remove GUNZIP condition from definition of inflate_mode in inflate.h
and in contrib/inflate86/inffast.S [Truta, Anderson]
- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
- Update projects/README.projects and projects/visualc6 [Truta]
- Update win32/DLL_FAQ.txt [Truta]
- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
- Use a new algorithm for setting strm->data_type in trees.c [Truta]
- Do not define an exit() prototype in zutil.c unless DEBUG defined
- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
- Fix Darwin build version identification [Peterson]
Changes in 1.2.2 (3 October 2004)
- Update zlib.h comments on gzip in-memory processing
- Set adler to 1 in inflateReset() to support Java test suite [Walles]
- Add contrib/dotzlib [Ravn]
- Update win32/DLL_FAQ.txt [Truta]
- Update contrib/minizip [Vollant]
- Move contrib/visual-basic.txt to old/ [Truta]
- Fix assembler builds in projects/visualc6/ [Truta]
Changes in 1.2.1.2 (9 September 2004)
- Update INDEX file
- Fix trees.c to update strm->data_type (no one ever noticed!)
- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
- Add limited multitasking protection to DYNAMIC_CRC_TABLE
- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
- Don't declare strerror() under VMS [Mozilla]
- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
- Update contrib/ada [Anisimkov]
- Update contrib/minizip [Vollant]
- Fix configure to not hardcode directories for Darwin [Peterson]
- Fix gzio.c to not return error on empty files [Brown]
- Fix indentation; update version in contrib/delphi/ZLib.pas and
contrib/pascal/zlibpas.pas [Truta]
- Update mkasm.bat in contrib/masmx86 [Truta]
- Update contrib/untgz [Truta]
- Add projects/README.projects [Truta]
- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
- Update win32/DLL_FAQ.txt [Truta]
- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
- Remove an unnecessary assignment to curr in inftrees.c [Truta]
- Add OS/2 to exe builds in configure [Poltorak]
- Remove err dummy parameter in zlib.h [Kientzle]
Changes in 1.2.1.1 (9 January 2004)
- Update email address in README
- Several FAQ updates
- Fix a big fat bug in inftrees.c that prevented decoding valid
dynamic blocks with only literals and no distance codes --
Thanks to "Hot Emu" for the bug report and sample file
- Add a note to puff.c on no distance codes case.
Changes in 1.2.1 (17 November 2003)
- Remove a tab in contrib/gzappend/gzappend.c
- Update some interfaces in contrib for new zlib functions
- Update zlib version number in some contrib entries
- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
- Support shared libraries on Hurd and KFreeBSD [Brown]
- Fix error in NO_DIVIDE option of adler32.c
Changes in 1.2.0.8 (4 November 2003) Changes in 1.2.0.8 (4 November 2003)
- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas - Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
- Add experimental NO_DIVIDE #define in adler32.c - Add experimental NO_DIVIDE #define in adler32.c
@@ -18,7 +109,7 @@ Changes in 1.2.0.8 (4 November 2003)
- Add -p to mkdir's in Makefile.in [vda] - Add -p to mkdir's in Makefile.in [vda]
- Fix configure to properly detect presence or lack of printf functions - Fix configure to properly detect presence or lack of printf functions
- Add AS400 support [Monnerat] - Add AS400 support [Monnerat]
- Added a little Cygwin support [Wilson] - Add a little Cygwin support [Wilson]
Changes in 1.2.0.7 (21 September 2003) Changes in 1.2.0.7 (21 September 2003)
- Correct some debug formats in contrib/infback9 - Correct some debug formats in contrib/infback9

104
FAQ
View File

@@ -21,18 +21,18 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
3. Where can I get a Visual Basic interface to zlib? 3. Where can I get a Visual Basic interface to zlib?
See See
* http://www.winimage.com/zLibDll/
* http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
* contrib/visual-basic.txt in the zlib distribution * contrib/visual-basic.txt in the zlib distribution
* win32/DLL_FAQ.txt in the zlib distribution
4. compress() returns Z_BUF_ERROR 4. compress() returns Z_BUF_ERROR.
Make sure that before the call of compress, the length of the compressed Make sure that before the call of compress, the length of the compressed
buffer is equal to the total size of the compressed buffer and not buffer is equal to the total size of the compressed buffer and not
zero. For Visual Basic, check that this parameter is passed by reference zero. For Visual Basic, check that this parameter is passed by reference
("as any"), not by value ("as long"). ("as any"), not by value ("as long").
5. deflate() or inflate() returns Z_BUF_ERROR 5. deflate() or inflate() returns Z_BUF_ERROR.
Before making the call, make sure that avail_in and avail_out are not Before making the call, make sure that avail_in and avail_out are not
zero. When setting the parameter flush equal to Z_FINISH, also make sure zero. When setting the parameter flush equal to Z_FINISH, also make sure
@@ -47,8 +47,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
It's in zlib.h for the moment, and Francis S. Lin has converted it to a It's in zlib.h for the moment, and Francis S. Lin has converted it to a
web page zlib.html. Volunteers to transform this to Unix-style man pages, web page zlib.html. Volunteers to transform this to Unix-style man pages,
please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage please contact us (zlib@gzip.org). Examples of zlib usage are in the files
are in the files example.c and minigzip.c. example.c and minigzip.c.
7. Why don't you use GNU autoconf or libtool or ...? 7. Why don't you use GNU autoconf or libtool or ...?
@@ -77,7 +77,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
11. Can zlib handle .zip archives? 11. Can zlib handle .zip archives?
See the directory contrib/minizip in the zlib distribution. Not by itself, no. See the directory contrib/minizip in the zlib
distribution.
12. Can zlib handle .Z files? 12. Can zlib handle .Z files?
@@ -92,6 +93,8 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
14. How do I install a shared zlib library on Unix? 14. How do I install a shared zlib library on Unix?
After the above, then:
make install make install
However, many flavors of Unix come with a shared zlib already installed. However, many flavors of Unix come with a shared zlib already installed.
@@ -99,12 +102,31 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
trying to install it, you may want to check if it's already there! If you trying to install it, you may want to check if it's already there! If you
can #include <zlib.h>, it's there. The -lz option will probably link to it. can #include <zlib.h>, it's there. The -lz option will probably link to it.
15. I have a question about OttoPDF 15. I have a question about OttoPDF.
We are not the authors of OttoPDF. The real author is on the OttoPDF web We are not the authors of OttoPDF. The real author is on the OttoPDF web
site Joel Hainley jhainley@myndkryme.com. site: Joel Hainley, jhainley@myndkryme.com.
16. Why does gzip give an error on a file I make with compress/deflate? 16. Can zlib decode Flate data in an Adobe PDF file?
Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
17. Why am I getting this "register_frame_info not found" error on Solaris?
After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
generates an error such as:
ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
symbol __register_frame_info: referenced symbol not found
The symbol __register_frame_info is not part of zlib, it is generated by
the C compiler (cc or gcc). You must recompile applications using zlib
which have this problem. This problem is specific to Solaris. See
http://www.sunfreeware.com for Solaris versions of zlib and applications
using zlib.
18. Why does gzip give an error on a file I make with compress/deflate?
The compress and deflate functions produce data in the zlib format, which The compress and deflate functions produce data in the zlib format, which
is different and incompatible with the gzip format. The gz* functions in is different and incompatible with the gzip format. The gz* functions in
@@ -112,7 +134,7 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
formats use the same compressed data format internally, but have different formats use the same compressed data format internally, but have different
headers and trailers around the compressed data. headers and trailers around the compressed data.
17. Ok, so why are there two different formats? 19. Ok, so why are there two different formats?
The gzip format was designed to retain the directory information about The gzip format was designed to retain the directory information about
a single file, such as the name and last modification date. The zlib a single file, such as the name and last modification date. The zlib
@@ -120,20 +142,13 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
channel applications, and has a much more compact header and trailer and channel applications, and has a much more compact header and trailer and
uses a faster integrity check than gzip. uses a faster integrity check than gzip.
18. Well that's nice, but how do I make a gzip file in memory? 20. Well that's nice, but how do I make a gzip file in memory?
You can request that deflate write the gzip format instead of the zlib You can request that deflate write the gzip format instead of the zlib
format using deflateInit2(). You can also request that inflate decode format using deflateInit2(). You can also request that inflate decode
the gzip format using inflateInit2(). Read zlib.h for more details. the gzip format using inflateInit2(). Read zlib.h for more details.
Note that you cannot specify special gzip header contents (e.g. a file 21. Is zlib thread-safe?
name or modification date), nor will inflate tell you what was in the
gzip header. If you need to customize the header or see what's in it,
you can use the raw deflate and inflate operations and the crc32()
function and roll your own gzip encoding and decoding. Read the gzip
RFC 1952 for details of the header and trailer format.
19. Is zlib thread-safe?
Yes. However any library routines that zlib uses and any application- Yes. However any library routines that zlib uses and any application-
provided memory allocation routines must also be thread-safe. zlib's gz* provided memory allocation routines must also be thread-safe. zlib's gz*
@@ -144,15 +159,15 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Of course, you should only operate on any given zlib or gzip stream from a Of course, you should only operate on any given zlib or gzip stream from a
single thread at a time. single thread at a time.
20. Can I use zlib in my commercial application? 22. Can I use zlib in my commercial application?
Yes. Please read the license in zlib.h. Yes. Please read the license in zlib.h.
21. Is zlib under the GNU license? 23. Is zlib under the GNU license?
No. Please read the license in zlib.h. No. Please read the license in zlib.h.
22. The license says that altered source versions must be "plainly marked". So 24. The license says that altered source versions must be "plainly marked". So
what exactly do I need to do to meet that requirement? what exactly do I need to do to meet that requirement?
You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
@@ -175,24 +190,24 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
in zlib.h as you would for a full source distribution. in zlib.h as you would for a full source distribution.
23. Will zlib work on a big-endian or little-endian architecture, and can I 25. Will zlib work on a big-endian or little-endian architecture, and can I
exchange compressed data between them? exchange compressed data between them?
Yes and yes. Yes and yes.
24. Will zlib work on a 64-bit machine? 26. Will zlib work on a 64-bit machine?
It should. It has been tested on 64-bit machines, and has no dependence It should. It has been tested on 64-bit machines, and has no dependence
on any data types being limited to 32-bits in length. If you have any on any data types being limited to 32-bits in length. If you have any
difficulties, please provide a complete problem report to zlib@gzip.org difficulties, please provide a complete problem report to zlib@gzip.org
25. Will zlib decompress data from the PKWare Data Compression Library? 27. Will zlib decompress data from the PKWare Data Compression Library?
No. The PKWare DCL uses a completely different compressed data format No. The PKWare DCL uses a completely different compressed data format
than does PKZIP and zlib. However, you can look in zlib's contrib/blast than does PKZIP and zlib. However, you can look in zlib's contrib/blast
directory for a possible solution to your problem. directory for a possible solution to your problem.
26. Can I access data randomly in a compressed stream? 28. Can I access data randomly in a compressed stream?
No, not without some preparation. If when compressing you periodically No, not without some preparation. If when compressing you periodically
use Z_FULL_FLUSH, carefully write all the pending data at those points, use Z_FULL_FLUSH, carefully write all the pending data at those points,
@@ -200,27 +215,27 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
at those points. You have to be careful to not use Z_FULL_FLUSH too at those points. You have to be careful to not use Z_FULL_FLUSH too
often, since it can significantly degrade compression. often, since it can significantly degrade compression.
27. Does zlib work on MVS, OS/390, CICS, etc.? 29. Does zlib work on MVS, OS/390, CICS, etc.?
We don't know for sure. We have heard occasional reports of success on We don't know for sure. We have heard occasional reports of success on
these systems. If you do use it on one of these, please provide us with these systems. If you do use it on one of these, please provide us with
a report, instructions, and patches that we can reference when we get a report, instructions, and patches that we can reference when we get
these questions. Thanks. these questions. Thanks.
28. Is there some simpler, easier to read version of inflate I can look at 30. Is there some simpler, easier to read version of inflate I can look at
to understand the deflate format? to understand the deflate format?
First off, you should read RFC 1951. Second, yes. Look in zlib's First off, you should read RFC 1951. Second, yes. Look in zlib's
contrib/puff directory. contrib/puff directory.
29. Does zlib infringe on any patents? 31. Does zlib infringe on any patents?
As far as we know, no. In fact, that was originally the whole point behind As far as we know, no. In fact, that was originally the whole point behind
zlib. Look here for some more information: zlib. Look here for some more information:
http://www.gzip.org/#faq11 http://www.gzip.org/#faq11
30. Can zlib work with greater than 4 GB of data? 32. Can zlib work with greater than 4 GB of data?
Yes. inflate() and deflate() will process any amount of data correctly. Yes. inflate() and deflate() will process any amount of data correctly.
Each call of inflate() or deflate() is limited to input and output chunks Each call of inflate() or deflate() is limited to input and output chunks
@@ -238,7 +253,7 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
only if the compiler's "long" type is 32 bits. If the compiler's "long" only if the compiler's "long" type is 32 bits. If the compiler's "long"
type is 64 bits, then the limit is 16 exabytes. type is 64 bits, then the limit is 16 exabytes.
31. Does zlib have any security vulnerabilities? 33. Does zlib have any security vulnerabilities?
The only one that we are aware of is potentially in gzprintf(). If zlib The only one that we are aware of is potentially in gzprintf(). If zlib
is compiled to use sprintf() or vsprintf(), then there is no protection is compiled to use sprintf() or vsprintf(), then there is no protection
@@ -258,35 +273,44 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Note that you should be using the most recent version of zlib. Versions Note that you should be using the most recent version of zlib. Versions
1.1.3 and before were subject to a double-free vulnerability. 1.1.3 and before were subject to a double-free vulnerability.
32. Is there a Java version of zlib? 34. Is there a Java version of zlib?
Probably what you want is to use zlib in Java. zlib is already included Probably what you want is to use zlib in Java. zlib is already included
as part of the Java SDK in the java.util.zip package. If you really want as part of the Java SDK in the java.util.zip package. If you really want
a version of zlib written in the Java language, look on the zlib home a version of zlib written in the Java language, look on the zlib home
page for links: http://www.zlib.org/ page for links: http://www.zlib.org/
33. I get this or that compiler or source-code scanner warning when I crank it 35. I get this or that compiler or source-code scanner warning when I crank it
up to maximally-pendantic. Can't you guys write proper code? up to maximally-pedantic. Can't you guys write proper code?
Many years ago, we gave up attempting to avoid warnings on every compiler Many years ago, we gave up attempting to avoid warnings on every compiler
in the universe. It just got to be a waste of time, and some compilers in the universe. It just got to be a waste of time, and some compilers
were downright silly. So now, we simply make sure that the code always were downright silly. So now, we simply make sure that the code always
works. works.
34. Will zlib read the (insert any ancient or arcane format here) compressed 36. Valgrind (or some similar memory access checker) says that deflate is
performing a conditional jump that depends on an uninitialized value.
Isn't that a bug?
No. That is intentional for performance reasons, and the output of
deflate is not affected. This only started showing up recently since
zlib 1.2.x uses malloc() by default for allocations, whereas earlier
versions used calloc(), which zeros out the allocated memory.
37. Will zlib read the (insert any ancient or arcane format here) compressed
data format? data format?
Probably not. Look in the comp.compression FAQ for pointers to various Probably not. Look in the comp.compression FAQ for pointers to various
formats and associated software. formats and associated software.
35. How can I encrypt/decrypt zip files with zlib? 38. How can I encrypt/decrypt zip files with zlib?
zlib doesn't support encryption. The original PKZIP encryption is very weak zlib doesn't support encryption. The original PKZIP encryption is very weak
and can be broken with freely available programs. To get strong encryption, and can be broken with freely available programs. To get strong encryption,
use gpg ( http://www.gnupg.org/ ) which already includes zlib compression. use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
For PKZIP compatible "encryption", look at http://www.info-zip.org/ For PKZIP compatible "encryption", look at http://www.info-zip.org/
36. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? 39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
"gzip" is the gzip format, and "deflate" is the zlib format. They should "gzip" is the gzip format, and "deflate" is the zlib format. They should
probably have called the second one "zlib" instead to avoid confusion probably have called the second one "zlib" instead to avoid confusion
@@ -302,14 +326,14 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Bottom line: use the gzip format for HTTP 1.1 encoding. Bottom line: use the gzip format for HTTP 1.1 encoding.
37. Does zlib support the new "Deflate64" format introduced by PKWare? 40. Does zlib support the new "Deflate64" format introduced by PKWare?
No. PKWare has apparently decided to keep that format proprietary, since No. PKWare has apparently decided to keep that format proprietary, since
they have not documented it as they have previous compression formats. they have not documented it as they have previous compression formats.
In any case, the compression improvements are so modest compared to other In any case, the compression improvements are so modest compared to other
more modern approaches, that it's not worth the effort to implement. more modern approaches, that it's not worth the effort to implement.
38. Can you please sign these lengthy legal documents and fax them back to us 41. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product? so that we can use your software in our product?
No. Go away. Shoo. No. Go away. Shoo.

3
INDEX
View File

@@ -8,9 +8,12 @@ algorithm.txt description of the (de)compression algorithm
configure configure script for Unix configure configure script for Unix
zconf.in.h template for zconf.h (used by configure) zconf.in.h template for zconf.h (used by configure)
amiga/ makefiles for Amiga SAS C
as400/ makefiles for IBM AS/400
msdos/ makefiles for MSDOS msdos/ makefiles for MSDOS
old/ makefiles for various architectures and zlib documentation old/ makefiles for various architectures and zlib documentation
files that have not yet been updated for zlib 1.2.x files that have not yet been updated for zlib 1.2.x
projects/ projects for various Integrated Development Environments
qnx/ makefiles for QNX qnx/ makefiles for QNX
win32/ makefiles for Windows win32/ makefiles for Windows

View File

@@ -30,7 +30,7 @@ CPP=$(CC) -E
LIBS=libz.a LIBS=libz.a
SHAREDLIB=libz.so SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.0.8 SHAREDLIBV=libz.so.1.2.2.2
SHAREDLIBM=libz.so.1 SHAREDLIBM=libz.so.1
AR=ar rc AR=ar rc

View File

@@ -30,7 +30,7 @@ CPP=$(CC) -E
LIBS=libz.a LIBS=libz.a
SHAREDLIB=libz.so SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.0.8 SHAREDLIBV=libz.so.1.2.2.2
SHAREDLIBM=libz.so.1 SHAREDLIBM=libz.so.1
AR=ar rc AR=ar rc

13
README
View File

@@ -1,6 +1,6 @@
ZLIB DATA COMPRESSION LIBRARY ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.0.8 is a general purpose data compression library. All the code is zlib 1.2.2.2 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files (Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -16,9 +16,8 @@ minigzip.c.
To compile all files and run the test program, follow the instructions given at To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most the top of Makefile. In short "make test; make install" should work for most
machines. For Unix: "./configure; make test; make install" For MSDOS, use one machines. For Unix: "./configure; make test; make install". For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
descrip.mms.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is <info@winimage.com> for the Windows DLL version. The zlib home page is
@@ -34,7 +33,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.2.0.8 are documented in the file ChangeLog. The changes made in version 1.2.2.2 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory "contrib". Unsupported third party contributions are provided in directory "contrib".
@@ -46,7 +45,7 @@ A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
CPAN (Comprehensive Perl Archive Network) sites CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/ http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com> is A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html http://www.python.org/doc/lib/module-zlib.html
@@ -93,7 +92,7 @@ Acknowledgments:
Copyright notice: Copyright notice:
(C) 1995-2003 Jean-loup Gailly and Mark Adler (C) 1995-2004 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

145
adler32.c
View File

@@ -1,5 +1,5 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream /* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -12,35 +12,45 @@
#define NMAX 5552 #define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8); #define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE #ifdef NO_DIVIDE
# define MOD(a) \ # define MOD(a) \
do { \ do { \
if (a > (BASE << 16)) a -= (BASE << 16); \ if (a >= (BASE << 16)) a -= (BASE << 16); \
if (a > (BASE << 15)) a -= (BASE << 15); \ if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a > (BASE << 14)) a -= (BASE << 14); \ if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a > (BASE << 13)) a -= (BASE << 13); \ if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a > (BASE << 12)) a -= (BASE << 12); \ if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a > (BASE << 11)) a -= (BASE << 11); \ if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a > (BASE << 10)) a -= (BASE << 10); \ if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a > (BASE << 9)) a -= (BASE << 9); \ if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a > (BASE << 8)) a -= (BASE << 8); \ if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a > (BASE << 7)) a -= (BASE << 7); \ if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a > (BASE << 6)) a -= (BASE << 6); \ if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a > (BASE << 5)) a -= (BASE << 5); \ if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a > (BASE << 4)) a -= (BASE << 4); \ if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a > (BASE << 3)) a -= (BASE << 3); \ if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a > (BASE << 2)) a -= (BASE << 2); \ if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a > (BASE << 1)) a -= (BASE << 1); \ if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a > BASE) a -= BASE; \ if (a >= BASE) a -= BASE; \
} while (0)
# define MOD4(a) \
do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0) } while (0)
#else #else
# define MOD(a) a %= BASE # define MOD(a) a %= BASE
# define MOD4(a) a %= BASE
#endif #endif
/* ========================================================================= */ /* ========================================================================= */
@@ -49,26 +59,91 @@ uLong ZEXPORT adler32(adler, buf, len)
const Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
unsigned long s1 = adler & 0xffff; unsigned long sum2;
unsigned long s2 = (adler >> 16) & 0xffff; unsigned n;
int k;
if (buf == Z_NULL) return 1L; /* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
while (len > 0) { /* in case user likes doing a byte at a time, keep it fast */
k = len < NMAX ? (int)len : NMAX; if (len == 1) {
len -= k; adler += buf[0];
while (k >= 16) { if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
MOD4(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
DO16(buf); /* 16 sums unrolled */
buf += 16;
} while (--n);
MOD(adler);
MOD(sum2);
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
DO16(buf); DO16(buf);
buf += 16; buf += 16;
k -= 16;
} }
if (k != 0) do { while (len--) {
s1 += *buf++; adler += *buf++;
s2 += s1; sum2 += adler;
} while (--k);
MOD(s1);
MOD(s2);
} }
return (s2 << 16) | s1; MOD(adler);
MOD(sum2);
}
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
/* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE);
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 > BASE) sum1 -= BASE;
if (sum1 > BASE) sum1 -= BASE;
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 > BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
} }

View File

@@ -87,7 +87,7 @@ STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
EXPORT SYMBOL("zError") EXPORT SYMBOL("zError")
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/* Version 1.2.0.7 additional entry points. */ /* Version 1.2.1 additional entry points. */
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/********************************************************************/ /********************************************************************/

View File

@@ -118,6 +118,6 @@
&MODLIB/INFTREES &MODLIB/TREES + &MODLIB/INFTREES &MODLIB/TREES +
&MODLIB/UNCOMPR &MODLIB/ZUTIL) + &MODLIB/UNCOMPR &MODLIB/ZUTIL) +
SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) + SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
TEXT('ZLIB 1.2.0.7') TGTRLS(V4R4M0) TEXT('ZLIB 1.2.2') TGTRLS(V4R4M0)
ENDPGM ENDPGM

View File

@@ -1,4 +1,4 @@
ZLIB version 1.2.0.7 for AS400 installation instructions ZLIB version 1.2.2 for AS400 installation instructions
I) From an AS400 *SAVF file: I) From an AS400 *SAVF file:

View File

@@ -1,7 +1,7 @@
* ZLIB.INC - Interface to the general purpose compression library * ZLIB.INC - Interface to the general purpose compression library
* *
* ILE RPG400 version by Patrick Monnerat, DATASPHERE. * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
* Version 1.2.0.7 * Version 1.2.2.2
* *
* *
* WARNING: * WARNING:
@@ -20,8 +20,8 @@
* Constants * Constants
************************************************************************** **************************************************************************
* *
D ZLIB_VERSION C '1.2.0.8' Header's version D ZLIB_VERSION C '1.2.2.2' Header's version
D ZLIB_VERNUM C X'1208' D ZLIB_VERNUM C X'1222'
* *
D Z_NO_FLUSH C 0 D Z_NO_FLUSH C 0
D Z_SYNC_FLUSH C 2 D Z_SYNC_FLUSH C 2

View File

@@ -1,5 +1,5 @@
/* compress.c -- compress a memory buffer /* compress.c -- compress a memory buffer
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2003 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */

11
configure vendored
View File

@@ -76,8 +76,8 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
SFLAGS=${CFLAGS-"-fPIC -O3"} SFLAGS=${CFLAGS-"-fPIC -O3"}
CFLAGS="$cflags" CFLAGS="$cflags"
case `(uname -s || echo unknown) 2>/dev/null` in case `(uname -s || echo unknown) 2>/dev/null` in
Linux | linux) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};; Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
CYGWIN* | Cygwin* | cygwin* ) CYGWIN* | Cygwin* | cygwin* | OS/2* )
EXE='.exe';; EXE='.exe';;
QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
# (alain.bonnefoy@icbt.com) # (alain.bonnefoy@icbt.com)
@@ -89,9 +89,7 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
SHAREDLIB=libz$shared_ext SHAREDLIB=libz$shared_ext
SHAREDLIBV=libz.$VER$shared_ext SHAREDLIBV=libz.$VER$shared_ext
SHAREDLIBM=libz.$VER1$shared_ext SHAREDLIBM=libz.$VER1$shared_ext
LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name /usr/lib/$SHAREDLIBV -compatibility_version $VER2 -current_version $VER"} LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
libdir='/usr/lib'
includedir='/usr/include';;
*) LDSHARED=${LDSHARED-"$cc -shared"};; *) LDSHARED=${LDSHARED-"$cc -shared"};;
esac esac
else else
@@ -127,6 +125,9 @@ else
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
CFLAGS=${CFLAGS-"-O2"} CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"ld"};; LDSHARED=${LDSHARED-"ld"};;
SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
UNIX_System_V\ 4.2.0) UNIX_System_V\ 4.2.0)
SFLAGS=${CFLAGS-"-KPIC -O"} SFLAGS=${CFLAGS-"-KPIC -O"}
CFLAGS=${CFLAGS-"-O"} CFLAGS=${CFLAGS-"-O"}

View File

@@ -19,8 +19,8 @@ blast/ by Mark Adler <madler@alumni.caltech.edu>
delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro> delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
Support for Delphi and C++ Builder Support for Delphi and C++ Builder
gzappend/ by Mark Adler <madler@alumni.caltech.edu> dotzlib/ by Henrik Ravn <henrik@ravn.com>
append to a gzip file -- illustrates the use of Z_BLOCK Support for Microsoft .Net and Visual C++ .Net
infback9/ by Mark Adler <madler@alumni.caltech.edu> infback9/ by Mark Adler <madler@alumni.caltech.edu>
Unsupported diffs to infback to decode the deflate64 format Unsupported diffs to infback to decode the deflate64 format
@@ -60,11 +60,8 @@ puff/ by Mark Adler <madler@alumni.caltech.edu>
testzlib/ by Gilles Vollant <info@winimage.com> testzlib/ by Gilles Vollant <info@winimage.com>
Example of the use of zlib Example of the use of zlib
untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es> untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
A very simple tar.gz file extractor using zlib A very simple tar.gz file extractor using zlib
visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
How to use compress(), uncompress() and the gz* functions from VB
vstudio/ by Gilles Vollant <info@winimage.com> vstudio/ by Gilles Vollant <info@winimage.com>
Building zlib with Visual Studio .NET Building a minizip-enhanced zlib with Microsoft Visual Studio

106
contrib/ada/buffer_demo.adb Normal file
View File

@@ -0,0 +1,106 @@
----------------------------------------------------------------
-- ZLib for Ada thick binding. --
-- --
-- Copyright (C) 2002-2004 Dmitriy Anisimkov --
-- --
-- Open source license information is in the zlib.ads file. --
----------------------------------------------------------------
--
-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
-- This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
--
-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
-- of exactly the correct size is used for decompressed data, and the last
-- few bytes passed in to Zlib are checksum bytes.
-- This program compresses a string of text, and then decompresses the
-- compressed text into a buffer of the same size as the original text.
with Ada.Streams; use Ada.Streams;
with Ada.Text_IO;
with ZLib; use ZLib;
procedure Buffer_Demo is
EOL : Character renames ASCII.LF;
Text : constant String
:= "Four score and seven years ago our fathers brought forth," & EOL &
"upon this continent, a new nation, conceived in liberty," & EOL &
"and dedicated to the proposition that `all men are created equal'.";
Source : Stream_Element_Array (1 .. Text'Length);
for Source'Address use Text'Address;
begin
Ada.Text_IO.Put (Text);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line
("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
declare
Compressed_Data : Stream_Element_Array (1 .. Text'Length);
L : Stream_Element_Offset;
begin
Compress : declare
Compressor : Filter_Type;
I : Stream_Element_Offset;
begin
Deflate_Init (Compressor);
-- Compress the whole of T at once.
Translate (Compressor, Source, I, Compressed_Data, L, Finish);
pragma Assert (I = Source'Last);
Close (Compressor);
Ada.Text_IO.Put_Line
("Compressed size : "
& Stream_Element_Offset'Image (L) & " bytes");
end Compress;
-- Now we decompress the data, passing short blocks of data to Zlib
-- (because this demonstrates the problem - the last block passed will
-- contain checksum information and there will be no output, only a
-- check inside Zlib that the checksum is correct).
Decompress : declare
Decompressor : Filter_Type;
Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
Block_Size : constant := 4;
-- This makes sure that the last block contains
-- only Adler checksum data.
P : Stream_Element_Offset := Compressed_Data'First - 1;
O : Stream_Element_Offset;
begin
Inflate_Init (Decompressor);
loop
Translate
(Decompressor,
Compressed_Data
(P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
P,
Uncompressed_Data
(Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
O,
No_Flush);
Ada.Text_IO.Put_Line
("Total in : " & Count'Image (Total_In (Decompressor)) &
", out : " & Count'Image (Total_Out (Decompressor)));
exit when P = L;
end loop;
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line
("Decompressed text matches original text : "
& Boolean'Image (Uncompressed_Data = Source));
end Decompress;
end;
end Buffer_Demo;

View File

@@ -5,10 +5,10 @@
-- -- -- --
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- Continuous test for ZLib multithreading. If the test is fail -- Continuous test for ZLib multithreading. If the test would fail
-- Wou should provide thread safe allocation routines for the Z_Stream. -- we should provide thread safe allocation routines for the Z_Stream.
-- --
-- $Id: mtest.adb,v 1.2 2003/08/12 12:11:05 vagul Exp $ -- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
with ZLib; with ZLib;
with Ada.Streams; with Ada.Streams;
@@ -148,6 +148,9 @@ procedure MTest is
pragma Unreferenced (Test); pragma Unreferenced (Test);
Dummy : Character;
begin begin
null; Ada.Text_IO.Get_Immediate (Dummy);
Stop := True;
end MTest; end MTest;

View File

@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: read.adb,v 1.7 2003/08/12 12:12:35 vagul Exp $ -- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
-- Test/demo program for the generic read interface. -- Test/demo program for the generic read interface.
@@ -68,7 +68,11 @@ procedure Read is
-- ZLib.Read -- ZLib.Read
-- reading data from the File_In. -- reading data from the File_In.
procedure Read is new ZLib.Read (Read, Read_Buffer, Read_First, Read_Last); procedure Read is new ZLib.Read
(Read,
Read_Buffer,
Rest_First => Read_First,
Rest_Last => Read_Last);
---------- ----------
-- Read -- -- Read --
@@ -103,6 +107,7 @@ procedure Read is
Pack_Size := 0; Pack_Size := 0;
Offset := 1; Offset := 1;
Read_First := Read_Buffer'Last + 1; Read_First := Read_Buffer'Last + 1;
Read_Last := Read_Buffer'Last;
end Reset; end Reset;
begin begin

View File

@@ -1,20 +1,31 @@
ZLib for Ada thick binding (ZLib.Ada) ZLib for Ada thick binding (ZLib.Ada)
Release 1.2 Release 1.3
ZLib.Ada is a thick binding interface to the popular ZLib data ZLib.Ada is a thick binding interface to the popular ZLib data
compression library, available at http://www.gzip.org/zlib/. compression library, available at http://www.gzip.org/zlib/.
It provides Ada-style access to the ZLib C library. It provides Ada-style access to the ZLib C library.
Here are the main changes since ZLib.Ada 1.1: Here are the main changes since ZLib.Ada 1.2:
- The default header type has a name "Default" now. Auto is used only for - Attension: ZLib.Read generic routine have a initialization requirement
automatic GZip/ZLib header detection. for Read_Last parameter now. It is a bit incompartible with previous version,
but extends functionality, we could use new parameters Allow_Read_Some and
Flush now.
- Added test for multitasking mtest.adb. - Added Is_Open routines to ZLib and ZLib.Streams packages.
- Added GNAT project file zlib.gpr. - Add pragma Assert to check Stream_Element is 8 bit.
- Fix extraction to buffer with exact known decompressed size. Error reported by
Steve Sangwine.
- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
computers. Patch provided by Pascal Obry.
- Add Status_Error exception definition.
- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
How to build ZLib.Ada under GNAT How to build ZLib.Ada under GNAT
@@ -50,3 +61,5 @@ The routines from the package specifications are commented.
Homepage: http://zlib-ada.sourceforge.net/ Homepage: http://zlib-ada.sourceforge.net/
Author: Dmitriy Anisimkov <anisimkov@yahoo.com> Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>

View File

@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-streams.adb,v 1.9 2003/08/12 13:15:31 vagul Exp $ -- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
with Ada.Unchecked_Deallocation; with Ada.Unchecked_Deallocation;
@@ -90,6 +90,7 @@ package body ZLib.Streams is
Stream.Buffer := new Buffer_Subtype; Stream.Buffer := new Buffer_Subtype;
Stream.Rest_First := Stream.Buffer'Last + 1; Stream.Rest_First := Stream.Buffer'Last + 1;
Stream.Rest_Last := Stream.Buffer'Last;
end if; end if;
end Create; end Create;
@@ -113,6 +114,15 @@ package body ZLib.Streams is
end loop; end loop;
end Flush; end Flush;
-------------
-- Is_Open --
-------------
function Is_Open (Stream : Stream_Type) return Boolean is
begin
return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
end Is_Open;
---------- ----------
-- Read -- -- Read --
---------- ----------

View File

@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-streams.ads,v 1.11 2003/08/12 13:15:31 vagul Exp $ -- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
package ZLib.Streams is package ZLib.Streams is
@@ -77,6 +77,8 @@ package ZLib.Streams is
-- !!! When the Need_Header is False ZLib-Ada is using undocumented -- !!! When the Need_Header is False ZLib-Ada is using undocumented
-- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
function Is_Open (Stream : Stream_Type) return Boolean;
procedure Close (Stream : in out Stream_Type); procedure Close (Stream : in out Stream_Type);
private private

View File

@@ -6,12 +6,11 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-thin.adb,v 1.6 2003/01/21 15:26:37 vagul Exp $ -- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
package body ZLib.Thin is package body ZLib.Thin is
ZLIB_VERSION : constant Chars_Ptr := ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
Interfaces.C.Strings.New_String ("1.1.4");
Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
@@ -37,14 +36,6 @@ package body ZLib.Thin is
-- Deflate_Init -- -- Deflate_Init --
------------------ ------------------
function Deflate_Init
(strm : in Z_Streamp;
level : in Int := Z_DEFAULT_COMPRESSION)
return Int is
begin
return deflateInit (strm, level, ZLIB_VERSION, Z_Stream_Size);
end Deflate_Init;
function Deflate_Init function Deflate_Init
(strm : Z_Streamp; (strm : Z_Streamp;
level : Int; level : Int;
@@ -69,16 +60,15 @@ package body ZLib.Thin is
-- Inflate_Init -- -- Inflate_Init --
------------------ ------------------
function Inflate_Init (strm : Z_Streamp) return Int is
begin
return inflateInit (strm, ZLIB_VERSION, Z_Stream_Size);
end Inflate_Init;
function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
begin begin
return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
end Inflate_Init; end Inflate_Init;
------------------------
-- Last_Error_Message --
------------------------
function Last_Error_Message (Strm : in Z_Stream) return String is function Last_Error_Message (Strm : in Z_Stream) return String is
use Interfaces.C.Strings; use Interfaces.C.Strings;
begin begin
@@ -89,45 +79,19 @@ package body ZLib.Thin is
end if; end if;
end Last_Error_Message; end Last_Error_Message;
-------------
-- Need_In --
-------------
function Need_In (strm : Z_Stream) return Boolean is
begin
return strm.Avail_In = 0;
end Need_In;
--------------
-- Need_Out --
--------------
function Need_Out (strm : Z_Stream) return Boolean is
begin
return strm.Avail_Out = 0;
end Need_Out;
------------ ------------
-- Set_In -- -- Set_In --
------------ ------------
procedure Set_In procedure Set_In
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Byte_Access; Buffer : in Voidp;
Size : in UInt) is Size : in UInt) is
begin begin
Strm.Next_In := Buffer; Strm.Next_In := Buffer;
Strm.Avail_In := Size; Strm.Avail_In := Size;
end Set_In; end Set_In;
procedure Set_In
(Strm : in out Z_Stream;
Buffer : in Voidp;
Size : in UInt) is
begin
Set_In (Strm, Bytes.To_Pointer (Buffer), Size);
end Set_In;
------------------ ------------------
-- Set_Mem_Func -- -- Set_Mem_Func --
------------------ ------------------
@@ -149,21 +113,13 @@ package body ZLib.Thin is
procedure Set_Out procedure Set_Out
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Byte_Access; Buffer : in Voidp;
Size : in UInt) is Size : in UInt) is
begin begin
Strm.Next_Out := Buffer; Strm.Next_Out := Buffer;
Strm.Avail_Out := Size; Strm.Avail_Out := Size;
end Set_Out; end Set_Out;
procedure Set_Out
(Strm : in out Z_Stream;
Buffer : in Voidp;
Size : in UInt) is
begin
Set_Out (Strm, Bytes.To_Pointer (Buffer), Size);
end Set_Out;
-------------- --------------
-- Total_In -- -- Total_In --
-------------- --------------

View File

@@ -6,10 +6,11 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-thin.ads,v 1.8 2003/08/12 13:16:51 vagul Exp $ -- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
with Interfaces.C.Strings; with Interfaces.C.Strings;
with System.Address_To_Access_Conversions;
with System;
private package ZLib.Thin is private package ZLib.Thin is
@@ -36,18 +37,18 @@ private package ZLib.Thin is
-- zconf.h:216 -- zconf.h:216
type Int is new Interfaces.C.int; type Int is new Interfaces.C.int;
type ULong is new Interfaces.C.unsigned; -- 32 bits or more type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
-- zconf.h:217 -- zconf.h:217
subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
type ULong_Access is access ULong; type ULong_Access is access ULong;
type Int_Access is access Int; type Int_Access is access Int;
subtype Voidp is System.Address; -- zconf.h:232 subtype Voidp is System.Address; -- zconf.h:232
package Bytes is new System.Address_To_Access_Conversions (Byte); subtype Byte_Access is Voidp;
subtype Byte_Access is Bytes.Object_Pointer;
Nul : constant Voidp := System.Null_Address;
-- end from zconf -- end from zconf
Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
@@ -146,17 +147,6 @@ private package ZLib.Thin is
strategy : Int) strategy : Int)
return Int; -- zlib.h:506 return Int; -- zlib.h:506
function deflateBound
(strm : Z_Streamp;
sourceLen : ULong)
return Int; -- zlib.h:595
function deflatePrime
(strm : Z_Streamp;
bits : Int;
value : Int)
return Int; -- zlib.h:604
function inflateSetDictionary function inflateSetDictionary
(strm : Z_Streamp; (strm : Z_Streamp;
dictionary : Byte_Access; dictionary : Byte_Access;
@@ -262,12 +252,6 @@ private package ZLib.Thin is
stream_size : Int) stream_size : Int)
return Int; return Int;
function Deflate_Init
(strm : in Z_Streamp;
level : in Int := Z_DEFAULT_COMPRESSION)
return Int;
pragma Inline (Deflate_Init);
function deflateInit2 function deflateInit2
(strm : Z_Streamp; (strm : Z_Streamp;
level : Int; level : Int;
@@ -295,9 +279,6 @@ private package ZLib.Thin is
stream_size : Int) stream_size : Int)
return Int; return Int;
function Inflate_Init (strm : Z_Streamp) return Int;
pragma Inline (Inflate_Init);
function inflateInit2 function inflateInit2
(strm : in Z_Streamp; (strm : in Z_Streamp;
windowBits : in Int; windowBits : in Int;
@@ -329,32 +310,12 @@ private package ZLib.Thin is
-- has dropped to zero. The application must initialize zalloc, zfree and -- has dropped to zero. The application must initialize zalloc, zfree and
-- opaque before calling the init function. -- opaque before calling the init function.
function Need_In (strm : in Z_Stream) return Boolean;
-- return true when we do not need to setup Next_In and Avail_In fields.
pragma Inline (Need_In);
function Need_Out (strm : in Z_Stream) return Boolean;
-- return true when we do not need to setup Next_Out and Avail_Out field.
pragma Inline (Need_Out);
procedure Set_In
(Strm : in out Z_Stream;
Buffer : in Byte_Access;
Size : in UInt);
pragma Inline (Set_In);
procedure Set_In procedure Set_In
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Voidp; Buffer : in Voidp;
Size : in UInt); Size : in UInt);
pragma Inline (Set_In); pragma Inline (Set_In);
procedure Set_Out
(Strm : in out Z_Stream;
Buffer : in Byte_Access;
Size : in UInt);
pragma Inline (Set_Out);
procedure Set_Out procedure Set_Out
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Voidp; Buffer : in Voidp;
@@ -402,10 +363,10 @@ private package ZLib.Thin is
private private
type Z_Stream is record -- zlib.h:68 type Z_Stream is record -- zlib.h:68
Next_In : Byte_Access; -- next input byte Next_In : Voidp := Nul; -- next input byte
Avail_In : UInt := 0; -- number of bytes available at next_in Avail_In : UInt := 0; -- number of bytes available at next_in
Total_In : ULong := 0; -- total nb of input bytes read so far Total_In : ULong := 0; -- total nb of input bytes read so far
Next_Out : Byte_Access; -- next output byte should be put there Next_Out : Voidp := Nul; -- next output byte should be put there
Avail_Out : UInt := 0; -- remaining free space at next_out Avail_Out : UInt := 0; -- remaining free space at next_out
Total_Out : ULong := 0; -- total nb of bytes output so far Total_Out : ULong := 0; -- total nb of bytes output so far
msg : Chars_Ptr; -- last error message, NULL if no error msg : Chars_Ptr; -- last error message, NULL if no error
@@ -432,8 +393,6 @@ private
pragma Import (C, deflateCopy, "deflateCopy"); pragma Import (C, deflateCopy, "deflateCopy");
pragma Import (C, deflateReset, "deflateReset"); pragma Import (C, deflateReset, "deflateReset");
pragma Import (C, deflateParams, "deflateParams"); pragma Import (C, deflateParams, "deflateParams");
pragma Import (C, deflateBound, "deflateBound");
pragma Import (C, deflatePrime, "deflatePrime");
pragma Import (C, inflateSetDictionary, "inflateSetDictionary"); pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
pragma Import (C, inflateSync, "inflateSync"); pragma Import (C, inflateSync, "inflateSync");
pragma Import (C, inflateReset, "inflateReset"); pragma Import (C, inflateReset, "inflateReset");

View File

@@ -1,12 +1,12 @@
---------------------------------------------------------------- ----------------------------------------------------------------
-- ZLib for Ada thick binding. -- -- ZLib for Ada thick binding. --
-- -- -- --
-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
-- -- -- --
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib.adb,v 1.19 2003/07/13 16:02:19 vagul Exp $ -- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
with Ada.Exceptions; with Ada.Exceptions;
with Ada.Unchecked_Conversion; with Ada.Unchecked_Conversion;
@@ -34,7 +34,7 @@ package body ZLib is
VERSION_ERROR); VERSION_ERROR);
type Flate_Step_Function is access type Flate_Step_Function is access
function (Strm : Thin.Z_Streamp; flush : Thin.Int) return Thin.Int; function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
pragma Convention (C, Flate_Step_Function); pragma Convention (C, Flate_Step_Function);
type Flate_End_Function is access type Flate_End_Function is access
@@ -82,13 +82,13 @@ package body ZLib is
Flush_Finish : constant array (Boolean) of Flush_Mode Flush_Finish : constant array (Boolean) of Flush_Mode
:= (True => Finish, False => No_Flush); := (True => Finish, False => No_Flush);
procedure Raise_Error (Stream : Z_Stream); procedure Raise_Error (Stream : in Z_Stream);
pragma Inline (Raise_Error); pragma Inline (Raise_Error);
procedure Raise_Error (Message : String); procedure Raise_Error (Message : in String);
pragma Inline (Raise_Error); pragma Inline (Raise_Error);
procedure Check_Error (Stream : Z_Stream; Code : Thin.Int); procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
procedure Free is new Ada.Unchecked_Deallocation procedure Free is new Ada.Unchecked_Deallocation
(Z_Stream, Z_Stream_Access); (Z_Stream, Z_Stream_Access);
@@ -118,7 +118,7 @@ package body ZLib is
-- Check_Error -- -- Check_Error --
----------------- -----------------
procedure Check_Error (Stream : Z_Stream; Code : Thin.Int) is procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
use type Thin.Int; use type Thin.Int;
begin begin
if Code /= Thin.Z_OK then if Code /= Thin.Z_OK then
@@ -138,10 +138,11 @@ package body ZLib is
is is
Code : Thin.Int; Code : Thin.Int;
begin begin
Code := Flate (Filter.Compression).Done if not Ignore_Error and then not Is_Open (Filter) then
(To_Thin_Access (Filter.Strm)); raise Status_Error;
end if;
Filter.Opened := False; Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
if Ignore_Error or else Code = Thin.Z_OK then if Ignore_Error or else Code = Thin.Z_OK then
Free (Filter.Strm); Free (Filter.Strm);
@@ -170,9 +171,8 @@ package body ZLib is
is is
use Thin; use Thin;
begin begin
return Unsigned_32 (crc32 return Unsigned_32 (crc32 (ULong (CRC),
(ULong (CRC), Data'Address,
Bytes.To_Pointer (Data'Address),
Data'Length)); Data'Length));
end CRC32; end CRC32;
@@ -192,13 +192,17 @@ package body ZLib is
Level : in Compression_Level := Default_Compression; Level : in Compression_Level := Default_Compression;
Strategy : in Strategy_Type := Default_Strategy; Strategy : in Strategy_Type := Default_Strategy;
Method : in Compression_Method := Deflated; Method : in Compression_Method := Deflated;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Memory_Level : in Memory_Level_Type := 8; Memory_Level : in Memory_Level_Type := Default_Memory_Level;
Header : in Header_Type := Default) Header : in Header_Type := Default)
is is
use type Thin.Int; use type Thin.Int;
Win_Bits : Thin.Int := Thin.Int (Window_Bits); Win_Bits : Thin.Int := Thin.Int (Window_Bits);
begin begin
if Is_Open (Filter) then
raise Status_Error;
end if;
-- We allow ZLib to make header only in case of default header type. -- We allow ZLib to make header only in case of default header type.
-- Otherwise we would either do header by ourselfs, or do not do -- Otherwise we would either do header by ourselfs, or do not do
-- header at all. -- header at all.
@@ -219,7 +223,6 @@ package body ZLib is
Filter.Strm := new Z_Stream; Filter.Strm := new Z_Stream;
Filter.Compression := True; Filter.Compression := True;
Filter.Stream_End := False; Filter.Stream_End := False;
Filter.Opened := True;
Filter.Header := Header; Filter.Header := Header;
if Thin.Deflate_Init if Thin.Deflate_Init
@@ -256,8 +259,8 @@ package body ZLib is
procedure Generic_Translate procedure Generic_Translate
(Filter : in out ZLib.Filter_Type; (Filter : in out ZLib.Filter_Type;
In_Buffer_Size : Integer := Default_Buffer_Size; In_Buffer_Size : in Integer := Default_Buffer_Size;
Out_Buffer_Size : Integer := Default_Buffer_Size) Out_Buffer_Size : in Integer := Default_Buffer_Size)
is is
In_Buffer : Stream_Element_Array In_Buffer : Stream_Element_Array
(1 .. Stream_Element_Offset (In_Buffer_Size)); (1 .. Stream_Element_Offset (In_Buffer_Size));
@@ -275,18 +278,21 @@ package body ZLib is
loop loop
Translate Translate
(Filter, (Filter => Filter,
In_Buffer (In_First .. Last), In_Data => In_Buffer (In_First .. Last),
In_Last, In_Last => In_Last,
Out_Buffer, Out_Data => Out_Buffer,
Out_Last, Out_Last => Out_Last,
Flush_Finish (Last < In_Buffer'First)); Flush => Flush_Finish (Last < In_Buffer'First));
if Out_Buffer'First <= Out_Last then
Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
end if;
exit Main when Stream_End (Filter); exit Main when Stream_End (Filter);
-- The end of in buffer. -- The end of in buffer.
exit when In_Last = Last; exit when In_Last = Last;
In_First := In_Last + 1; In_First := In_Last + 1;
@@ -301,7 +307,7 @@ package body ZLib is
procedure Inflate_Init procedure Inflate_Init
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Header : in Header_Type := Default) Header : in Header_Type := Default)
is is
use type Thin.Int; use type Thin.Int;
@@ -320,6 +326,10 @@ package body ZLib is
end Check_Version; end Check_Version;
begin begin
if Is_Open (Filter) then
raise Status_Error;
end if;
case Header is case Header is
when None => when None =>
Check_Version; Check_Version;
@@ -347,7 +357,6 @@ package body ZLib is
Filter.Strm := new Z_Stream; Filter.Strm := new Z_Stream;
Filter.Compression := False; Filter.Compression := False;
Filter.Stream_End := False; Filter.Stream_End := False;
Filter.Opened := True;
Filter.Header := Header; Filter.Header := Header;
if Thin.Inflate_Init if Thin.Inflate_Init
@@ -357,16 +366,25 @@ package body ZLib is
end if; end if;
end Inflate_Init; end Inflate_Init;
-------------
-- Is_Open --
-------------
function Is_Open (Filter : in Filter_Type) return Boolean is
begin
return Filter.Strm /= null;
end Is_Open;
----------------- -----------------
-- Raise_Error -- -- Raise_Error --
----------------- -----------------
procedure Raise_Error (Message : String) is procedure Raise_Error (Message : in String) is
begin begin
Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
end Raise_Error; end Raise_Error;
procedure Raise_Error (Stream : Z_Stream) is procedure Raise_Error (Stream : in Z_Stream) is
begin begin
Raise_Error (Last_Error_Message (Stream)); Raise_Error (Last_Error_Message (Stream));
end Raise_Error; end Raise_Error;
@@ -378,21 +396,29 @@ package body ZLib is
procedure Read procedure Read
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : out Ada.Streams.Stream_Element_Array; Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset) Last : out Ada.Streams.Stream_Element_Offset;
Flush : in Flush_Mode := No_Flush)
is is
In_Last : Stream_Element_Offset; In_Last : Stream_Element_Offset;
Item_First : Ada.Streams.Stream_Element_Offset := Item'First; Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
V_Flush : Flush_Mode := Flush;
begin begin
pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
loop loop
if Rest_First > Buffer'Last then if Rest_Last = Buffer'First - 1 then
V_Flush := Finish;
elsif Rest_First > Rest_Last then
Read (Buffer, Rest_Last); Read (Buffer, Rest_Last);
Rest_First := Buffer'First; Rest_First := Buffer'First;
end if;
pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); if Rest_Last < Buffer'First then
V_Flush := Finish;
end if;
end if;
Translate Translate
(Filter => Filter, (Filter => Filter,
@@ -400,11 +426,13 @@ package body ZLib is
In_Last => In_Last, In_Last => In_Last,
Out_Data => Item (Item_First .. Item'Last), Out_Data => Item (Item_First .. Item'Last),
Out_Last => Last, Out_Last => Last,
Flush => Flush_Finish (Rest_Last < Rest_First)); Flush => V_Flush);
Rest_First := In_Last + 1; Rest_First := In_Last + 1;
exit when Last = Item'Last or else Stream_End (Filter); exit when Stream_End (Filter)
or else Last = Item'Last
or else (Last >= Item'First and then Allow_Read_Some);
Item_First := Last + 1; Item_First := Last + 1;
end loop; end loop;
@@ -489,11 +517,11 @@ package body ZLib is
Code : Thin.Int; Code : Thin.Int;
begin begin
if Filter.Opened = False then if not Is_Open (Filter) then
raise ZLib_Error; raise Status_Error;
end if; end if;
if Out_Data'Length = 0 then if Out_Data'Length = 0 and then In_Data'Length = 0 then
raise Constraint_Error; raise Constraint_Error;
end if; end if;
@@ -514,7 +542,6 @@ package body ZLib is
- Stream_Element_Offset (Avail_In (Filter.Strm.all)); - Stream_Element_Offset (Avail_In (Filter.Strm.all));
Out_Last := Out_Data'Last Out_Last := Out_Data'Last
- Stream_Element_Offset (Avail_Out (Filter.Strm.all)); - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
end Translate_Auto; end Translate_Auto;
-------------------- --------------------
@@ -604,7 +631,6 @@ package body ZLib is
Flush => Flush); Flush => Flush);
CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
end if; end if;
if Filter.Stream_End and then Out_Last <= Out_Data'Last then if Filter.Stream_End and then Out_Last <= Out_Data'Last then
@@ -642,10 +668,11 @@ package body ZLib is
procedure Write procedure Write
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : in Ada.Streams.Stream_Element_Array; Item : in Ada.Streams.Stream_Element_Array;
Flush : in Flush_Mode) Flush : in Flush_Mode := No_Flush)
is is
Buffer : Stream_Element_Array (1 .. Buffer_Size); Buffer : Stream_Element_Array (1 .. Buffer_Size);
In_Last, Out_Last : Stream_Element_Offset; In_Last : Stream_Element_Offset;
Out_Last : Stream_Element_Offset;
In_First : Stream_Element_Offset := Item'First; In_First : Stream_Element_Offset := Item'First;
begin begin
if Item'Length = 0 and Flush = No_Flush then if Item'Length = 0 and Flush = No_Flush then

View File

@@ -1,7 +1,7 @@
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- ZLib for Ada thick binding. -- -- ZLib for Ada thick binding. --
-- -- -- --
-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
-- -- -- --
-- This library is free software; you can redistribute it and/or modify -- -- This library is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by -- -- it under the terms of the GNU General Public License as published by --
@@ -25,7 +25,7 @@
-- covered by the GNU Public License. -- -- covered by the GNU Public License. --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- $Id: zlib.ads,v 1.17 2003/08/12 13:19:07 vagul Exp $ -- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
with Ada.Streams; with Ada.Streams;
@@ -34,6 +34,7 @@ with Interfaces;
package ZLib is package ZLib is
ZLib_Error : exception; ZLib_Error : exception;
Status_Error : exception;
type Compression_Level is new Integer range -1 .. 9; type Compression_Level is new Integer range -1 .. 9;
@@ -55,12 +56,15 @@ package ZLib is
subtype Count is Ada.Streams.Stream_Element_Count; subtype Count is Ada.Streams.Stream_Element_Count;
Default_Memory_Level : constant Memory_Level_Type := 8;
Default_Window_Bits : constant Window_Bits_Type := 15;
---------------------------------- ----------------------------------
-- Compression method constants -- -- Compression method constants --
---------------------------------- ----------------------------------
Deflated : constant Compression_Method; Deflated : constant Compression_Method;
-- Only one method allowed in this ZLib version. -- Only one method allowed in this ZLib version
--------------------------------- ---------------------------------
-- Compression level constants -- -- Compression level constants --
@@ -79,21 +83,29 @@ package ZLib is
-- Regular way for compression, no flush -- Regular way for compression, no flush
Partial_Flush : constant Flush_Mode; Partial_Flush : constant Flush_Mode;
-- will be removed, use Z_SYNC_FLUSH instead -- Will be removed, use Z_SYNC_FLUSH instead
Sync_Flush : constant Flush_Mode; Sync_Flush : constant Flush_Mode;
-- all pending output is flushed to the output buffer and the output -- All pending output is flushed to the output buffer and the output
-- is aligned on a byte boundary, so that the decompressor can get all -- is aligned on a byte boundary, so that the decompressor can get all
-- input data available so far. (In particular avail_in is zero after the -- input data available so far. (In particular avail_in is zero after the
-- call if enough output space has been provided before the call.) -- call if enough output space has been provided before the call.)
-- Flushing may degrade compression for some compression algorithms and so -- Flushing may degrade compression for some compression algorithms and so
-- it should be used only when necessary. -- it should be used only when necessary.
Block_Flush : constant Flush_Mode;
-- Z_BLOCK requests that inflate() stop
-- if and when it get to the next deflate block boundary. When decoding the
-- zlib or gzip format, this will cause inflate() to return immediately
-- after the header and before the first block. When doing a raw inflate,
-- inflate() will go ahead and process the first block, and will return
-- when it gets to the end of that block, or when it runs out of data.
Full_Flush : constant Flush_Mode; Full_Flush : constant Flush_Mode;
-- all output is flushed as with SYNC_FLUSH, and the compression state -- All output is flushed as with SYNC_FLUSH, and the compression state
-- is reset so that decompression can restart from this point if previous -- is reset so that decompression can restart from this point if previous
-- compressed data has been damaged or if random access is desired. Using -- compressed data has been damaged or if random access is desired. Using
-- FULL_FLUSH too often can seriously degrade the compression. -- Full_Flush too often can seriously degrade the compression.
Finish : constant Flush_Mode; Finish : constant Flush_Mode;
-- Just for tell the compressor that input data is complete. -- Just for tell the compressor that input data is complete.
@@ -111,7 +123,7 @@ package ZLib is
Default_Buffer_Size : constant := 4096; Default_Buffer_Size : constant := 4096;
type Filter_Type is limited private; type Filter_Type is tagged limited private;
-- The filter is for compression and for decompression. -- The filter is for compression and for decompression.
-- The usage of the type is depend of its initialization. -- The usage of the type is depend of its initialization.
@@ -124,8 +136,8 @@ package ZLib is
Level : in Compression_Level := Default_Compression; Level : in Compression_Level := Default_Compression;
Strategy : in Strategy_Type := Default_Strategy; Strategy : in Strategy_Type := Default_Strategy;
Method : in Compression_Method := Deflated; Method : in Compression_Method := Deflated;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Memory_Level : in Memory_Level_Type := 8; Memory_Level : in Memory_Level_Type := Default_Memory_Level;
Header : in Header_Type := Default); Header : in Header_Type := Default);
-- Compressor initialization. -- Compressor initialization.
-- When Header parameter is Auto or Default, then default zlib header -- When Header parameter is Auto or Default, then default zlib header
@@ -136,7 +148,7 @@ package ZLib is
procedure Inflate_Init procedure Inflate_Init
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Header : in Header_Type := Default); Header : in Header_Type := Default);
-- Decompressor initialization. -- Decompressor initialization.
-- Default header type mean that ZLib default header is expecting in the -- Default header type mean that ZLib default header is expecting in the
@@ -146,10 +158,14 @@ package ZLib is
-- input compressed stream. -- input compressed stream.
-- Auto header type mean that header type (GZip or Native) would be -- Auto header type mean that header type (GZip or Native) would be
-- detected automatically in the input stream. -- detected automatically in the input stream.
-- Note that header types parameter values None, GZip and Auto is -- Note that header types parameter values None, GZip and Auto are
-- supporting for inflate routine only in ZLib versions 1.2.0.2 and later. -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
-- Deflate_Init is supporting all header types. -- Deflate_Init is supporting all header types.
function Is_Open (Filter : in Filter_Type) return Boolean;
pragma Inline (Is_Open);
-- Is the filter opened for compression or decompression.
procedure Close procedure Close
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Ignore_Error : in Boolean := False); Ignore_Error : in Boolean := False);
@@ -167,31 +183,31 @@ package ZLib is
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
In_Buffer_Size : in Integer := Default_Buffer_Size; In_Buffer_Size : in Integer := Default_Buffer_Size;
Out_Buffer_Size : in Integer := Default_Buffer_Size); Out_Buffer_Size : in Integer := Default_Buffer_Size);
-- Compressing/decompressing data arrived from Data_In routine -- Compress/decompress data fetch from Data_In routine and pass the result
-- to the Data_Out routine. User should provide Data_In and Data_Out -- to the Data_Out routine. User should provide Data_In and Data_Out
-- for compression/decompression data flow. -- for compression/decompression data flow.
-- Compression or decompression depend on initialization of Filter. -- Compression or decompression depend on Filter initialization.
function Total_In (Filter : in Filter_Type) return Count; function Total_In (Filter : in Filter_Type) return Count;
pragma Inline (Total_In); pragma Inline (Total_In);
-- Return total number of input bytes read so far. -- Returns total number of input bytes read so far
function Total_Out (Filter : in Filter_Type) return Count; function Total_Out (Filter : in Filter_Type) return Count;
pragma Inline (Total_Out); pragma Inline (Total_Out);
-- Return total number of bytes output so far. -- Returns total number of bytes output so far
function CRC32 function CRC32
(CRC : in Unsigned_32; (CRC : in Unsigned_32;
Data : in Ada.Streams.Stream_Element_Array) Data : in Ada.Streams.Stream_Element_Array)
return Unsigned_32; return Unsigned_32;
pragma Inline (CRC32); pragma Inline (CRC32);
-- Calculate CRC32, it could be necessary for make gzip format. -- Compute CRC32, it could be necessary for make gzip format
procedure CRC32 procedure CRC32
(CRC : in out Unsigned_32; (CRC : in out Unsigned_32;
Data : in Ada.Streams.Stream_Element_Array); Data : in Ada.Streams.Stream_Element_Array);
pragma Inline (CRC32); pragma Inline (CRC32);
-- Calculate CRC32, it could be necessary for make gzip format. -- Compute CRC32, it could be necessary for make gzip format
------------------------------------------------- -------------------------------------------------
-- Below is more complex low level routines. -- -- Below is more complex low level routines. --
@@ -204,15 +220,11 @@ package ZLib is
Out_Data : out Ada.Streams.Stream_Element_Array; Out_Data : out Ada.Streams.Stream_Element_Array;
Out_Last : out Ada.Streams.Stream_Element_Offset; Out_Last : out Ada.Streams.Stream_Element_Offset;
Flush : in Flush_Mode); Flush : in Flush_Mode);
-- Compressing/decompressing the datas from In_Data buffer to the -- Compress/decompress the In_Data buffer and place the result into
-- Out_Data buffer. -- Out_Data. In_Last is the index of last element from In_Data accepted by
-- In_Data is incoming data portion, -- the Filter. Out_Last is the last element of the received data from
-- In_Last is the index of last element from In_Data accepted by the -- Filter. To tell the filter that incoming data are complete put the
-- Filter. -- Flush parameter to Finish.
-- Out_Data is the buffer for output data from the filter.
-- Out_Last is the last element of the received data from Filter.
-- To tell the filter that incoming data is complete put the
-- Flush parameter to FINISH.
function Stream_End (Filter : in Filter_Type) return Boolean; function Stream_End (Filter : in Filter_Type) return Boolean;
pragma Inline (Stream_End); pragma Inline (Stream_End);
@@ -239,10 +251,9 @@ package ZLib is
procedure Write procedure Write
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : in Ada.Streams.Stream_Element_Array; Item : in Ada.Streams.Stream_Element_Array;
Flush : in Flush_Mode); Flush : in Flush_Mode := No_Flush);
-- Compressing/Decompressing data from Item to the -- Compress/Decompress data from Item to the generic parameter procedure
-- generic parameter procedure Write. -- Write. Output buffer size could be set in Buffer_Size generic parameter.
-- Output buffer size could be set in Buffer_Size generic parameter.
generic generic
with procedure Read with procedure Read
@@ -257,33 +268,41 @@ package ZLib is
Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
-- Rest_First have to be initialized to Buffer'Last + 1 -- Rest_First have to be initialized to Buffer'Last + 1
-- Rest_Last have to be initialized to Buffer'Last
-- before usage. -- before usage.
Allow_Read_Some : in Boolean := False;
-- Is it allowed to return Last < Item'Last before end of data.
procedure Read procedure Read
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : out Ada.Streams.Stream_Element_Array; Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset); Last : out Ada.Streams.Stream_Element_Offset;
-- Compressing/Decompressing data from generic parameter Flush : in Flush_Mode := No_Flush);
-- procedure Read to the Item. -- Compress/Decompress data from generic parameter procedure Read to the
-- User should provide Buffer for the operation -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
-- and Rest_First variable first time initialized to the Buffer'Last + 1. -- indicators. If Allow_Read_Some is True, Read routines could return
-- Last < Item'Last only at end of stream.
private private
use Ada.Streams; use Ada.Streams;
type Flush_Mode is new Integer range 0 .. 4; pragma Assert (Ada.Streams.Stream_Element'Size = 8);
pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
type Flush_Mode is new Integer range 0 .. 5;
type Compression_Method is new Integer range 8 .. 8; type Compression_Method is new Integer range 8 .. 8;
type Strategy_Type is new Integer range 0 .. 3; type Strategy_Type is new Integer range 0 .. 3;
No_Flush : constant Flush_Mode := 0; No_Flush : constant Flush_Mode := 0;
Partial_Flush : constant Flush_Mode := 1;
Sync_Flush : constant Flush_Mode := 2; Sync_Flush : constant Flush_Mode := 2;
Full_Flush : constant Flush_Mode := 3; Full_Flush : constant Flush_Mode := 3;
Finish : constant Flush_Mode := 4; Finish : constant Flush_Mode := 4;
Partial_Flush : constant Flush_Mode := 1; Block_Flush : constant Flush_Mode := 5;
-- will be removed, use Z_SYNC_FLUSH instead
Filtered : constant Strategy_Type := 1; Filtered : constant Strategy_Type := 1;
Huffman_Only : constant Strategy_Type := 2; Huffman_Only : constant Strategy_Type := 2;
@@ -296,7 +315,7 @@ private
type Z_Stream_Access is access all Z_Stream; type Z_Stream_Access is access all Z_Stream;
type Filter_Type is record type Filter_Type is tagged limited record
Strm : Z_Stream_Access; Strm : Z_Stream_Access;
Compression : Boolean; Compression : Boolean;
Stream_End : Boolean; Stream_End : Boolean;
@@ -304,8 +323,6 @@ private
CRC : Unsigned_32; CRC : Unsigned_32;
Offset : Stream_Element_Offset; Offset : Stream_Element_Offset;
-- Offset for gzip header/footer output. -- Offset for gzip header/footer output.
Opened : Boolean := False;
end record; end record;
end ZLib; end ZLib;

View File

@@ -3,10 +3,10 @@ project Zlib is
for Languages use ("Ada"); for Languages use ("Ada");
for Source_Dirs use ("."); for Source_Dirs use (".");
for Object_Dir use "."; for Object_Dir use ".";
for Main use ("test.adb", "mtest.adb", "read.adb"); for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
package Compiler is package Compiler is
for Default_Switches ("ada") use ("-gnatwbcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
end Compiler; end Compiler;
package Linker is package Linker is
@@ -18,4 +18,3 @@ project Zlib is
end Builder; end Builder;
end Zlib; end Zlib;

View File

@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
const OutBuf: Pointer; BufSize: Integer); const OutBuf: Pointer; BufSize: Integer);
const const
zlib_version = '1.2.1'; zlib_version = '1.2.2';
type type
EZlibError = class(Exception); EZlibError = class(Exception);
@@ -344,7 +344,7 @@ begin
strm.avail_out := OutBytes; strm.avail_out := OutBytes;
DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
try try
while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
begin begin
P := OutBuf; P := OutBuf;
Inc(OutBytes, BufInc); Inc(OutBytes, BufInc);

View File

@@ -14,7 +14,7 @@ we recommend the users to update their ZLib unit.
Summary of modifications Summary of modifications
======================== ========================
- Improved makefile, adapted to zlib version 1.2.0. - Improved makefile, adapted to zlib version 1.2.1.
- Some field types from TZStreamRec are changed from Integer to - Some field types from TZStreamRec are changed from Integer to
Longint, for consistency with the zlib.h header, and for 64-bit Longint, for consistency with the zlib.h header, and for 64-bit

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<project name="DotZLib" default="build" basedir="./DotZLib">
<description>A .Net wrapper library around ZLib1.dll</description>
<property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
<property name="build.root" value="bin" />
<property name="debug" value="true" />
<property name="nunit" value="true" />
<property name="build.folder" value="${build.root}/debug/" if="${debug}" />
<property name="build.folder" value="${build.root}/release/" unless="${debug}" />
<target name="clean" description="Remove all generated files">
<delete dir="${build.root}" failonerror="false" />
</target>
<target name="build" description="compiles the source code">
<mkdir dir="${build.folder}" />
<csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
<references basedir="${nunit.location}">
<includes if="${nunit}" name="nunit.framework.dll" />
</references>
<sources>
<includes name="*.cs" />
<excludes name="UnitTests.cs" unless="${nunit}" />
</sources>
<arg value="/d:nunit" if="${nunit}" />
</csc>
</target>
</project>

BIN
contrib/dotzlib/DotZLib.chm Normal file

Binary file not shown.

View File

@@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("DotZLib")]
[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Henrik Ravn")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

View File

@@ -0,0 +1,202 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace DotZLib
{
#region ChecksumGeneratorBase
/// <summary>
/// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
/// </summary>
/// <example></example>
public abstract class ChecksumGeneratorBase : ChecksumGenerator
{
/// <summary>
/// The value of the current checksum
/// </summary>
protected uint _current;
/// <summary>
/// Initializes a new instance of the checksum generator base - the current checksum is
/// set to zero
/// </summary>
public ChecksumGeneratorBase()
{
_current = 0;
}
/// <summary>
/// Initializes a new instance of the checksum generator basewith a specified value
/// </summary>
/// <param name="initialValue">The value to set the current checksum to</param>
public ChecksumGeneratorBase(uint initialValue)
{
_current = initialValue;
}
/// <summary>
/// Resets the current checksum to zero
/// </summary>
public void Reset() { _current = 0; }
/// <summary>
/// Gets the current checksum value
/// </summary>
public uint Value { get { return _current; } }
/// <summary>
/// Updates the current checksum with part of an array of bytes
/// </summary>
/// <param name="data">The data to update the checksum with</param>
/// <param name="offset">Where in <c>data</c> to start updating</param>
/// <param name="count">The number of bytes from <c>data</c> to use</param>
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
/// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
/// This is therefore the only method a derived class has to implement</remarks>
public abstract void Update(byte[] data, int offset, int count);
/// <summary>
/// Updates the current checksum with an array of bytes.
/// </summary>
/// <param name="data">The data to update the checksum with</param>
public void Update(byte[] data)
{
Update(data, 0, data.Length);
}
/// <summary>
/// Updates the current checksum with the data from a string
/// </summary>
/// <param name="data">The string to update the checksum with</param>
/// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
public void Update(string data)
{
Update(Encoding.UTF8.GetBytes(data));
}
/// <summary>
/// Updates the current checksum with the data from a string, using a specific encoding
/// </summary>
/// <param name="data">The string to update the checksum with</param>
/// <param name="encoding">The encoding to use</param>
public void Update(string data, Encoding encoding)
{
Update(encoding.GetBytes(data));
}
}
#endregion
#region CRC32
/// <summary>
/// Implements a CRC32 checksum generator
/// </summary>
public sealed class CRC32Checksum : ChecksumGeneratorBase
{
#region DLL imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern uint crc32(uint crc, int data, uint length);
#endregion
/// <summary>
/// Initializes a new instance of the CRC32 checksum generator
/// </summary>
public CRC32Checksum() : base() {}
/// <summary>
/// Initializes a new instance of the CRC32 checksum generator with a specified value
/// </summary>
/// <param name="initialValue">The value to set the current checksum to</param>
public CRC32Checksum(uint initialValue) : base(initialValue) {}
/// <summary>
/// Updates the current checksum with part of an array of bytes
/// </summary>
/// <param name="data">The data to update the checksum with</param>
/// <param name="offset">Where in <c>data</c> to start updating</param>
/// <param name="count">The number of bytes from <c>data</c> to use</param>
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
public override void Update(byte[] data, int offset, int count)
{
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > data.Length) throw new ArgumentException();
GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
_current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
}
finally
{
hData.Free();
}
}
}
#endregion
#region Adler
/// <summary>
/// Implements a checksum generator that computes the Adler checksum on data
/// </summary>
public sealed class AdlerChecksum : ChecksumGeneratorBase
{
#region DLL imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern uint adler32(uint adler, int data, uint length);
#endregion
/// <summary>
/// Initializes a new instance of the Adler checksum generator
/// </summary>
public AdlerChecksum() : base() {}
/// <summary>
/// Initializes a new instance of the Adler checksum generator with a specified value
/// </summary>
/// <param name="initialValue">The value to set the current checksum to</param>
public AdlerChecksum(uint initialValue) : base(initialValue) {}
/// <summary>
/// Updates the current checksum with part of an array of bytes
/// </summary>
/// <param name="data">The data to update the checksum with</param>
/// <param name="offset">Where in <c>data</c> to start updating</param>
/// <param name="count">The number of bytes from <c>data</c> to use</param>
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
public override void Update(byte[] data, int offset, int count)
{
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > data.Length) throw new ArgumentException();
GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
_current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
}
finally
{
hData.Free();
}
}
}
#endregion
}

View File

@@ -0,0 +1,83 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Diagnostics;
namespace DotZLib
{
/// <summary>
/// This class implements a circular buffer
/// </summary>
internal class CircularBuffer
{
#region Private data
private int _capacity;
private int _head;
private int _tail;
private int _size;
private byte[] _buffer;
#endregion
public CircularBuffer(int capacity)
{
Debug.Assert( capacity > 0 );
_buffer = new byte[capacity];
_capacity = capacity;
_head = 0;
_tail = 0;
_size = 0;
}
public int Size { get { return _size; } }
public int Put(byte[] source, int offset, int count)
{
Debug.Assert( count > 0 );
int trueCount = Math.Min(count, _capacity - Size);
for (int i = 0; i < trueCount; ++i)
_buffer[(_tail+i) % _capacity] = source[offset+i];
_tail += trueCount;
_tail %= _capacity;
_size += trueCount;
return trueCount;
}
public bool Put(byte b)
{
if (Size == _capacity) // no room
return false;
_buffer[_tail++] = b;
_tail %= _capacity;
++_size;
return true;
}
public int Get(byte[] destination, int offset, int count)
{
int trueCount = Math.Min(count,Size);
for (int i = 0; i < trueCount; ++i)
destination[offset + i] = _buffer[(_head+i) % _capacity];
_head += trueCount;
_head %= _capacity;
_size -= trueCount;
return trueCount;
}
public int Get()
{
if (Size == 0)
return -1;
int result = (int)_buffer[_head++ % _capacity];
--_size;
return result;
}
}
}

View File

@@ -0,0 +1,198 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Runtime.InteropServices;
namespace DotZLib
{
/// <summary>
/// Implements the common functionality needed for all <see cref="Codec"/>s
/// </summary>
public abstract class CodecBase : Codec, IDisposable
{
#region Data members
/// <summary>
/// Instance of the internal zlib buffer structure that is
/// passed to all functions in the zlib dll
/// </summary>
internal ZStream _ztream = new ZStream();
/// <summary>
/// True if the object instance has been disposed, false otherwise
/// </summary>
protected bool _isDisposed = false;
/// <summary>
/// The size of the internal buffers
/// </summary>
protected const int kBufferSize = 16384;
private byte[] _outBuffer = new byte[kBufferSize];
private byte[] _inBuffer = new byte[kBufferSize];
private GCHandle _hInput;
private GCHandle _hOutput;
private uint _checksum = 0;
#endregion
/// <summary>
/// Initializes a new instance of the <c>CodeBase</c> class.
/// </summary>
public CodecBase()
{
try
{
_hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
_hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
}
catch (Exception)
{
CleanUp(false);
throw;
}
}
#region Codec Members
/// <summary>
/// Occurs when more processed data are available.
/// </summary>
public event DataAvailableHandler DataAvailable;
/// <summary>
/// Fires the <see cref="DataAvailable"/> event
/// </summary>
protected void OnDataAvailable()
{
if (_ztream.total_out > 0)
{
if (DataAvailable != null)
DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
resetOutput();
}
}
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
public void Add(byte[] data)
{
Add(data,0,data.Length);
}
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <param name="offset">The index of the first byte to add from <c>data</c></param>
/// <param name="count">The number of bytes to add</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
/// <remarks>This must be implemented by a derived class</remarks>
public abstract void Add(byte[] data, int offset, int count);
/// <summary>
/// Finishes up any pending data that needs to be processed and handled.
/// </summary>
/// <remarks>This must be implemented by a derived class</remarks>
public abstract void Finish();
/// <summary>
/// Gets the checksum of the data that has been added so far
/// </summary>
public uint Checksum { get { return _checksum; } }
#endregion
#region Destructor & IDisposable stuff
/// <summary>
/// Destroys this instance
/// </summary>
~CodecBase()
{
CleanUp(false);
}
/// <summary>
/// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
/// </summary>
public void Dispose()
{
CleanUp(true);
}
/// <summary>
/// Performs any codec specific cleanup
/// </summary>
/// <remarks>This must be implemented by a derived class</remarks>
protected abstract void CleanUp();
// performs the release of the handles and calls the dereived CleanUp()
private void CleanUp(bool isDisposing)
{
if (!_isDisposed)
{
CleanUp();
if (_hInput.IsAllocated)
_hInput.Free();
if (_hOutput.IsAllocated)
_hOutput.Free();
_isDisposed = true;
}
}
#endregion
#region Helper methods
/// <summary>
/// Copies a number of bytes to the internal codec buffer - ready for proccesing
/// </summary>
/// <param name="data">The byte array that contains the data to copy</param>
/// <param name="startIndex">The index of the first byte to copy</param>
/// <param name="count">The number of bytes to copy from <c>data</c></param>
protected void copyInput(byte[] data, int startIndex, int count)
{
Array.Copy(data, startIndex, _inBuffer,0, count);
_ztream.next_in = _hInput.AddrOfPinnedObject();
_ztream.total_in = 0;
_ztream.avail_in = (uint)count;
}
/// <summary>
/// Resets the internal output buffers to a known state - ready for processing
/// </summary>
protected void resetOutput()
{
_ztream.total_out = 0;
_ztream.avail_out = kBufferSize;
_ztream.next_out = _hOutput.AddrOfPinnedObject();
}
/// <summary>
/// Updates the running checksum property
/// </summary>
/// <param name="newSum">The new checksum value</param>
protected void setChecksum(uint newSum)
{
_checksum = newSum;
}
#endregion
}
}

View File

@@ -0,0 +1,106 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace DotZLib
{
/// <summary>
/// Implements a data compressor, using the deflate algorithm in the ZLib dll
/// </summary>
public sealed class Deflater : CodecBase
{
#region Dll imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int deflate(ref ZStream sz, int flush);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int deflateReset(ref ZStream sz);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int deflateEnd(ref ZStream sz);
#endregion
/// <summary>
/// Constructs an new instance of the <c>Deflater</c>
/// </summary>
/// <param name="level">The compression level to use for this <c>Deflater</c></param>
public Deflater(CompressLevel level) : base()
{
int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
if (retval != 0)
throw new ZLibException(retval, "Could not initialize deflater");
resetOutput();
}
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <param name="offset">The index of the first byte to add from <c>data</c></param>
/// <param name="count">The number of bytes to add</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
public override void Add(byte[] data, int offset, int count)
{
if (data == null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > data.Length) throw new ArgumentException();
int total = count;
int inputIndex = offset;
int err = 0;
while (err >= 0 && inputIndex < total)
{
copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
while (err >= 0 && _ztream.avail_in > 0)
{
err = deflate(ref _ztream, (int)FlushTypes.None);
if (err == 0)
while (_ztream.avail_out == 0)
{
OnDataAvailable();
err = deflate(ref _ztream, (int)FlushTypes.None);
}
inputIndex += (int)_ztream.total_in;
}
}
setChecksum( _ztream.adler );
}
/// <summary>
/// Finishes up any pending data that needs to be processed and handled.
/// </summary>
public override void Finish()
{
int err;
do
{
err = deflate(ref _ztream, (int)FlushTypes.Finish);
OnDataAvailable();
}
while (err == 0);
setChecksum( _ztream.adler );
deflateReset(ref _ztream);
resetOutput();
}
/// <summary>
/// Closes the internal zlib deflate stream
/// </summary>
protected override void CleanUp() { deflateEnd(ref _ztream); }
}
}

View File

@@ -0,0 +1,288 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace DotZLib
{
#region Internal types
/// <summary>
/// Defines constants for the various flush types used with zlib
/// </summary>
internal enum FlushTypes
{
None, Partial, Sync, Full, Finish, Block
}
#region ZStream structure
// internal mapping of the zlib zstream structure for marshalling
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
internal struct ZStream
{
public IntPtr next_in;
public uint avail_in;
public uint total_in;
public IntPtr next_out;
public uint avail_out;
public uint total_out;
[MarshalAs(UnmanagedType.LPStr)]
string msg;
uint state;
uint zalloc;
uint zfree;
uint opaque;
int data_type;
public uint adler;
uint reserved;
}
#endregion
#endregion
#region Public enums
/// <summary>
/// Defines constants for the available compression levels in zlib
/// </summary>
public enum CompressLevel : int
{
/// <summary>
/// The default compression level with a reasonable compromise between compression and speed
/// </summary>
Default = -1,
/// <summary>
/// No compression at all. The data are passed straight through.
/// </summary>
None = 0,
/// <summary>
/// The maximum compression rate available.
/// </summary>
Best = 9,
/// <summary>
/// The fastest available compression level.
/// </summary>
Fastest = 1
}
#endregion
#region Exception classes
/// <summary>
/// The exception that is thrown when an error occurs on the zlib dll
/// </summary>
public class ZLibException : ApplicationException
{
/// <summary>
/// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
/// error message and error code
/// </summary>
/// <param name="errorCode">The zlib error code that caused the exception</param>
/// <param name="msg">A message that (hopefully) describes the error</param>
public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
/// error code
/// </summary>
/// <param name="errorCode">The zlib error code that caused the exception</param>
public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
{
}
}
#endregion
#region Interfaces
/// <summary>
/// Declares methods and properties that enables a running checksum to be calculated
/// </summary>
public interface ChecksumGenerator
{
/// <summary>
/// Gets the current value of the checksum
/// </summary>
uint Value { get; }
/// <summary>
/// Clears the current checksum to 0
/// </summary>
void Reset();
/// <summary>
/// Updates the current checksum with an array of bytes
/// </summary>
/// <param name="data">The data to update the checksum with</param>
void Update(byte[] data);
/// <summary>
/// Updates the current checksum with part of an array of bytes
/// </summary>
/// <param name="data">The data to update the checksum with</param>
/// <param name="offset">Where in <c>data</c> to start updating</param>
/// <param name="count">The number of bytes from <c>data</c> to use</param>
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
/// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
void Update(byte[] data, int offset, int count);
/// <summary>
/// Updates the current checksum with the data from a string
/// </summary>
/// <param name="data">The string to update the checksum with</param>
/// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
void Update(string data);
/// <summary>
/// Updates the current checksum with the data from a string, using a specific encoding
/// </summary>
/// <param name="data">The string to update the checksum with</param>
/// <param name="encoding">The encoding to use</param>
void Update(string data, Encoding encoding);
}
/// <summary>
/// Represents the method that will be called from a codec when new data
/// are available.
/// </summary>
/// <paramref name="data">The byte array containing the processed data</paramref>
/// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
/// <paramref name="count">The number of processed bytes available</paramref>
/// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
/// You cannot assume that startIndex will be zero.
/// </remarks>
public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
/// <summary>
/// Declares methods and events for implementing compressors/decompressors
/// </summary>
public interface Codec
{
/// <summary>
/// Occurs when more processed data are available.
/// </summary>
event DataAvailableHandler DataAvailable;
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
void Add(byte[] data);
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <param name="offset">The index of the first byte to add from <c>data</c></param>
/// <param name="count">The number of bytes to add</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
void Add(byte[] data, int offset, int count);
/// <summary>
/// Finishes up any pending data that needs to be processed and handled.
/// </summary>
void Finish();
/// <summary>
/// Gets the checksum of the data that has been added so far
/// </summary>
uint Checksum { get; }
}
#endregion
#region Classes
/// <summary>
/// Encapsulates general information about the ZLib library
/// </summary>
public class Info
{
#region DLL imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern uint zlibCompileFlags();
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern string zlibVersion();
#endregion
#region Private stuff
private uint _flags;
// helper function that unpacks a bitsize mask
private static int bitSize(uint bits)
{
switch (bits)
{
case 0: return 16;
case 1: return 32;
case 2: return 64;
}
return -1;
}
#endregion
/// <summary>
/// Constructs an instance of the <c>Info</c> class.
/// </summary>
public Info()
{
_flags = zlibCompileFlags();
}
/// <summary>
/// True if the library is compiled with debug info
/// </summary>
public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
/// <summary>
/// True if the library is compiled with assembly optimizations
/// </summary>
public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
/// <summary>
/// Gets the size of the unsigned int that was compiled into Zlib
/// </summary>
public int SizeOfUInt { get { return bitSize(_flags & 3); } }
/// <summary>
/// Gets the size of the unsigned long that was compiled into Zlib
/// </summary>
public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
/// <summary>
/// Gets the size of the pointers that were compiled into Zlib
/// </summary>
public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
/// <summary>
/// Gets the size of the z_off_t type that was compiled into Zlib
/// </summary>
public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
/// <summary>
/// Gets the version of ZLib as a string, e.g. "1.2.1"
/// </summary>
public static string Version { get { return zlibVersion(); } }
}
#endregion
}

View File

@@ -0,0 +1,141 @@
<VisualStudioProject>
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
SchemaVersion = "2.0"
ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
>
<Build>
<Settings
ApplicationIcon = ""
AssemblyKeyContainerName = ""
AssemblyName = "DotZLib"
AssemblyOriginatorKeyFile = ""
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
PreBuildEvent = ""
PostBuildEvent = ""
RootNamespace = "DotZLib"
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = ""
>
<Config
Name = "Debug"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "DEBUG;TRACE"
DocumentationFile = "docs\DotZLib.xml"
DebugSymbols = "true"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = "1591"
Optimize = "false"
OutputPath = "bin\Debug\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
<Config
Name = "Release"
AllowUnsafeBlocks = "false"
BaseAddress = "285212672"
CheckForOverflowUnderflow = "false"
ConfigurationOverrideFile = ""
DefineConstants = "TRACE"
DocumentationFile = "docs\DotZLib.xml"
DebugSymbols = "false"
FileAlignment = "4096"
IncrementalBuild = "false"
NoStdLib = "false"
NoWarn = ""
Optimize = "true"
OutputPath = "bin\Release\"
RegisterForComInterop = "false"
RemoveIntegerChecks = "false"
TreatWarningsAsErrors = "false"
WarningLevel = "4"
/>
</Settings>
<References>
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
/>
<Reference
Name = "System.Data"
AssemblyName = "System.Data"
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
/>
<Reference
Name = "System.XML"
AssemblyName = "System.Xml"
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
<Reference
Name = "nunit.framework"
AssemblyName = "nunit.framework"
HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
AssemblyFolderKey = "hklm\dn\nunit.framework"
/>
</References>
</Build>
<Files>
<Include>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "ChecksumImpl.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "CircularBuffer.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "CodecBase.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Deflater.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "DotZLib.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "GZipStream.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Inflater.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "UnitTests.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>

View File

@@ -0,0 +1,301 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace DotZLib
{
/// <summary>
/// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
/// </summary>
public class GZipStream : Stream, IDisposable
{
#region Dll Imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
private static extern IntPtr gzopen(string name, string mode);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int gzclose(IntPtr gzFile);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int gzwrite(IntPtr gzFile, int data, int length);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int gzread(IntPtr gzFile, int data, int length);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int gzgetc(IntPtr gzFile);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int gzputc(IntPtr gzFile, int c);
#endregion
#region Private data
private IntPtr _gzFile;
private bool _isDisposed = false;
private bool _isWriting;
#endregion
#region Constructors
/// <summary>
/// Creates a new file as a writeable GZipStream
/// </summary>
/// <param name="fileName">The name of the compressed file to create</param>
/// <param name="level">The compression level to use when adding data</param>
/// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
public GZipStream(string fileName, CompressLevel level)
{
_isWriting = true;
_gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
if (_gzFile == IntPtr.Zero)
throw new ZLibException(-1, "Could not open " + fileName);
}
/// <summary>
/// Opens an existing file as a readable GZipStream
/// </summary>
/// <param name="fileName">The name of the file to open</param>
/// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
public GZipStream(string fileName)
{
_isWriting = false;
_gzFile = gzopen(fileName, "rb");
if (_gzFile == IntPtr.Zero)
throw new ZLibException(-1, "Could not open " + fileName);
}
#endregion
#region Access properties
/// <summary>
/// Returns true of this stream can be read from, false otherwise
/// </summary>
public override bool CanRead
{
get
{
return !_isWriting;
}
}
/// <summary>
/// Returns false.
/// </summary>
public override bool CanSeek
{
get
{
return false;
}
}
/// <summary>
/// Returns true if this tsream is writeable, false otherwise
/// </summary>
public override bool CanWrite
{
get
{
return _isWriting;
}
}
#endregion
#region Destructor & IDispose stuff
/// <summary>
/// Destroys this instance
/// </summary>
~GZipStream()
{
cleanUp(false);
}
/// <summary>
/// Closes the external file handle
/// </summary>
public void Dispose()
{
cleanUp(true);
}
// Does the actual closing of the file handle.
private void cleanUp(bool isDisposing)
{
if (!_isDisposed)
{
gzclose(_gzFile);
_isDisposed = true;
}
}
#endregion
#region Basic reading and writing
/// <summary>
/// Attempts to read a number of bytes from the stream.
/// </summary>
/// <param name="buffer">The destination data buffer</param>
/// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
/// <param name="count">The number of bytes requested</param>
/// <returns>The number of bytes read</returns>
/// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
/// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
/// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
/// <exception cref="NotSupportedException">If this stream is not readable.</exception>
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
public override int Read(byte[] buffer, int offset, int count)
{
if (!CanRead) throw new NotSupportedException();
if (buffer == null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > buffer.Length) throw new ArgumentException();
if (_isDisposed) throw new ObjectDisposedException("GZipStream");
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
int result;
try
{
result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
if (result < 0)
throw new IOException();
}
finally
{
h.Free();
}
return result;
}
/// <summary>
/// Attempts to read a single byte from the stream.
/// </summary>
/// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
public override int ReadByte()
{
if (!CanRead) throw new NotSupportedException();
if (_isDisposed) throw new ObjectDisposedException("GZipStream");
return gzgetc(_gzFile);
}
/// <summary>
/// Writes a number of bytes to the stream
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
/// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
/// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
/// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
public override void Write(byte[] buffer, int offset, int count)
{
if (!CanWrite) throw new NotSupportedException();
if (buffer == null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > buffer.Length) throw new ArgumentException();
if (_isDisposed) throw new ObjectDisposedException("GZipStream");
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
if (result < 0)
throw new IOException();
}
finally
{
h.Free();
}
}
/// <summary>
/// Writes a single byte to the stream
/// </summary>
/// <param name="value">The byte to add to the stream.</param>
/// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
public override void WriteByte(byte value)
{
if (!CanWrite) throw new NotSupportedException();
if (_isDisposed) throw new ObjectDisposedException("GZipStream");
int result = gzputc(_gzFile, (int)value);
if (result < 0)
throw new IOException();
}
#endregion
#region Position & length stuff
/// <summary>
/// Not supported.
/// </summary>
/// <param name="value"></param>
/// <exception cref="NotSupportedException">Always thrown</exception>
public override void SetLength(long value)
{
throw new NotSupportedException();
}
/// <summary>
/// Not suppported.
/// </summary>
/// <param name="offset"></param>
/// <param name="origin"></param>
/// <returns></returns>
/// <exception cref="NotSupportedException">Always thrown</exception>
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
/// <summary>
/// Flushes the <c>GZipStream</c>.
/// </summary>
/// <remarks>In this implementation, this method does nothing. This is because excessive
/// flushing may degrade the achievable compression rates.</remarks>
public override void Flush()
{
// left empty on purpose
}
/// <summary>
/// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
/// </summary>
/// <remarks>In this implementation this property is not supported</remarks>
/// <exception cref="NotSupportedException">Always thrown</exception>
public override long Position
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
/// <summary>
/// Gets the size of the stream. Not suppported.
/// </summary>
/// <remarks>In this implementation this property is not supported</remarks>
/// <exception cref="NotSupportedException">Always thrown</exception>
public override long Length
{
get
{
throw new NotSupportedException();
}
}
#endregion
}
}

View File

@@ -0,0 +1,105 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace DotZLib
{
/// <summary>
/// Implements a data decompressor, using the inflate algorithm in the ZLib dll
/// </summary>
public class Inflater : CodecBase
{
#region Dll imports
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
private static extern int inflateInit_(ref ZStream sz, string vs, int size);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int inflate(ref ZStream sz, int flush);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int inflateReset(ref ZStream sz);
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
private static extern int inflateEnd(ref ZStream sz);
#endregion
/// <summary>
/// Constructs an new instance of the <c>Inflater</c>
/// </summary>
public Inflater() : base()
{
int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
if (retval != 0)
throw new ZLibException(retval, "Could not initialize inflater");
resetOutput();
}
/// <summary>
/// Adds more data to the codec to be processed.
/// </summary>
/// <param name="data">Byte array containing the data to be added to the codec</param>
/// <param name="offset">The index of the first byte to add from <c>data</c></param>
/// <param name="count">The number of bytes to add</param>
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
public override void Add(byte[] data, int offset, int count)
{
if (data == null) throw new ArgumentNullException();
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
if ((offset+count) > data.Length) throw new ArgumentException();
int total = count;
int inputIndex = offset;
int err = 0;
while (err >= 0 && inputIndex < total)
{
copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
err = inflate(ref _ztream, (int)FlushTypes.None);
if (err == 0)
while (_ztream.avail_out == 0)
{
OnDataAvailable();
err = inflate(ref _ztream, (int)FlushTypes.None);
}
inputIndex += (int)_ztream.total_in;
}
setChecksum( _ztream.adler );
}
/// <summary>
/// Finishes up any pending data that needs to be processed and handled.
/// </summary>
public override void Finish()
{
int err;
do
{
err = inflate(ref _ztream, (int)FlushTypes.Finish);
OnDataAvailable();
}
while (err == 0);
setChecksum( _ztream.adler );
inflateReset(ref _ztream);
resetOutput();
}
/// <summary>
/// Closes the internal zlib inflate stream
/// </summary>
protected override void CleanUp() { inflateEnd(ref _ztream); }
}
}

View File

@@ -0,0 +1,274 @@
//
// <20> Copyright Henrik Ravn 2004
//
// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
using System;
using System.Collections;
using System.IO;
// uncomment the define below to include unit tests
//#define nunit
#if nunit
using NUnit.Framework;
// Unit tests for the DotZLib class library
// ----------------------------------------
//
// Use this with NUnit 2 from http://www.nunit.org
//
namespace DotZLibTests
{
using DotZLib;
// helper methods
internal class Utils
{
public static bool byteArrEqual( byte[] lhs, byte[] rhs )
{
if (lhs.Length != rhs.Length)
return false;
for (int i = lhs.Length-1; i >= 0; --i)
if (lhs[i] != rhs[i])
return false;
return true;
}
}
[TestFixture]
public class CircBufferTests
{
#region Circular buffer tests
[Test]
public void SinglePutGet()
{
CircularBuffer buf = new CircularBuffer(10);
Assert.AreEqual( 0, buf.Size );
Assert.AreEqual( -1, buf.Get() );
Assert.IsTrue(buf.Put( 1 ));
Assert.AreEqual( 1, buf.Size );
Assert.AreEqual( 1, buf.Get() );
Assert.AreEqual( 0, buf.Size );
Assert.AreEqual( -1, buf.Get() );
}
[Test]
public void BlockPutGet()
{
CircularBuffer buf = new CircularBuffer(10);
byte[] arr = {1,2,3,4,5,6,7,8,9,10};
Assert.AreEqual( 10, buf.Put(arr,0,10) );
Assert.AreEqual( 10, buf.Size );
Assert.IsFalse( buf.Put(11) );
Assert.AreEqual( 1, buf.Get() );
Assert.IsTrue( buf.Put(11) );
byte[] arr2 = (byte[])arr.Clone();
Assert.AreEqual( 9, buf.Get(arr2,1,9) );
Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
}
#endregion
}
[TestFixture]
public class ChecksumTests
{
#region CRC32 Tests
[Test]
public void CRC32_Null()
{
CRC32Checksum crc32 = new CRC32Checksum();
Assert.AreEqual( 0, crc32.Value );
crc32 = new CRC32Checksum(1);
Assert.AreEqual( 1, crc32.Value );
crc32 = new CRC32Checksum(556);
Assert.AreEqual( 556, crc32.Value );
}
[Test]
public void CRC32_Data()
{
CRC32Checksum crc32 = new CRC32Checksum();
byte[] data = { 1,2,3,4,5,6,7 };
crc32.Update(data);
Assert.AreEqual( 0x70e46888, crc32.Value );
crc32 = new CRC32Checksum();
crc32.Update("penguin");
Assert.AreEqual( 0x0e5c1a120, crc32.Value );
crc32 = new CRC32Checksum(1);
crc32.Update("penguin");
Assert.AreEqual(0x43b6aa94, crc32.Value);
}
#endregion
#region Adler tests
[Test]
public void Adler_Null()
{
AdlerChecksum adler = new AdlerChecksum();
Assert.AreEqual(0, adler.Value);
adler = new AdlerChecksum(1);
Assert.AreEqual( 1, adler.Value );
adler = new AdlerChecksum(556);
Assert.AreEqual( 556, adler.Value );
}
[Test]
public void Adler_Data()
{
AdlerChecksum adler = new AdlerChecksum(1);
byte[] data = { 1,2,3,4,5,6,7 };
adler.Update(data);
Assert.AreEqual( 0x5b001d, adler.Value );
adler = new AdlerChecksum();
adler.Update("penguin");
Assert.AreEqual(0x0bcf02f6, adler.Value );
adler = new AdlerChecksum(1);
adler.Update("penguin");
Assert.AreEqual(0x0bd602f7, adler.Value);
}
#endregion
}
[TestFixture]
public class InfoTests
{
#region Info tests
[Test]
public void Info_Version()
{
Info info = new Info();
Assert.AreEqual("1.2.2", Info.Version);
Assert.AreEqual(32, info.SizeOfUInt);
Assert.AreEqual(32, info.SizeOfULong);
Assert.AreEqual(32, info.SizeOfPointer);
Assert.AreEqual(32, info.SizeOfOffset);
}
#endregion
}
[TestFixture]
public class DeflateInflateTests
{
#region Deflate tests
[Test]
public void Deflate_Init()
{
using (Deflater def = new Deflater(CompressLevel.Default))
{
}
}
private ArrayList compressedData = new ArrayList();
private uint adler1;
private ArrayList uncompressedData = new ArrayList();
private uint adler2;
public void CDataAvail(byte[] data, int startIndex, int count)
{
for (int i = 0; i < count; ++i)
compressedData.Add(data[i+startIndex]);
}
[Test]
public void Deflate_Compress()
{
compressedData.Clear();
byte[] testData = new byte[35000];
for (int i = 0; i < testData.Length; ++i)
testData[i] = 5;
using (Deflater def = new Deflater((CompressLevel)5))
{
def.DataAvailable += new DataAvailableHandler(CDataAvail);
def.Add(testData);
def.Finish();
adler1 = def.Checksum;
}
}
#endregion
#region Inflate tests
[Test]
public void Inflate_Init()
{
using (Inflater inf = new Inflater())
{
}
}
private void DDataAvail(byte[] data, int startIndex, int count)
{
for (int i = 0; i < count; ++i)
uncompressedData.Add(data[i+startIndex]);
}
[Test]
public void Inflate_Expand()
{
uncompressedData.Clear();
using (Inflater inf = new Inflater())
{
inf.DataAvailable += new DataAvailableHandler(DDataAvail);
inf.Add((byte[])compressedData.ToArray(typeof(byte)));
inf.Finish();
adler2 = inf.Checksum;
}
Assert.AreEqual( adler1, adler2 );
}
#endregion
}
[TestFixture]
public class GZipStreamTests
{
#region GZipStream test
[Test]
public void GZipStream_WriteRead()
{
using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
{
BinaryWriter writer = new BinaryWriter(gzOut);
writer.Write("hi there");
writer.Write(Math.PI);
writer.Write(42);
}
using (GZipStream gzIn = new GZipStream("gzstream.gz"))
{
BinaryReader reader = new BinaryReader(gzIn);
string s = reader.ReadString();
Assert.AreEqual("hi there",s);
double d = reader.ReadDouble();
Assert.AreEqual(Math.PI, d);
int i = reader.ReadInt32();
Assert.AreEqual(42,i);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,58 @@
This directory contains a .Net wrapper class library for the ZLib1.dll
The wrapper includes support for inflating/deflating memory buffers,
.Net streaming wrappers for the gz streams part of zlib, and wrappers
for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
Directory structure:
--------------------
LICENSE_1_0.txt - License file.
readme.txt - This file.
DotZLib.chm - Class library documentation
DotZLib.build - NAnt build file
DotZLib.sln - Microsoft Visual Studio 2003 solution file
DotZLib\*.cs - Source files for the class library
Unit tests:
-----------
The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
To include unit tests in the build, define nunit before building.
Build instructions:
-------------------
1. Using Visual Studio.Net 2003:
Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
you are building the release or debug version of the library. Check
DotZLib/UnitTests.cs for instructions on how to include unit tests in the
build.
2. Using NAnt:
Open a command prompt with access to the build environment and run nant
in the same directory as the DotZLib.build file.
You can define 2 properties on the nant command-line to control the build:
debug={true|false} to toggle between release/debug builds (default=true).
nunit={true|false} to include or esclude unit tests (default=true).
Also the target clean will remove binaries.
Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
or ./DotZLib/bin/debug, depending on whether you are building the release
or debug version of the library.
Examples:
nant -D:debug=false -D:nunit=false
will build a release mode version of the library without unit tests.
nant
will build a debug version of the library with unit tests
nant clean
will remove all previously built files.
---------------------------------
Copyright (c) Henrik Ravn 2004
Use, modification and distribution are subject to the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -430,6 +430,9 @@ void FAR *out_desc;
} }
} }
/* handle error breaks in while */
if (mode == BAD) break;
/* build code tables */ /* build code tables */
state->next = state->codes; state->next = state->codes;
lencode = (code const FAR *)(state->next); lencode = (code const FAR *)(state->next);

View File

@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate9_copyright[] = const char inflate9_copyright[] =
" inflate9 1.2.0.8 Copyright 1995-2003 Mark Adler "; " inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
133, 133, 133, 133, 144, 76, 203}; 133, 133, 133, 133, 144, 72, 199};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,

File diff suppressed because it is too large Load Diff

View File

@@ -188,17 +188,8 @@
/* /*
* typedef enum inflate_mode consts, in inflate.h * typedef enum inflate_mode consts, in inflate.h
*/ */
#ifndef NO_GUNZIP
#define GUNZIP
#endif
#ifdef GUNZIP
#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */ #define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
#define INFLATE_MODE_BAD 26 #define INFLATE_MODE_BAD 26
#else
#define INFLATE_MODE_TYPE 3
#define INFLATE_MODE_BAD 17
#endif
#if ! defined( USE_MMX ) && ! defined( NO_MMX ) #if ! defined( USE_MMX ) && ! defined( NO_MMX )

View File

@@ -47,21 +47,25 @@
; all the +4 offsets are due to the addition of pending_buf_size (in zlib ; all the +addstr offsets are due to the addition of pending_buf_size in zlib 1.04
; and adding gzhead and gzindex in zlib 1.2.2.1
; in the deflate_state structure since the asm code was first written ; in the deflate_state structure since the asm code was first written
; (if you compile with zlib 1.0.4 or older, remove the +4). ; (if you compile with zlib 1.0.4 or older, set addstr to 0).
; (if you compiler with zlib between 1.04 and 1.2.1, set addstr to 4)
; Note : these value are good with a 8 bytes boundary pack structure ; Note : these value are good with a 8 bytes boundary pack structure
dep_chain_length equ 70h+4
dep_window equ 2ch+4 addstr equ 4+8
dep_strstart equ 60h+4 dep_chain_length equ 70h+addstr
dep_prev_length equ 6ch+4 dep_window equ 2ch+addstr
dep_nice_match equ 84h+4 dep_strstart equ 60h+addstr
dep_w_size equ 20h+4 dep_prev_length equ 6ch+addstr
dep_prev equ 34h+4 dep_nice_match equ 84h+addstr
dep_w_mask equ 28h+4 dep_w_size equ 20h+addstr
dep_good_match equ 80h+4 dep_prev equ 34h+addstr
dep_match_start equ 64h+4 dep_w_mask equ 28h+addstr
dep_lookahead equ 68h+4 dep_good_match equ 80h+addstr
dep_match_start equ 64h+addstr
dep_lookahead equ 68h+addstr
_TEXT segment _TEXT segment
@@ -597,19 +601,19 @@ curmatch equ esp + 60
;;; program to crash horribly, without so much as a warning at ;;; program to crash horribly, without so much as a warning at
;;; compile time. Sigh.) ;;; compile time. Sigh.)
dsWSize equ 36 dsWSize equ 36+addstr-4
dsWMask equ 44 dsWMask equ 44+addstr-4
dsWindow equ 48 dsWindow equ 48+addstr-4
dsPrev equ 56 dsPrev equ 56+addstr-4
dsMatchLen equ 88 dsMatchLen equ 88+addstr-4
dsPrevMatch equ 92 dsPrevMatch equ 92+addstr-4
dsStrStart equ 100 dsStrStart equ 100+addstr-4
dsMatchStart equ 104 dsMatchStart equ 104+addstr-4
dsLookahead equ 108 dsLookahead equ 108+addstr-4
dsPrevLen equ 112 dsPrevLen equ 112+addstr-4
dsMaxChainLen equ 116 dsMaxChainLen equ 116+addstr-4
dsGoodMatch equ 132 dsGoodMatch equ 132+addstr-4
dsNiceMatch equ 136 dsNiceMatch equ 136+addstr-4
;;; match.asm -- Pentium-Pro-optimized version of longest_match() ;;; match.asm -- Pentium-Pro-optimized version of longest_match()

View File

@@ -84,17 +84,20 @@ dd 2147483647
dd 4294967295 dd 4294967295
; head was added in zlib 1.2.2.1, so we add addstr
; set addstr to 0 with zlib 1.2.1 of below
addstr equ 4
mode_state equ 0 ;/* state->mode */ mode_state equ 0 ;/* state->mode */
wsize_state equ 32 ;/* state->wsize */ wsize_state equ 32+addstr ;/* state->wsize */
write_state equ (36+4) ;/* state->write */ write_state equ (36+4+addstr) ;/* state->write */
window_state equ (40+4) ;/* state->window */ window_state equ (40+4+addstr) ;/* state->window */
hold_state equ (44+4) ;/* state->hold */ hold_state equ (44+4+addstr) ;/* state->hold */
bits_state equ (48+4) ;/* state->bits */ bits_state equ (48+4+addstr) ;/* state->bits */
lencode_state equ (64+4) ;/* state->lencode */ lencode_state equ (64+4+addstr) ;/* state->lencode */
distcode_state equ (68+4) ;/* state->distcode */ distcode_state equ (68+4+addstr) ;/* state->distcode */
lenbits_state equ (72+4) ;/* state->lenbits */ lenbits_state equ (72+4+addstr) ;/* state->lenbits */
distbits_state equ (76+4) ;/* state->distbits */ distbits_state equ (76+4+addstr) ;/* state->distbits */
;;SECTION .text ;;SECTION .text

View File

@@ -1,3 +1,3 @@
cl /I..\.. /O2 /c gvmat32c.c cl /DASMV /I..\.. /O2 /c gvmat32c.c
ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
ml /coff /Zi /c /Flinffas32.lst inffas32.asm ml /coff /Zi /c /Flinffas32.lst inffas32.asm

View File

@@ -1,3 +1,11 @@
Change in 1.01b (20 may 04)
- Integrate patch from Debian package (submited by Mark Brown)
- Add tools mztools from Xavier Roche
Change in 1.01 (8 may 04)
- fix buffer overrun risk in unzip.c (Xavier Roche)
- fix a minor buffer insecurity in minizip.c (Mike Whittaker)
Change in 1.00: (10 sept 03) Change in 1.00: (10 sept 03)
- rename to 1.00 - rename to 1.00
- cosmetic code change - cosmetic code change

View File

@@ -1,9 +1,9 @@
/* crypt.h -- base code for crypt/uncrypt ZIPfile /* crypt.h -- base code for crypt/uncrypt ZIPfile
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
This code is a modified version of crypting code in Infozip distribution This code is a modified version of crypting code in Infozip distribution

View File

@@ -1,9 +1,9 @@
/* ioapi.c -- IO base function header for compress/uncompress .zip /* ioapi.c -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API files using zlib + zip or unzip API
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
*/ */
#include <stdio.h> #include <stdio.h>
@@ -94,7 +94,7 @@ uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
uLong size; uLong size;
{ {
uLong ret; uLong ret;
ret = fread(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
} }
@@ -106,7 +106,7 @@ uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
uLong size; uLong size;
{ {
uLong ret; uLong ret;
ret = fwrite(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
} }

View File

@@ -1,9 +1,9 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip /* ioapi.h -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API files using zlib + zip or unzip API
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
*/ */
#ifndef _ZLIBIOAPI_H #ifndef _ZLIBIOAPI_H

View File

@@ -2,9 +2,9 @@
files using zlib + zip or unzip API files using zlib + zip or unzip API
This IO API version uses the Win32 API (for Microsoft Windows) This IO API version uses the Win32 API (for Microsoft Windows)
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
*/ */
#include <stdlib.h> #include <stdlib.h>

View File

@@ -2,9 +2,9 @@
files using zlib + zip or unzip API files using zlib + zip or unzip API
This IO API version uses the Win32 API (for Microsoft Windows) This IO API version uses the Win32 API (for Microsoft Windows)
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
*/ */
#include <windows.h> #include <windows.h>

View File

@@ -1,3 +1,11 @@
/*
miniunz.c
Version 1.01b, May 30th, 2004
Copyright (C) 1998-2004 Gilles Vollant
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -27,7 +35,7 @@
mini unzip, demo of unzip package mini unzip, demo of unzip package
usage : usage :
Usage : miniunz [-exvlo] file.zip [file_to_extract] Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
if it exists if it exists
@@ -140,17 +148,18 @@ int makedir (newdir)
void do_banner() void do_banner()
{ {
printf("MiniUnz 1.00, demo of zLib + Unz package written by Gilles Vollant\n"); printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
} }
void do_help() void do_help()
{ {
printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.]\n\n" \ printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
" -e Extract without pathname (junk paths)\n" \ " -e Extract without pathname (junk paths)\n" \
" -x Extract with pathname\n" \ " -x Extract with pathname\n" \
" -v list files\n" \ " -v list files\n" \
" -l list files\n" \ " -l list files\n" \
" -d directory to extract into\n" \
" -o overwrite files without prompting\n" \ " -o overwrite files without prompting\n" \
" -p extract crypted file using password\n\n"); " -p extract crypted file using password\n\n");
} }
@@ -304,8 +313,14 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
do do
{ {
char answer[128]; char answer[128];
printf("The file %s exist. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename); int ret;
scanf("%1s",answer);
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
ret = scanf("%1s",answer);
if (ret != 1)
{
exit(EXIT_FAILURE);
}
rep = answer[0] ; rep = answer[0] ;
if ((rep>='a') && (rep<='z')) if ((rep>='a') && (rep<='z'))
rep -= 0x20; rep -= 0x20;
@@ -459,6 +474,8 @@ int main(argc,argv)
int opt_do_extract=1; int opt_do_extract=1;
int opt_do_extract_withoutpath=0; int opt_do_extract_withoutpath=0;
int opt_overwrite=0; int opt_overwrite=0;
int opt_extractdir=0;
const char *dirname=NULL;
unzFile uf=NULL; unzFile uf=NULL;
do_banner(); do_banner();
@@ -488,6 +505,12 @@ int main(argc,argv)
opt_do_extract = opt_do_extract_withoutpath = 1; opt_do_extract = opt_do_extract_withoutpath = 1;
if ((c=='o') || (c=='O')) if ((c=='o') || (c=='O'))
opt_overwrite=1; opt_overwrite=1;
if ((c=='d') || (c=='D'))
{
opt_extractdir=1;
dirname=argv[i+1];
}
if (((c=='p') || (c=='P')) && (i+1<argc)) if (((c=='p') || (c=='P')) && (i+1<argc))
{ {
password=argv[i+1]; password=argv[i+1];
@@ -499,7 +522,7 @@ int main(argc,argv)
{ {
if (zipfilename == NULL) if (zipfilename == NULL)
zipfilename = argv[i]; zipfilename = argv[i];
else if (filename_to_extract==NULL) else if ((filename_to_extract==NULL) && (!opt_extractdir))
filename_to_extract = argv[i] ; filename_to_extract = argv[i] ;
} }
} }
@@ -544,6 +567,12 @@ int main(argc,argv)
return do_list(uf); return do_list(uf);
else if (opt_do_extract==1) else if (opt_do_extract==1)
{ {
if (opt_extractdir && chdir(dirname))
{
printf("Error changing into %s, aborting\n", dirname);
exit(-1);
}
if (filename_to_extract == NULL) if (filename_to_extract == NULL)
return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password); return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);
else else

View File

@@ -1,3 +1,10 @@
/*
minizip.c
Version 1.01b, May 30th, 2004
Copyright (C) 1998-2004 Gilles Vollant
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -66,6 +73,8 @@ uLong filetime(f, tmzip, dt)
{ {
char name[MAXFILENAME+1]; char name[MAXFILENAME+1];
int len = strlen(f); int len = strlen(f);
if (len > MAXFILENAME)
len = MAXFILENAME;
strncpy(name, f,MAXFILENAME-1); strncpy(name, f,MAXFILENAME-1);
/* strncpy doesnt append the trailing NULL, of the string is too long. */ /* strncpy doesnt append the trailing NULL, of the string is too long. */
@@ -120,7 +129,7 @@ int check_exist_file(filename)
void do_banner() void do_banner()
{ {
printf("MiniZip 1.00, demo of zLib + Zip package written by Gilles Vollant\n"); printf("MiniZip 1.01b, demo of zLib + Zip package written by Gilles Vollant\n");
printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
} }
@@ -269,8 +278,13 @@ int main(argc,argv)
do do
{ {
char answer[128]; char answer[128];
printf("The file %s exist. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try); int ret;
scanf("%1s",answer); printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
ret = scanf("%1s",answer);
if (ret != 1)
{
exit(EXIT_FAILURE);
}
rep = answer[0] ; rep = answer[0] ;
if ((rep>='a') && (rep<='z')) if ((rep>='a') && (rep<='z'))
rep -= 0x20; rep -= 0x20;
@@ -305,7 +319,12 @@ int main(argc,argv)
for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++) for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
{ {
if (((*(argv[i]))!='-') && ((*(argv[i]))!='/')) if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
((argv[i][1]=='o') || (argv[i][1]=='O') ||
(argv[i][1]=='a') || (argv[i][1]=='A') ||
(argv[i][1]=='p') || (argv[i][1]=='P') ||
((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
(strlen(argv[i]) == 2)))
{ {
FILE * fin; FILE * fin;
int size_read; int size_read;
@@ -391,6 +410,10 @@ int main(argc,argv)
if (errclose != ZIP_OK) if (errclose != ZIP_OK)
printf("error in closing %s\n",filename_try); printf("error in closing %s\n",filename_try);
} }
else
{
do_help();
}
free(buf); free(buf);
return 0; return 0;

281
contrib/minizip/mztools.c Normal file
View File

@@ -0,0 +1,281 @@
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
/* Code */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#include "unzip.h"
#define READ_8(adr) ((unsigned char)*(adr))
#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
#define WRITE_8(buff, n) do { \
*((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
} while(0)
#define WRITE_16(buff, n) do { \
WRITE_8((unsigned char*)(buff), n); \
WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
} while(0)
#define WRITE_32(buff, n) do { \
WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
} while(0)
extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
const char* file;
const char* fileOut;
const char* fileOutTmp;
uLong* nRecovered;
uLong* bytesRecovered;
{
int err = Z_OK;
FILE* fpZip = fopen(file, "rb");
FILE* fpOut = fopen(fileOut, "wb");
FILE* fpOutCD = fopen(fileOutTmp, "wb");
if (fpZip != NULL && fpOut != NULL) {
int entries = 0;
uLong totalBytes = 0;
char header[30];
char filename[256];
char extra[1024];
int offset = 0;
int offsetCD = 0;
while ( fread(header, 1, 30, fpZip) == 30 ) {
int currentOffset = offset;
/* File entry */
if (READ_32(header) == 0x04034b50) {
unsigned int version = READ_16(header + 4);
unsigned int gpflag = READ_16(header + 6);
unsigned int method = READ_16(header + 8);
unsigned int filetime = READ_16(header + 10);
unsigned int filedate = READ_16(header + 12);
unsigned int crc = READ_32(header + 14); /* crc */
unsigned int cpsize = READ_32(header + 18); /* compressed size */
unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
unsigned int fnsize = READ_16(header + 26); /* file name length */
unsigned int extsize = READ_16(header + 28); /* extra field length */
filename[0] = extra[0] = '\0';
/* Header */
if (fwrite(header, 1, 30, fpOut) == 30) {
offset += 30;
} else {
err = Z_ERRNO;
break;
}
/* Filename */
if (fnsize > 0) {
if (fread(filename, 1, fnsize, fpZip) == fnsize) {
if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
offset += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (fread(extra, 1, extsize, fpZip) == extsize) {
if (fwrite(extra, 1, extsize, fpOut) == extsize) {
offset += extsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_ERRNO;
break;
}
}
/* Data */
{
int dataSize = cpsize;
if (dataSize == 0) {
dataSize = uncpsize;
}
if (dataSize > 0) {
char* data = malloc(dataSize);
if (data != NULL) {
if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
offset += dataSize;
totalBytes += dataSize;
} else {
err = Z_ERRNO;
}
} else {
err = Z_ERRNO;
}
free(data);
if (err != Z_OK) {
break;
}
} else {
err = Z_MEM_ERROR;
break;
}
}
}
/* Central directory entry */
{
char header[46];
char* comment = "";
int comsize = (int) strlen(comment);
WRITE_32(header, 0x02014b50);
WRITE_16(header + 4, version);
WRITE_16(header + 6, version);
WRITE_16(header + 8, gpflag);
WRITE_16(header + 10, method);
WRITE_16(header + 12, filetime);
WRITE_16(header + 14, filedate);
WRITE_32(header + 16, crc);
WRITE_32(header + 20, cpsize);
WRITE_32(header + 24, uncpsize);
WRITE_16(header + 28, fnsize);
WRITE_16(header + 30, extsize);
WRITE_16(header + 32, comsize);
WRITE_16(header + 34, 0); /* disk # */
WRITE_16(header + 36, 0); /* int attrb */
WRITE_32(header + 38, 0); /* ext attrb */
WRITE_32(header + 42, currentOffset);
/* Header */
if (fwrite(header, 1, 46, fpOutCD) == 46) {
offsetCD += 46;
/* Filename */
if (fnsize > 0) {
if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
offsetCD += fnsize;
} else {
err = Z_ERRNO;
break;
}
} else {
err = Z_STREAM_ERROR;
break;
}
/* Extra field */
if (extsize > 0) {
if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
offsetCD += extsize;
} else {
err = Z_ERRNO;
break;
}
}
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
offsetCD += comsize;
} else {
err = Z_ERRNO;
break;
}
}
} else {
err = Z_ERRNO;
break;
}
}
/* Success */
entries++;
} else {
break;
}
}
/* Final central directory */
{
int entriesZip = entries;
char header[22];
char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
int comsize = (int) strlen(comment);
if (entriesZip > 0xffff) {
entriesZip = 0xffff;
}
WRITE_32(header, 0x06054b50);
WRITE_16(header + 4, 0); /* disk # */
WRITE_16(header + 6, 0); /* disk # */
WRITE_16(header + 8, entriesZip); /* hack */
WRITE_16(header + 10, entriesZip); /* hack */
WRITE_32(header + 12, offsetCD); /* size of CD */
WRITE_32(header + 16, offset); /* offset to CD */
WRITE_16(header + 20, comsize); /* comment */
/* Header */
if (fwrite(header, 1, 22, fpOutCD) == 22) {
/* Comment field */
if (comsize > 0) {
if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
err = Z_ERRNO;
}
}
} else {
err = Z_ERRNO;
}
}
/* Final merge (file + central directory) */
fclose(fpOutCD);
if (err == Z_OK) {
fpOutCD = fopen(fileOutTmp, "rb");
if (fpOutCD != NULL) {
int nRead;
char buffer[8192];
while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
err = Z_ERRNO;
break;
}
}
fclose(fpOutCD);
}
}
/* Close */
fclose(fpZip);
fclose(fpOut);
/* Wipe temporary file */
(void)remove(fileOutTmp);
/* Number of recovered entries */
if (err == Z_OK) {
if (nRecovered != NULL) {
*nRecovered = entries;
}
if (bytesRecovered != NULL) {
*bytesRecovered = totalBytes;
}
}
} else {
err = Z_STREAM_ERROR;
}
return err;
}

31
contrib/minizip/mztools.h Normal file
View File

@@ -0,0 +1,31 @@
/*
Additional tools for Minizip
Code: Xavier Roche '2004
License: Same as ZLIB (www.gzip.org)
*/
#ifndef _zip_tools_H
#define _zip_tools_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#include "unzip.h"
/* Repair a ZIP file (missing central directory)
file: file to recover
fileOut: output file after recovery
fileOutTmp: temporary file name used for recovery
*/
extern int ZEXPORT unzRepair(const char* file,
const char* fileOut,
const char* fileOutTmp,
uLong* nRecovered,
uLong* bytesRecovered);
#endif

View File

@@ -1,7 +1,7 @@
/* unzip.c -- IO for uncompress .zip files using zlib /* unzip.c -- IO for uncompress .zip files using zlib
Version 1.00, September 10th, 2003 Version 1.01d, September 22th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
Read unzip.h for more info Read unzip.h for more info
*/ */
@@ -88,7 +88,7 @@ woven in by Terry Thorsen 1/2003.
const char unz_copyright[] = const char unz_copyright[] =
" unzip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
/* unz_file_info_interntal contain internal info about a file in zipfile*/ /* unz_file_info_interntal contain internal info about a file in zipfile*/
typedef struct unz_file_info_internal_s typedef struct unz_file_info_internal_s
@@ -798,6 +798,7 @@ extern int ZEXPORT unzGoToNextFile (file)
s=(unz_s*)file; s=(unz_s*)file;
if (!s->current_file_ok) if (!s->current_file_ok)
return UNZ_END_OF_LIST_OF_FILE; return UNZ_END_OF_LIST_OF_FILE;
if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
if (s->num_file+1==s->gi.number_entry) if (s->num_file+1==s->gi.number_entry)
return UNZ_END_OF_LIST_OF_FILE; return UNZ_END_OF_LIST_OF_FILE;
@@ -1244,10 +1245,18 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len)
pfile_in_zip_read_info->stream.avail_out = (uInt)len; pfile_in_zip_read_info->stream.avail_out = (uInt)len;
if (len>pfile_in_zip_read_info->rest_read_uncompressed) if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
(!(pfile_in_zip_read_info->raw)))
pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->stream.avail_out =
(uInt)pfile_in_zip_read_info->rest_read_uncompressed; (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
if ((len>pfile_in_zip_read_info->rest_read_compressed+
pfile_in_zip_read_info->stream.avail_in) &&
(pfile_in_zip_read_info->raw))
pfile_in_zip_read_info->stream.avail_out =
(uInt)pfile_in_zip_read_info->rest_read_compressed+
pfile_in_zip_read_info->stream.avail_in;
while (pfile_in_zip_read_info->stream.avail_out>0) while (pfile_in_zip_read_info->stream.avail_out>0)
{ {
if ((pfile_in_zip_read_info->stream.avail_in==0) && if ((pfile_in_zip_read_info->stream.avail_in==0) &&
@@ -1339,6 +1348,9 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len)
*/ */
err=inflate(&pfile_in_zip_read_info->stream,flush); err=inflate(&pfile_in_zip_read_info->stream,flush);
if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
err = Z_DATA_ERROR;
uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
uOutThis = uTotalOutAfter-uTotalOutBefore; uOutThis = uTotalOutAfter-uTotalOutBefore;
@@ -1461,7 +1473,7 @@ extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
if (ZREAD(pfile_in_zip_read_info->z_filefunc, if (ZREAD(pfile_in_zip_read_info->z_filefunc,
pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->filestream,
buf,size_to_read)!=size_to_read) buf,read_now)!=read_now)
return UNZ_ERRNO; return UNZ_ERRNO;
return (int)read_now; return (int)read_now;
@@ -1544,3 +1556,40 @@ extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
*(szComment+s->gi.size_comment)='\0'; *(szComment+s->gi.size_comment)='\0';
return (int)uReadThis; return (int)uReadThis;
} }
/* Additions by RX '2004 */
extern uLong ZEXPORT unzGetOffset (file)
unzFile file;
{
unz_s* s;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
if (!s->current_file_ok)
return 0;
if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
if (s->num_file==s->gi.number_entry)
return 0;
return s->pos_in_central_dir;
}
extern int ZEXPORT unzSetOffset (file, pos)
unzFile file;
uLong pos;
{
unz_s* s;
int err;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz_s*)file;
s->pos_in_central_dir = pos;
s->num_file = s->gi.number_entry; /* hack */
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0);
s->current_file_ok = (err == UNZ_OK);
return err;
}

View File

@@ -1,7 +1,7 @@
/* unzip.h -- IO for uncompress .zip files using zlib /* unzip.h -- IO for uncompress .zip files using zlib
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible. WinZip, InfoZip tools and compatible.
@@ -335,6 +335,16 @@ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
the error code the error code
*/ */
/***************************************************************************/
/* Get the current file offset */
extern uLong ZEXPORT unzGetOffset (unzFile file);
/* Set the current file offset */
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,7 +1,7 @@
/* zip.c -- IO on .zip files using zlib /* zip.c -- IO on .zip files using zlib
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
Read zip.h for more info Read zip.h for more info
*/ */
@@ -77,7 +77,7 @@
#endif #endif
#endif #endif
const char zip_copyright[] = const char zip_copyright[] =
" zip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll"; " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
#define SIZEDATA_INDATABLOCK (4096-(4*4)) #define SIZEDATA_INDATABLOCK (4096-(4*4))
@@ -265,10 +265,19 @@ local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
{ {
unsigned char buf[4]; unsigned char buf[4];
int n; int n;
for (n = 0; n < nbByte; n++) { for (n = 0; n < nbByte; n++)
{
buf[n] = (unsigned char)(x & 0xff); buf[n] = (unsigned char)(x & 0xff);
x >>= 8; x >>= 8;
} }
if (x != 0)
{ /* data overflow - hack for ZIP64 (X Roche) */
for (n = 0; n < nbByte; n++)
{
buf[n] = 0xff;
}
}
if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
return ZIP_ERRNO; return ZIP_ERRNO;
else else
@@ -287,7 +296,16 @@ local void ziplocal_putValue_inmemory (dest, x, nbByte)
buf[n] = (unsigned char)(x & 0xff); buf[n] = (unsigned char)(x & 0xff);
x >>= 8; x >>= 8;
} }
if (x != 0)
{ /* data overflow - hack for ZIP64 */
for (n = 0; n < nbByte; n++)
{
buf[n] = 0xff;
} }
}
}
/****************************************************************************/ /****************************************************************************/
@@ -699,9 +717,9 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
if (comment==NULL) if (comment==NULL)
size_comment = 0; size_comment = 0;
else else
size_comment = strlen(comment); size_comment = (uInt)strlen(comment);
size_filename = strlen(filename); size_filename = (uInt)strlen(filename);
if (zipfi == NULL) if (zipfi == NULL)
zi->ci.dosDate = 0; zi->ci.dosDate = 0;
@@ -1108,7 +1126,7 @@ extern int ZEXPORT zipClose (file, global_comment)
if (global_comment==NULL) if (global_comment==NULL)
size_global_comment = 0; size_global_comment = 0;
else else
size_global_comment = strlen(global_comment); size_global_comment = (uInt)strlen(global_comment);
centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream); centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);

View File

@@ -1,7 +1,7 @@
/* zip.h -- IO for compress .zip files using zlib /* zip.h -- IO for compress .zip files using zlib
Version 1.00, September 10th, 2003 Version 1.01, May 8th, 2004
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2004 Gilles Vollant
This unzip package allow creates .ZIP file, compatible with PKZip 2.04g This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible. WinZip, InfoZip tools and compatible.
@@ -212,7 +212,6 @@ extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
Close the current file in the zipfile Close the current file in the zipfile
*/ */
extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
uLong uncompressed_size, uLong uncompressed_size,
uLong crc32)); uLong crc32));

View File

@@ -10,7 +10,7 @@ unit zlibpas;
interface interface
const const
ZLIB_VERSION = '1.2.1'; ZLIB_VERSION = '1.2.2';
type type
alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
@@ -166,6 +166,7 @@ function deflateEnd; external;
function deflateInit_; external; function deflateInit_; external;
function deflateInit2_; external; function deflateInit2_; external;
function deflateParams; external; function deflateParams; external;
function deflatePrime; external;
function deflateReset; external; function deflateReset; external;
function deflateSetDictionary; external; function deflateSetDictionary; external;
function inflate; external; function inflate; external;

View File

@@ -1,8 +1,8 @@
/* /*
* puff.c * puff.c
* Copyright (C) 2002, 2003 Mark Adler * Copyright (C) 2002-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in puff.h * For conditions of distribution and use, see copyright notice in puff.h
* version 1.7, 3 Mar 2003 * version 1.8, 9 Jan 2004
* *
* puff.c is a simple inflate written to be an unambiguous way to specify the * puff.c is a simple inflate written to be an unambiguous way to specify the
* deflate format. It is not written for speed but rather simplicity. As a * deflate format. It is not written for speed but rather simplicity. As a
@@ -60,6 +60,7 @@
* 1.6 7 Aug 2002 - Minor format changes * 1.6 7 Aug 2002 - Minor format changes
* 1.7 3 Mar 2003 - Added test code for distribution * 1.7 3 Mar 2003 - Added test code for distribution
* - Added zlib-like license * - Added zlib-like license
* 1.8 9 Jan 2004 - Added some comments on no distance codes case
*/ */
#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
@@ -577,6 +578,9 @@ local int fixed(struct state *s)
* block is fewer bits), but it is allowed by the format. So incomplete * block is fewer bits), but it is allowed by the format. So incomplete
* literal/length codes of one symbol should also be permitted. * literal/length codes of one symbol should also be permitted.
* *
* - If there are only literal codes and no lengths, then there are no distance
* codes. This is represented by one distance code with zero bits.
*
* - The list of up to 286 length/literal lengths and up to 30 distance lengths * - The list of up to 286 length/literal lengths and up to 30 distance lengths
* are themselves compressed using Huffman codes and run-length encoding. In * are themselves compressed using Huffman codes and run-length encoding. In
* the list of code lengths, a 0 symbol means no code, a 1..15 symbol means * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means

View File

@@ -1,7 +1,7 @@
/* /*
* untgz.c -- Display contents and extract files from a gzip'd TAR file * untgz.c -- Display contents and extract files from a gzip'd TAR file
* *
* written by "Pedro A. Aranda Guti\irrez" <paag@tid.es> * written by Pedro A. Aranda Gutierrez <paag@tid.es>
* adaptation to Unix by Jean-loup Gailly <jloup@gzip.org> * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
* various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro> * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
*/ */
@@ -28,8 +28,9 @@
# endif # endif
# define mkdir(dirname,mode) _mkdir(dirname) # define mkdir(dirname,mode) _mkdir(dirname)
# ifdef _MSC_VER # ifdef _MSC_VER
# define strdup(str) _strdup(str)
# define access(path,mode) _access(path,mode) # define access(path,mode) _access(path,mode)
# define chmod(path,mode) _chmod(path,mode)
# define strdup(str) _strdup(str)
# endif # endif
#else #else
# include <utime.h> # include <utime.h>
@@ -48,7 +49,21 @@
#define FIFOTYPE '6' /* FIFO special */ #define FIFOTYPE '6' /* FIFO special */
#define CONTTYPE '7' /* reserved */ #define CONTTYPE '7' /* reserved */
/* GNU tar extensions */
#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
#define GNUTYPE_LONGLINK 'K' /* long link name */
#define GNUTYPE_LONGNAME 'L' /* long file name */
#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
#define GNUTYPE_SPARSE 'S' /* sparse file */
#define GNUTYPE_VOLHDR 'V' /* tape/volume header */
/* tar header */
#define BLOCKSIZE 512 #define BLOCKSIZE 512
#define SHORTNAMESIZE 100
struct tar_header struct tar_header
{ /* byte offset */ { /* byte offset */
@@ -71,11 +86,20 @@ struct tar_header
/* 500 */ /* 500 */
}; };
union tar_buffer { union tar_buffer
{
char buffer[BLOCKSIZE]; char buffer[BLOCKSIZE];
struct tar_header header; struct tar_header header;
}; };
struct attr_item
{
struct attr_item *next;
char *fname;
int mode;
time_t time;
};
enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID }; enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
char *TGZfname OF((const char *)); char *TGZfname OF((const char *));
@@ -84,6 +108,9 @@ void TGZnotfound OF((const char *));
int getoct OF((char *, int)); int getoct OF((char *, int));
char *strtime OF((time_t *)); char *strtime OF((time_t *));
int setfiletime OF((char *, time_t)); int setfiletime OF((char *, time_t));
void push_attr OF((struct attr_item **, char *, int, time_t));
void restore_attr OF((struct attr_item **));
int ExprMatch OF((char *, char *)); int ExprMatch OF((char *, char *));
int makedir OF((char *)); int makedir OF((char *));
@@ -221,7 +248,42 @@ int setfiletime (char *fname,time_t ftime)
} }
/* regular expression matching */ /* push file attributes */
void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
{
struct attr_item *item;
item = (struct attr_item *)malloc(sizeof(struct attr_item));
if (item == NULL)
error("Out of memory");
item->fname = strdup(fname);
item->mode = mode;
item->time = time;
item->next = *list;
*list = item;
}
/* restore file attributes */
void restore_attr(struct attr_item **list)
{
struct attr_item *item, *prev;
for (item = *list; item != NULL; )
{
setfiletime(item->fname,item->time);
chmod(item->fname,item->mode);
prev = item;
item = item->next;
free(prev);
}
*list = NULL;
}
/* match regular expression */
#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) #define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
@@ -332,6 +394,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
char fname[BLOCKSIZE]; char fname[BLOCKSIZE];
int tarmode; int tarmode;
time_t tartime; time_t tartime;
struct attr_item *attributes = NULL;
if (action == TGZ_LIST) if (action == TGZ_LIST)
printf(" date time size file\n" printf(" date time size file\n"
@@ -354,14 +417,15 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
/* /*
* If we have to get a tar header * If we have to get a tar header
*/ */
if (getheader == 1) if (getheader >= 1)
{ {
/* /*
* if we met the end of the tar * if we met the end of the tar
* or the end-of-tar block, * or the end-of-tar block,
* we are done * we are done
*/ */
if ((len == 0) || (buffer.header.name[0] == 0)) break; if (len == 0 || buffer.header.name[0] == 0)
break;
tarmode = getoct(buffer.header.mode,8); tarmode = getoct(buffer.header.mode,8);
tartime = (time_t)getoct(buffer.header.mtime,12); tartime = (time_t)getoct(buffer.header.mtime,12);
@@ -371,8 +435,25 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
action = TGZ_INVALID; action = TGZ_INVALID;
} }
strcpy(fname,buffer.header.name); if (getheader == 1)
{
strncpy(fname,buffer.header.name,SHORTNAMESIZE);
if (fname[SHORTNAMESIZE-1] != 0)
fname[SHORTNAMESIZE] = 0;
}
else
{
/*
* The file name is longer than SHORTNAMESIZE
*/
if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
error("bad long name");
getheader = 1;
}
/*
* Act according to the type flag
*/
switch (buffer.header.typeflag) switch (buffer.header.typeflag)
{ {
case DIRTYPE: case DIRTYPE:
@@ -381,7 +462,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
if (action == TGZ_EXTRACT) if (action == TGZ_EXTRACT)
{ {
makedir(fname); makedir(fname);
setfiletime(fname,tartime); push_attr(&attributes,fname,tarmode,tartime);
} }
break; break;
case REGTYPE: case REGTYPE:
@@ -419,6 +500,24 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
} }
getheader = 0; getheader = 0;
break; break;
case GNUTYPE_LONGLINK:
case GNUTYPE_LONGNAME:
remaining = getoct(buffer.header.size,12);
if (remaining < 0 || remaining >= BLOCKSIZE)
{
action = TGZ_INVALID;
break;
}
len = gzread(in, fname, BLOCKSIZE);
if (len < 0)
error(gzerror(in, &err));
if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
{
action = TGZ_INVALID;
break;
}
getheader = 2;
break;
default: default:
if (action == TGZ_LIST) if (action == TGZ_LIST)
printf(" %s <---> %s\n",strtime(&tartime),fname); printf(" %s <---> %s\n",strtime(&tartime),fname);
@@ -433,7 +532,8 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
{ {
if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
{ {
fprintf(stderr,"%s: Error writing %s -- skipping\n",prog,fname); fprintf(stderr,
"%s: Error writing %s -- skipping\n",prog,fname);
fclose(outfile); fclose(outfile);
outfile = NULL; outfile = NULL;
remove(fname); remove(fname);
@@ -450,7 +550,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
fclose(outfile); fclose(outfile);
outfile = NULL; outfile = NULL;
if (action != TGZ_INVALID) if (action != TGZ_INVALID)
setfiletime(fname,tartime); push_attr(&attributes,fname,tarmode,tartime);
} }
} }
@@ -464,6 +564,11 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
} }
} }
/*
* Restore file modes and time stamps
*/
restore_attr(&attributes);
if (gzclose(in) != Z_OK) if (gzclose(in) != Z_OK)
error("failed gzclose"); error("failed gzclose");
@@ -475,7 +580,7 @@ int tar (gzFile in,int action,int arg,int argc,char **argv)
void help(int exitval) void help(int exitval)
{ {
printf("untgz version 0.2\n" printf("untgz version 0.2.1\n"
" using zlib version %s\n\n", " using zlib version %s\n\n",
zlibVersion()); zlibVersion());
printf("Usage: untgz file.tgz extract all files\n" printf("Usage: untgz file.tgz extract all files\n"

View File

@@ -1,4 +1,4 @@
Building instructions for the DLL versions of Zlib 1.21 Building instructions for the DLL versions of Zlib 1.2.x
======================================================= =======================================================
This directory contains projects that build zlib and minizip using This directory contains projects that build zlib and minizip using

View File

@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1,2,1,0 FILEVERSION 1,2,2,2
PRODUCTVERSION 1,2,1,0 PRODUCTVERSION 1,2,2,2
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
@@ -17,7 +17,7 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression library\0" VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.2.1.0\0" VALUE "FileVersion", "1.2.2.2\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlib.dll\0" VALUE "OriginalFilename", "zlib.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"

125
crc32.c
View File

@@ -1,16 +1,24 @@
/* crc32.c -- compute the CRC-32 of a data stream /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
* *
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors * tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results about a factor * instead of four steps with four exclusive-ors. This results in about a
* of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/ */
/* @(#) $Id$ */ /* @(#) $Id$ */
/*
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
protection on the static variables used to control the first-use generation
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32().
*/
#ifdef MAKECRCH #ifdef MAKECRCH
# include <stdio.h> # include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE # ifndef DYNAMIC_CRC_TABLE
@@ -58,12 +66,15 @@
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
local int crc_table_empty = 1; local volatile int crc_table_empty = 1;
local unsigned long FAR crc_table[TBLS][256]; local unsigned long FAR crc_table[TBLS][256];
local void make_crc_table OF((void)); local void make_crc_table OF((void));
#ifdef MAKECRCH #ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *)); local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */ #endif /* MAKECRCH */
local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
/* /*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
@@ -97,8 +108,15 @@ local void make_crc_table()
int n, k; int n, k;
unsigned long poly; /* polynomial exclusive-or pattern */ unsigned long poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */ /* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* See if another task is already doing this (not thread-safe, but better
than nothing -- significantly reduces duration of vulnerability in
case the advice about DYNAMIC_CRC_TABLE is ignored) */
if (first) {
first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL; poly = 0UL;
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
@@ -113,8 +131,8 @@ local void make_crc_table()
} }
#ifdef BYFOUR #ifdef BYFOUR
/* generate crc for each value followed by one, two, and three zeros, and /* generate crc for each value followed by one, two, and three zeros,
then the byte reversal of those as well as the first table */ and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) { for (n = 0; n < 256; n++) {
c = crc_table[0][n]; c = crc_table[0][n];
crc_table[4][n] = REV(c); crc_table[4][n] = REV(c);
@@ -127,6 +145,12 @@ local void make_crc_table()
#endif /* BYFOUR */ #endif /* BYFOUR */
crc_table_empty = 0; crc_table_empty = 0;
}
else { /* not first */
/* wait for the other guy to finish (not efficient, but rare) */
while (crc_table_empty)
;
}
#ifdef MAKECRCH #ifdef MAKECRCH
/* write out CRC tables to crc32.h */ /* write out CRC tables to crc32.h */
@@ -180,7 +204,8 @@ local void write_table(out, table)
const unsigned long FAR * ZEXPORT get_crc_table() const unsigned long FAR * ZEXPORT get_crc_table()
{ {
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table(); if (crc_table_empty)
make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */ #endif /* DYNAMIC_CRC_TABLE */
return (const unsigned long FAR *)crc_table; return (const unsigned long FAR *)crc_table;
} }
@@ -309,3 +334,89 @@ local unsigned long crc32_big(crc, buf, len)
} }
#endif /* BYFOUR */ #endif /* BYFOUR */
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
local unsigned long gf2_matrix_times(mat, vec)
unsigned long *mat;
unsigned long vec;
{
unsigned long sum;
sum = 0;
while (vec) {
if (vec & 1)
sum ^= *mat;
vec >>= 1;
mat++;
}
return sum;
}
/* ========================================================================= */
local void gf2_matrix_square(square, mat)
unsigned long *square;
unsigned long *mat;
{
int n;
for (n = 0; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off_t len2;
{
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
/* degenerate case */
if (len2 == 0)
return crc1;
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1)
crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0)
break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1)
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
}

179
deflate.c
View File

@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm /* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2003 Jean-loup Gailly. * Copyright (C) 1995-2004 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -52,7 +52,7 @@
#include "deflate.h" #include "deflate.h"
const char deflate_copyright[] = const char deflate_copyright[] =
" deflate 1.2.0.8 Copyright 1995-2003 Jean-loup Gailly "; " deflate 1.2.2.2 Copyright 1995-2004 Jean-loup Gailly ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -264,7 +264,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
#endif #endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_RLE) { strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
@@ -274,6 +274,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->strm = strm; s->strm = strm;
s->wrap = wrap; s->wrap = wrap;
s->gzhead = Z_NULL;
s->w_bits = windowBits; s->w_bits = windowBits;
s->w_size = 1 << s->w_bits; s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1; s->w_mask = s->w_size - 1;
@@ -390,6 +391,17 @@ int ZEXPORT deflateReset (strm)
return Z_OK; return Z_OK;
} }
/* ========================================================================= */
int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm;
gz_headerp head;
{
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
if (strm->state->wrap != 2) return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
/* ========================================================================= */ /* ========================================================================= */
int ZEXPORT deflatePrime (strm, bits, value) int ZEXPORT deflatePrime (strm, bits, value)
z_streamp strm; z_streamp strm;
@@ -420,7 +432,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
#else #else
if (level == Z_DEFAULT_COMPRESSION) level = 6; if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif #endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) { if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
func = configuration_table[s->level].func; func = configuration_table[s->level].func;
@@ -548,9 +560,11 @@ int ZEXPORT deflate (strm, flush)
if (s->status == INIT_STATE) { if (s->status == INIT_STATE) {
#ifdef GZIP #ifdef GZIP
if (s->wrap == 2) { if (s->wrap == 2) {
strm->adler = crc32(0L, Z_NULL, 0);
put_byte(s, 31); put_byte(s, 31);
put_byte(s, 139); put_byte(s, 139);
put_byte(s, 8); put_byte(s, 8);
if (s->gzhead == NULL) {
put_byte(s, 0); put_byte(s, 0);
put_byte(s, 0); put_byte(s, 0);
put_byte(s, 0); put_byte(s, 0);
@@ -559,9 +573,34 @@ int ZEXPORT deflate (strm, flush)
put_byte(s, s->level == 9 ? 2 : put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0)); 4 : 0));
put_byte(s, 255); put_byte(s, OS_CODE);
s->status = BUSY_STATE; s->status = BUSY_STATE;
strm->adler = crc32(0L, Z_NULL, 0); }
else {
put_byte(s, (s->gzhead->text ? 1 : 0) +
(s->gzhead->hcrc ? 2 : 0) +
(s->gzhead->extra == Z_NULL ? 0 : 4) +
(s->gzhead->name == Z_NULL ? 0 : 8) +
(s->gzhead->comment == Z_NULL ? 0 : 16)
);
put_byte(s, s->gzhead->time & 0xff);
put_byte(s, (s->gzhead->time >> 8) & 0xff);
put_byte(s, (s->gzhead->time >> 16) & 0xff);
put_byte(s, (s->gzhead->time >> 24) & 0xff);
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, s->gzhead->os & 0xff);
if (s->gzhead->extra != NULL) {
put_byte(s, s->gzhead->extra_len & 0xff);
put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
}
if (s->gzhead->hcrc)
strm->adler = crc32(strm->adler, s->pending_buf,
s->pending);
s->gzindex = 0;
s->status = EXTRA_STATE;
}
} }
else else
#endif #endif
@@ -592,6 +631,110 @@ int ZEXPORT deflate (strm, flush)
strm->adler = adler32(0L, Z_NULL, 0); strm->adler = adler32(0L, Z_NULL, 0);
} }
} }
#ifdef GZIP
if (s->status == EXTRA_STATE) {
if (s->gzhead->extra != NULL) {
int beg = s->pending; /* start of bytes to update crc */
while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size)
break;
}
put_byte(s, s->gzhead->extra[s->gzindex]);
s->gzindex++;
}
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (s->gzindex == s->gzhead->extra_len) {
s->gzindex = 0;
s->status = NAME_STATE;
}
}
else
s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
if (s->gzhead->name != NULL) {
int beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size) {
val = 1;
break;
}
}
val = s->gzhead->name[s->gzindex++];
put_byte(s, val);
} while (val != 0);
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (val == 0) {
s->gzindex = 0;
s->status = COMMENT_STATE;
}
}
else
s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
if (s->gzhead->comment != NULL) {
int beg = s->pending; /* start of bytes to update crc */
int val;
do {
if (s->pending == s->pending_buf_size) {
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
flush_pending(strm);
beg = s->pending;
if (s->pending == s->pending_buf_size) {
val = 1;
break;
}
}
val = s->gzhead->comment[s->gzindex++];
put_byte(s, val);
} while (val != 0);
if (s->gzhead->hcrc && s->pending > beg)
strm->adler = crc32(strm->adler, s->pending_buf + beg,
s->pending - beg);
if (val == 0)
s->status = HCRC_STATE;
}
else
s->status = HCRC_STATE;
}
if (s->status == HCRC_STATE) {
if (s->gzhead->hcrc) {
if (s->pending + 2 > s->pending_buf_size)
flush_pending(strm);
if (s->pending + 2 <= s->pending_buf_size) {
put_byte(s, strm->adler & 0xff);
put_byte(s, (strm->adler >> 8) & 0xff);
strm->adler = crc32(0L, Z_NULL, 0);
s->status = BUSY_STATE;
}
}
else
s->status = BUSY_STATE;
}
#endif
/* Flush as much pending output as possible */ /* Flush as much pending output as possible */
if (s->pending != 0) { if (s->pending != 0) {
@@ -704,7 +847,12 @@ int ZEXPORT deflateEnd (strm)
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
status = strm->state->status; status = strm->state->status;
if (status != INIT_STATE && status != BUSY_STATE && if (status != INIT_STATE &&
status != EXTRA_STATE &&
status != NAME_STATE &&
status != COMMENT_STATE &&
status != HCRC_STATE &&
status != BUSY_STATE &&
status != FINISH_STATE) { status != FINISH_STATE) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
@@ -744,12 +892,12 @@ int ZEXPORT deflateCopy (dest, source)
ss = source->state; ss = source->state;
*dest = *source; zmemcpy(dest, source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR; if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds; dest->state = (struct internal_state FAR *) ds;
*ds = *ss; zmemcpy(ds, ss, sizeof(deflate_state));
ds->strm = dest; ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
@@ -909,7 +1057,12 @@ local uInt longest_match(s, cur_match)
match = s->window + cur_match; match = s->window + cur_match;
/* Skip to next match if the match length cannot increase /* Skip to next match if the match length cannot increase
* or if the match length is less than 2: * or if the match length is less than 2. Note that the checks below
* for insufficient lookahead only occur occasionally for performance
* reasons. Therefore uninitialized memory will be accessed, and
* conditional jumps will be made that depend on those values.
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/ */
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use /* This code assumes sizeof(unsigned short) == 2. Do not use
@@ -1309,12 +1462,12 @@ local block_state deflate_fast(s, flush)
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
#ifdef FASTEST #ifdef FASTEST
if ((s->strategy < Z_HUFFMAN_ONLY) || if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) { (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
s->match_length = longest_match_fast (s, hash_head); s->match_length = longest_match_fast (s, hash_head);
} }
#else #else
if (s->strategy < Z_HUFFMAN_ONLY) { if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head); s->match_length = longest_match_fast (s, hash_head);
@@ -1418,7 +1571,7 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match * of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file). * of the string with itself at the start of the input file).
*/ */
if (s->strategy < Z_HUFFMAN_ONLY) { if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head); s->match_length = longest_match_fast (s, hash_head);

View File

@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995-2002 Jean-loup Gailly * Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -49,6 +49,10 @@
/* All codes must not exceed MAX_BITS bits */ /* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42 #define INIT_STATE 42
#define EXTRA_STATE 69
#define NAME_STATE 73
#define COMMENT_STATE 91
#define HCRC_STATE 103
#define BUSY_STATE 113 #define BUSY_STATE 113
#define FINISH_STATE 666 #define FINISH_STATE 666
/* Stream status */ /* Stream status */
@@ -95,7 +99,8 @@ typedef struct internal_state {
Bytef *pending_out; /* next pending byte to output to the stream */ Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */ int pending; /* nb of bytes in the pending buffer */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
Byte data_type; /* UNKNOWN, BINARY or ASCII */ gz_headerp gzhead; /* gzip header information to write */
int gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */ int last_flush; /* value of flush param for previous deflate call */

View File

@@ -1,5 +1,5 @@
/* example.c -- usage example of the zlib compression library /* example.c -- usage example of the zlib compression library
* Copyright (C) 1995-2003 Jean-loup Gailly. * Copyright (C) 1995-2004 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -11,8 +11,6 @@
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
#if defined(VMS) || defined(RISCOS) #if defined(VMS) || defined(RISCOS)

29
examples/README.examples Normal file
View File

@@ -0,0 +1,29 @@
This directory contains examples of the use of zlib.
fitblk.c
compress just enough input to nearly fill a requested output size
- zlib isn't designed to do this, but fitblk does it anyway
gzappend.c
append to a gzip file
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of deflatePrime() to start at any bit
gzjoin.c
join gzip files without recalculating the crc or recompressing
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of crc32_combine()
gzlog.c
gzlog.h
efficiently maintain a message log file in gzip format
- illustrates use of raw deflate and Z_SYNC_FLUSH
- illustrates use of gzip header extra field
zlib_how.html
painfully comprehensive description of zpipe.c (see below)
- describes in excruciating detail the use of deflate() and inflate()
zpipe.c
reads and writes zlib streams from stdin to stdout
- illustrates the proper use of deflate() and inflate()

235
examples/fitblk.c Normal file
View File

@@ -0,0 +1,235 @@
/* fitblk.c: example of fitting compressed output to a specified size
Not copyrighted -- provided to the public domain
Version 1.1 25 November 2004 Mark Adler */
/* Version history:
1.0 24 Nov 2004 First version
1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
Use fixed-size, stack-allocated raw buffers
Simplify code moving compression to subroutines
Use assert() for internal errors
Add detailed description of approach
*/
/* Approach to just fitting a requested compressed size:
fitblk performs three compression passes on a portion of the input
data in order to determine how much of that input will compress to
nearly the requested output block size. The first pass generates
enough deflate blocks to produce output to fill the requested
output size plus a specfied excess amount (see the EXCESS define
below). The last deflate block may go quite a bit past that, but
is discarded. The second pass decompresses and recompresses just
the compressed data that fit in the requested plus excess sized
buffer. The deflate process is terminated after that amount of
input, which is less than the amount consumed on the first pass.
The last deflate block of the result will be of a comparable size
to the final product, so that the header for that deflate block and
the compression ratio for that block will be about the same as in
the final product. The third compression pass decompresses the
result of the second step, but only the compressed data up to the
requested size minus an amount to allow the compressed stream to
complete (see the MARGIN define below). That will result in a
final compressed stream whose length is less than or equal to the
requested size. Assuming sufficient input and a requested size
greater than a few hundred bytes, the shortfall will typically be
less than ten bytes.
If the input is short enough that the first compression completes
before filling the requested output size, then that compressed
stream is return with no recompression.
EXCESS is chosen to be just greater than the shortfall seen in a
two pass approach similar to the above. That shortfall is due to
the last deflate block compressing more efficiently with a smaller
header on the second pass. EXCESS is set to be large enough so
that there is enough uncompressed data for the second pass to fill
out the requested size, and small enough so that the final deflate
block of the second pass will be close in size to the final deflate
block of the third and final pass. MARGIN is chosen to be just
large enough to assure that the final compression has enough room
to complete in all cases.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "zlib.h"
#define local static
/* print nastygram and leave */
local void quit(char *why)
{
fprintf(stderr, "fitblk abort: %s\n", why);
exit(1);
}
#define RAWLEN 4096 /* intermediate uncompressed buffer size */
/* compress from file to def until provided buffer is full or end of
input reached; return last deflate() return value, or Z_ERRNO if
there was read error on the file */
local int partcompress(FILE *in, z_streamp def)
{
int ret, flush;
char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
def->avail_in = fread(raw, 1, RAWLEN, in);
if (ferror(in))
return Z_ERRNO;
def->next_in = raw;
if (feof(in))
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (def->avail_out != 0 && flush == Z_NO_FLUSH);
return ret;
}
/* recompress from inf's input to def's output; the input for inf and
the output for def are set in those structures before calling;
return last deflate() return value, or Z_MEM_ERROR if inflate()
was not able to allocate enough memory when it needed to */
local int recompress(z_streamp inf, z_streamp def)
{
int ret, flush;
char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
/* decompress */
inf->avail_out = RAWLEN;
inf->next_out = raw;
ret = inflate(inf, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
ret != Z_NEED_DICT);
if (ret == Z_MEM_ERROR)
return ret;
/* compress what was decompresed until done or no room */
def->avail_in = RAWLEN - inf->avail_out;
def->next_in = raw;
if (inf->avail_out != 0)
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (ret != Z_STREAM_END && def->avail_out != 0);
return ret;
}
#define EXCESS 256 /* empirically determined stream overage */
#define MARGIN 8 /* amount to back off for completion */
/* compress from stdin to fixed-size block on stdout */
int main(int argc, char **argv)
{
int ret; /* return code */
unsigned size; /* requested fixed output block size */
unsigned have; /* bytes written by deflate() call */
char *blk; /* intermediate and final stream */
char *tmp; /* close to desired size stream */
z_stream def, inf; /* zlib deflate and inflate states */
/* get requested output size */
if (argc != 2)
quit("need one argument: size of output block");
ret = strtol(argv[1], argv + 1, 10);
if (argv[1][0] != 0)
quit("argument must be a number");
if (ret < 8) /* 8 is minimum zlib stream size */
quit("need positive size of 8 or greater");
size = (unsigned)ret;
/* allocate memory for buffers and compression engine */
blk = malloc(size + EXCESS);
def.zalloc = Z_NULL;
def.zfree = Z_NULL;
def.opaque = Z_NULL;
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK || blk == NULL)
quit("out of memory");
/* compress from stdin until output full, or no more input */
def.avail_out = size + EXCESS;
def.next_out = blk;
ret = partcompress(stdin, &def);
if (ret == Z_ERRNO)
quit("error reading input");
/* if it all fit, then size was undersubscribed -- done! */
if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
/* write block to stdout */
have = size + EXCESS - def.avail_out;
ret = fwrite(blk, 1, have, stdout);
if (ret != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (all input)\n",
size - have, size);
return 0;
}
/* it didn't all fit -- set up for recompression */
inf.zalloc = Z_NULL;
inf.zfree = Z_NULL;
inf.opaque = Z_NULL;
inf.avail_in = 0;
inf.next_in = Z_NULL;
ret = inflateInit(&inf);
tmp = malloc(size + EXCESS);
if (ret != Z_OK || tmp == NULL)
quit("out of memory");
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do first recompression close to the right amount */
inf.avail_in = size + EXCESS;
inf.next_in = blk;
def.avail_out = size + EXCESS;
def.next_out = tmp;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
/* set up for next reocmpression */
ret = inflateReset(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do second and final recompression (third compression) */
inf.avail_in = size - MARGIN; /* assure stream will complete */
inf.next_in = tmp;
def.avail_out = size;
def.next_out = blk;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
/* done -- write block to stdout */
have = size - def.avail_out;
ret = fwrite(blk, 1, have, stdout);
if (ret != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
free(tmp);
ret = inflateEnd(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (%lu input)\n",
size - have, size, def.total_in);
return 0;
}

View File

@@ -48,10 +48,10 @@
unfriendly behavior that if gzappend fails, the gzip file is corrupted. unfriendly behavior that if gzappend fails, the gzip file is corrupted.
This program was written to illustrate the use of the new Z_BLOCK option of This program was written to illustrate the use of the new Z_BLOCK option of
zlib 1.2.1's inflate() function. This option returns from inflate() at each zlib 1.2.x's inflate() function. This option returns from inflate() at each
block boundary to facilitate locating and modifying the last block bit at block boundary to facilitate locating and modifying the last block bit at
the start of the final deflate block. Also whether using Z_BLOCK or not, the start of the final deflate block. Also whether using Z_BLOCK or not,
another required feature of zlib 1.2.1 is that inflate() now provides the another required feature of zlib 1.2.x is that inflate() now provides the
number of unusued bits in the last input byte used. gzappend will not work number of unusued bits in the last input byte used. gzappend will not work
with versions of zlib earlier than 1.2.1. with versions of zlib earlier than 1.2.1.

447
examples/gzjoin.c Normal file
View File

@@ -0,0 +1,447 @@
/* gzjoin -- command to join gzip files into one gzip file
Copyright (C) 2004 Mark Adler, all rights reserved
version 1.0, 11 Dec 2004
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
* Change history:
*
* 1.0 11 Dec 2004 - First version
*/
/*
gzjoin takes one or more gzip files on the command line and writes out a
single gzip file that will uncompress to the concatenation of the
uncompressed data from the individual gzip files. gzjoin does this without
having to recompress any of the data and without having to calculate a new
crc32 for the concatenated uncompressed data. gzjoin does however have to
decompress all of the input data in order to find the bits in the compressed
data that need to be modified to concatenate the streams.
gzjoin does not do an integrity check on the input gzip files other than
checking the gzip header and decompressing the compressed data. They are
otherwise assumed to be complete and correct.
Each joint between gzip files removes at least 18 bytes of previous trailer
and subsequent header, and inserts an average of about three bytes to the
compressed data in order to connect the streams. The output gzip file
has a minimal ten-byte gzip header with no file name or modification time.
This program was written to illustrate the use of the Z_BLOCK option of
inflate() and the crc32_combine() function. gzjoin will not compile with
versions of zlib earlier than 1.2.3.
*/
#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
#include <stdlib.h> /* exit(), malloc(), free() */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close(), read(), lseek() */
#include "zlib.h"
/* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
#define local static
/* exit with an error (return a value to allow use in an expression) */
local int bail(char *why1, char *why2)
{
fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
exit(1);
return 0;
}
/* -- simple buffered file input with access to the buffer -- */
#define CHUNK 32768 /* must be a power of two and fit in unsigned */
/* bin buffered input file type */
typedef struct {
char *name; /* name of file for error messages */
int fd; /* file descriptor */
unsigned left; /* bytes remaining at next */
unsigned char *next; /* next byte to read */
unsigned char *buf; /* allocated buffer of length CHUNK */
} bin;
/* close a buffered file and free allocated memory */
local void bclose(bin *in)
{
if (in != NULL) {
if (in->fd != -1)
close(in->fd);
if (in->buf != NULL)
free(in->buf);
free(in);
}
}
/* open a buffered file for input, return a pointer to type bin, or NULL on
failure */
local bin *bopen(char *name)
{
bin *in;
in = malloc(sizeof(bin));
if (in == NULL)
return NULL;
in->buf = malloc(CHUNK);
in->fd = open(name, O_RDONLY, 0);
if (in->buf == NULL || in->fd == -1) {
bclose(in);
return NULL;
}
in->left = 0;
in->next = in->buf;
in->name = name;
return in;
}
/* load buffer from file, return -1 on read error, 0 or 1 on success, with
1 indicating that end-of-file was reached */
local int bload(bin *in)
{
ssize_t len;
if (in == NULL)
return -1;
if (in->left != 0)
return 0;
in->next = in->buf;
do {
len = read(in->fd, in->buf + in->left, CHUNK - in->left);
if (len < 0)
return -1;
in->left += (unsigned)len;
} while (len != 0 && in->left < CHUNK);
return len == 0 ? 1 : 0;
}
/* get a byte from the file, bail if end of file */
#define bget(in) (in->left ? 0 : bload(in), \
in->left ? (in->left--, *(in->next)++) : \
bail("unexpected end of file on ", in->name))
/* get a four-byte little-endian unsigned integer from file */
local unsigned long bget4(bin *in)
{
unsigned long val;
val = bget(in);
val += (unsigned long)(bget(in)) << 8;
val += (unsigned long)(bget(in)) << 16;
val += (unsigned long)(bget(in)) << 24;
return val;
}
/* skip bytes in file */
local void bskip(bin *in, unsigned skip)
{
/* check pointer */
if (in == NULL)
return;
/* easy case -- skip bytes in buffer */
if (skip <= in->left) {
in->left -= skip;
in->next += skip;
return;
}
/* skip what's in buffer, discard buffer contents */
skip -= in->left;
in->left = 0;
/* seek past multiples of CHUNK bytes */
if (skip > CHUNK) {
unsigned left;
left = skip & (CHUNK - 1);
if (left == 0) {
/* exact number of chunks: seek all the way minus one byte to check
for end-of-file with a read */
lseek(in->fd, skip - 1, SEEK_CUR);
if (read(in->fd, in->buf, 1) != 1)
bail("unexpected end of file on ", in->name);
return;
}
/* skip the integral chunks, update skip with remainder */
lseek(in->fd, skip - left, SEEK_CUR);
skip = left;
}
/* read more input and skip remainder */
bload(in);
if (skip > in->left)
bail("unexpected end of file on ", in->name);
in->left -= skip;
in->next += skip;
}
/* -- end of buffered input functions -- */
/* skip the gzip header from file in */
local void gzhead(bin *in)
{
int flags;
/* verify gzip magic header and compression method */
if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
bail(in->name, " is not a valid gzip file");
/* get and verify flags */
flags = bget(in);
if ((flags & 0xe0) != 0)
bail("unknown reserved bits set in ", in->name);
/* skip modification time, extra flags, and os */
bskip(in, 6);
/* skip extra field if present */
if (flags & 4) {
unsigned len;
len = bget(in);
len += (unsigned)(bget(in)) << 8;
bskip(in, len);
}
/* skip file name if present */
if (flags & 8)
while (bget(in) != 0)
;
/* skip comment if present */
if (flags & 16)
while (bget(in) != 0)
;
/* skip header crc if present */
if (flags & 2)
bskip(in, 2);
}
/* write a four-byte little-endian unsigned integer to out */
local void put4(unsigned long val, FILE *out)
{
putc(val & 0xff, out);
putc((val >> 8) & 0xff, out);
putc((val >> 16) & 0xff, out);
putc((val >> 24) & 0xff, out);
}
/* Load up zlib stream from buffered input, bail if end of file */
local void zpull(z_streamp strm, bin *in)
{
if (in->left == 0)
bload(in);
if (in->left == 0)
bail("unexpected end of file on ", in->name);
strm->avail_in = in->left;
strm->next_in = in->next;
}
/* Write header for gzip file to out and initialize trailer. */
local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
{
fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
*crc = crc32(0L, Z_NULL, 0);
*tot = 0;
}
/* Copy the compressed data from name, zeroing the last block bit of the last
block if clr is true, and adding empty blocks as needed to get to a byte
boundary. If clr is false, then the last block becomes the last block of
the output, and the gzip trailer is written. crc and tot maintains the
crc and length (modulo 2^32) of the output for the trailer. The resulting
gzip file is written to out. gzinit() must be called before the first call
of gzcopy() to write the gzip header and to initialize crc and tot. */
local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
FILE *out)
{
int ret; /* return value from zlib functions */
int pos; /* where the "last block" bit is in byte */
int last; /* true if processing the last block */
bin *in; /* buffered input file */
unsigned char *start; /* start of compressed data in buffer */
unsigned char *junk; /* buffer for uncompressed data -- discarded */
z_off_t len; /* length of uncompressed data (support > 4 GB) */
z_stream strm; /* zlib inflate stream */
/* open gzip file and skip header */
in = bopen(name);
if (in == NULL)
bail("could not open ", name);
gzhead(in);
/* allocate buffer for uncompressed data and initialize raw inflate
stream */
junk = malloc(CHUNK);
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15);
if (junk == NULL || ret != Z_OK)
bail("out of memory", "");
/* inflate and copy compressed data, clear last-block bit if requested */
len = 0;
zpull(&strm, in);
start = strm.next_in;
last = start[0] & 1;
if (last && clr)
start[0] &= ~1;
strm.avail_out = 0;
for (;;) {
/* if input used and output done, write used input and get more */
if (strm.avail_in == 0 && strm.avail_out != 0) {
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
/* decompress -- return early when end-of-block reached */
strm.avail_out = CHUNK;
strm.next_out = junk;
ret = inflate(&strm, Z_BLOCK);
switch (ret) {
case Z_MEM_ERROR:
bail("out of memory", "");
case Z_DATA_ERROR:
bail("invalid compressed data in ", in->name);
}
/* update length of uncompressed data */
len += CHUNK - strm.avail_out;
/* check for block boundary (only get this when block copied out) */
if (strm.data_type & 128) {
/* if that was the last block, then done */
if (last)
break;
/* number of unused bits in last byte */
pos = strm.data_type & 7;
/* find the next last-block bit */
if (pos != 0) {
/* next last-block bit is in last used byte */
pos = 0x100 >> pos;
last = strm.next_in[-1] & pos;
if (last && clr)
strm.next_in[-1] &= ~pos;
}
else {
/* next last-block bit is in next unused byte */
if (strm.avail_in == 0) {
/* don't have that byte yet -- get it */
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
last = strm.next_in[0] & 1;
if (last && clr)
strm.next_in[0] &= ~1;
}
}
}
/* update buffer with unused input */
in->left = strm.avail_in;
in->next = strm.next_in;
/* copy used input, write empty blocks to get to byte boundary */
pos = strm.data_type & 7;
fwrite(start, 1, in->next - start - 1, out);
last = in->next[-1];
if (pos == 0 || !clr)
/* already at byte boundary, or last file: write last byte */
putc(last, out);
else {
/* append empty blocks to last byte */
last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
if (pos & 1) {
/* odd -- append an empty stored block */
putc(last, out);
if (pos == 1)
putc(0, out); /* two more bits in block header */
fwrite("\0\0\xff\xff", 1, 4, out);
}
else {
/* even -- append 1, 2, or 3 empty fixed blocks */
switch (pos) {
case 6:
putc(last | 8, out);
last = 0;
case 4:
putc(last | 0x20, out);
last = 0;
case 2:
putc(last | 0x80, out);
putc(0, out);
}
}
}
/* update crc and tot */
*crc = crc32_combine(*crc, bget4(in), len);
*tot += (unsigned long)len;
/* clean up */
inflateEnd(&strm);
free(junk);
bclose(in);
/* write trailer if this is the last gzip file */
if (!clr) {
put4(*crc, out);
put4(*tot, out);
}
}
/* join the gzip files on the command line, write result to stdout */
int main(int argc, char **argv)
{
unsigned long crc, tot; /* running crc and total uncompressed length */
/* skip command name */
argc--;
argv++;
/* show usage if no arguments */
if (argc == 0) {
fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
stderr);
return 0;
}
/* join gzip files on command line and write to stdout */
gzinit(&crc, &tot, stdout);
while (argc--)
gzcopy(*argv++, argc, &crc, &tot, stdout);
/* done */
return 0;
}

413
examples/gzlog.c Normal file
View File

@@ -0,0 +1,413 @@
/*
* gzlog.c
* Copyright (C) 2004 Mark Adler
* For conditions of distribution and use, see copyright notice in gzlog.h
* version 1.0, 26 Nov 2004
*
*/
#include <string.h> /* memcmp() */
#include <stdlib.h> /* malloc(), free(), NULL */
#include <sys/types.h> /* size_t, off_t */
#include <unistd.h> /* read(), close(), sleep(), ftruncate(), */
/* lseek() */
#include <fcntl.h> /* open() */
#include <sys/file.h> /* flock() */
#include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */
#include "gzlog.h" /* interface */
#define local static
/* log object structure */
typedef struct {
int id; /* object identifier */
int fd; /* log file descriptor */
off_t extra; /* offset of extra "ap" subfield */
off_t mark_off; /* offset of marked data */
off_t last_off; /* offset of last block */
unsigned long crc; /* uncompressed crc */
unsigned long len; /* uncompressed length (modulo 2^32) */
unsigned stored; /* length of current stored block */
} gz_log;
#define GZLOGID 19334 /* gz_log object identifier */
#define LOCK_RETRY 1 /* retry lock once a second */
#define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */
/* acquire a lock on a file */
local int lock(int fd)
{
int patience;
/* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */
patience = LOCK_PATIENCE;
do {
if (flock(fd, LOCK_EX + LOCK_NB) == 0)
return 0;
(void)sleep(LOCK_RETRY);
patience -= LOCK_RETRY;
} while (patience > 0);
/* we've run out of patience -- give up */
return -1;
}
/* release lock */
local void unlock(int fd)
{
(void)flock(fd, LOCK_UN);
}
/* release a log object */
local void log_clean(gz_log *log)
{
unlock(log->fd);
(void)close(log->fd);
free(log);
}
/* read an unsigned long from a byte buffer little-endian */
local unsigned long make_ulg(unsigned char *buf)
{
int n;
unsigned long val;
val = (unsigned long)(*buf++);
for (n = 8; n < 32; n += 8)
val += (unsigned long)(*buf++) << n;
return val;
}
/* read an off_t from a byte buffer little-endian */
local off_t make_off(unsigned char *buf)
{
int n;
off_t val;
val = (off_t)(*buf++);
for (n = 8; n < 64; n += 8)
val += (off_t)(*buf++) << n;
return val;
}
/* write an unsigned long little-endian to byte buffer */
local void dice_ulg(unsigned long val, unsigned char *buf)
{
int n;
for (n = 0; n < 4; n++) {
*buf++ = val & 0xff;
val >>= 8;
}
}
/* write an off_t little-endian to byte buffer */
local void dice_off(off_t val, unsigned char *buf)
{
int n;
for (n = 0; n < 8; n++) {
*buf++ = val & 0xff;
val >>= 8;
}
}
/* initial, empty gzip file for appending */
local char empty_gz[] = {
0x1f, 0x8b, /* magic gzip id */
8, /* compression method is deflate */
4, /* there is an extra field */
0, 0, 0, 0, /* no modification time provided */
0, 0xff, /* no extra flags, no OS */
20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */
32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */
32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */
1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
0, 0, 0, 0, /* crc */
0, 0, 0, 0 /* uncompressed length */
};
/* initialize a log object with locking */
void *gzlog_open(char *path)
{
unsigned xlen;
unsigned char temp[20];
unsigned sub_len;
int good;
gz_log *log;
/* allocate log structure */
log = malloc(sizeof(gz_log));
if (log == NULL)
return NULL;
log->id = GZLOGID;
/* open file, creating it if necessary, and locking it */
log->fd = open(path, O_RDWR | O_CREAT, 0600);
if (log->fd < 0) {
free(log);
return NULL;
}
if (lock(log->fd)) {
close(log->fd);
free(log);
return NULL;
}
/* if file is empty, write new gzip stream */
if (lseek(log->fd, 0, SEEK_END) == 0) {
if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) {
log_clean(log);
return NULL;
}
}
/* check gzip header */
(void)lseek(log->fd, 0, SEEK_SET);
if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f ||
temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) {
log_clean(log);
return NULL;
}
/* process extra field to find "ap" sub-field */
xlen = temp[10] + (temp[11] << 8);
good = 0;
while (xlen) {
if (xlen < 4 || read(log->fd, temp, 4) != 4)
break;
sub_len = temp[2];
sub_len += temp[3] << 8;
xlen -= 4;
if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) {
good = 1;
break;
}
if (xlen < sub_len)
break;
(void)lseek(log->fd, sub_len, SEEK_CUR);
xlen -= sub_len;
}
if (!good) {
log_clean(log);
return NULL;
}
/* read in "ap" sub-field */
log->extra = lseek(log->fd, 0, SEEK_CUR);
if (read(log->fd, temp, 16) != 16) {
log_clean(log);
return NULL;
}
log->mark_off = make_off(temp);
log->last_off = make_off(temp + 8);
/* get crc, length of gzip file */
(void)lseek(log->fd, log->last_off, SEEK_SET);
if (read(log->fd, temp, 13) != 13 ||
memcmp(temp, "\001\000\000\377\377", 5) != 0) {
log_clean(log);
return NULL;
}
log->crc = make_ulg(temp + 5);
log->len = make_ulg(temp + 9);
/* set up to write over empty last block */
(void)lseek(log->fd, log->last_off + 5, SEEK_SET);
log->stored = 0;
return (void *)log;
}
/* maximum amount to put in a stored block before starting a new one */
#define MAX_BLOCK 16384
/* write a block to a log object */
int gzlog_write(void *obj, char *data, size_t len)
{
size_t some;
unsigned char temp[5];
gz_log *log;
/* check object */
log = (gz_log *)obj;
if (log == NULL || log->id != GZLOGID)
return 1;
/* write stored blocks until all of the input is written */
do {
some = MAX_BLOCK - log->stored;
if (some > len)
some = len;
if (write(log->fd, data, some) != some)
return 1;
log->crc = crc32(log->crc, data, some);
log->len += some;
len -= some;
data += some;
log->stored += some;
/* if the stored block is full, end it and start another */
if (log->stored == MAX_BLOCK) {
(void)lseek(log->fd, log->last_off, SEEK_SET);
temp[0] = 0;
dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
temp + 1);
if (write(log->fd, temp, 5) != 5)
return 1;
log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
(void)lseek(log->fd, 5, SEEK_CUR);
log->stored = 0;
}
} while (len);
return 0;
}
/* recompress the remaining stored deflate data in place */
local int recomp(gz_log *log)
{
z_stream strm;
size_t len, max;
unsigned char *in;
unsigned char *out;
unsigned char temp[16];
/* allocate space and read it all in (it's around 1 MB) */
len = log->last_off - log->mark_off;
max = len + (len >> 12) + (len >> 14) + 11;
out = malloc(max);
if (out == NULL)
return 1;
in = malloc(len);
if (in == NULL) {
free(out);
return 1;
}
(void)lseek(log->fd, log->mark_off, SEEK_SET);
if (read(log->fd, in, len) != len) {
free(in);
free(out);
return 1;
}
/* recompress in memory, decoding stored data as we go */
/* note: this assumes that unsigned is four bytes or more */
/* consider not making that assumption */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8,
Z_DEFAULT_STRATEGY) != Z_OK) {
free(in);
free(out);
return 1;
}
strm.next_in = in;
strm.avail_out = max;
strm.next_out = out;
while (len >= 5) {
if (strm.next_in[0] != 0)
break;
strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8);
strm.next_in += 5;
len -= 5;
if (strm.avail_in != 0) {
if (len < strm.avail_in)
break;
len -= strm.avail_in;
(void)deflate(&strm, Z_NO_FLUSH);
if (strm.avail_in != 0 || strm.avail_out == 0)
break;
}
}
(void)deflate(&strm, Z_SYNC_FLUSH);
(void)deflateEnd(&strm);
free(in);
if (len != 0 || strm.avail_out == 0) {
free(out);
return 1;
}
/* overwrite stored data with compressed data */
(void)lseek(log->fd, log->mark_off, SEEK_SET);
len = max - strm.avail_out;
if (write(log->fd, out, len) != len) {
free(out);
return 1;
}
free(out);
/* write last empty block, crc, and length */
log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR);
temp[0] = 1;
dice_ulg(0xffffL << 16, temp + 1);
dice_ulg(log->crc, temp + 5);
dice_ulg(log->len, temp + 9);
if (write(log->fd, temp, 13) != 13)
return 1;
/* truncate file to discard remaining stored data and old trailer */
ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR));
/* update extra field to point to new last empty block */
(void)lseek(log->fd, log->extra, SEEK_SET);
dice_off(log->mark_off, temp);
dice_off(log->last_off, temp + 8);
if (write(log->fd, temp, 16) != 16)
return 1;
return 0;
}
/* maximum accumulation of stored blocks before compressing */
#define MAX_STORED 1048576
/* close log object */
int gzlog_close(void *obj)
{
unsigned char temp[8];
gz_log *log;
/* check object */
log = (gz_log *)obj;
if (log == NULL || log->id != GZLOGID)
return 1;
/* go to start of most recent block being written */
(void)lseek(log->fd, log->last_off, SEEK_SET);
/* if some stuff was put there, update block */
if (log->stored) {
temp[0] = 0;
dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
temp + 1);
if (write(log->fd, temp, 5) != 5)
return 1;
log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
}
/* write last block (empty) */
if (write(log->fd, "\001\000\000\377\377", 5) != 5)
return 1;
/* write updated crc and uncompressed length */
dice_ulg(log->crc, temp);
dice_ulg(log->len, temp + 4);
if (write(log->fd, temp, 8) != 8)
return 1;
/* put offset of that last block in gzip extra block */
(void)lseek(log->fd, log->extra + 8, SEEK_SET);
dice_off(log->last_off, temp);
if (write(log->fd, temp, 8) != 8)
return 1;
/* if more than 1 MB stored, then time to compress it */
if (log->last_off - log->mark_off > MAX_STORED) {
if (recomp(log))
return 1;
}
/* unlock and close file */
log_clean(log);
return 0;
}

58
examples/gzlog.h Normal file
View File

@@ -0,0 +1,58 @@
/* gzlog.h
Copyright (C) 2004 Mark Adler, all rights reserved
version 1.0, 26 Nov 2004
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
The gzlog object allows writing short messages to a gzipped log file,
opening the log file locked for small bursts, and then closing it. The log
object works by appending stored data to the gzip file until 1 MB has been
accumulated. At that time, the stored data is compressed, and replaces the
uncompressed data in the file. The log file is truncated to its new size at
that time. After closing, the log file is always valid gzip file that can
decompressed to recover what was written.
A gzip header "extra" field contains two file offsets for appending. The
first points to just after the last compressed data. The second points to
the last stored block in the deflate stream, which is empty. All of the
data between those pointers is uncompressed.
*/
/* Open a gzlog object, creating the log file if it does not exist. Return
NULL on error. Note that gzlog_open() could take a long time to return if
there is difficulty in locking the file. */
void *gzlog_open(char *path);
/* Write to a gzlog object. Return non-zero on error. This function will
simply write data to the file uncompressed. Compression of the data
will not occur until gzlog_close() is called. It is expected that
gzlog_write() is used for a short message, and then gzlog_close() is
called. If a large amount of data is to be written, then the application
should write no more than 1 MB at a time with gzlog_write() before
calling gzlog_close() and then gzlog_open() again. */
int gzlog_write(void *log, char *data, size_t len);
/* Close a gzlog object. Return non-zero on error. The log file is locked
until this function is called. This function will compress stored data
at the end of the gzip file if at least 1 MB has been accumulated. Note
that the file will not be a valid gzip file until this function completes.
*/
int gzlog_close(void *log);

522
examples/zlib_how.html Normal file
View File

@@ -0,0 +1,522 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>zlib Usage Example</title>
<!-- Copyright (c) 2004 Mark Adler. -->
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
<h2 align="center"> zlib Usage Example </h2>
We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
Users wonder when they should provide more input, when they should use more output,
what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
so on. So for those who have read <tt>zlib.h</tt> (a few times), and
would like further edification, below is an annotated example in C of simple routines to compress and decompress
from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively. The
annotations are interspersed between lines of the code. So please read between the lines.
We hope this helps explain some of the intricacies of <em>zlib</em>.
<p>
Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
<pre><b>
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.2 9 November 2004 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
*/
</b></pre><!-- -->
We now include the header files for the required definitions. From
<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
<tt>fputs()</tt> for error messages. From <tt>string.h</tt> we use
<tt>strcmp()</tt> for command line argument processing.
From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
From <tt>zlib.h</tt>
we use the basic compression functions <tt>deflateInit()</tt>,
<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
<tt>inflateEnd()</tt>.
<pre><b>
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;assert.h&gt;
#include "zlib.h"
</b></pre><!-- -->
<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
from the <em>zlib</em> routines. Larger buffer sizes would be more efficient,
especially for <tt>inflate()</tt>. If the memory is available, buffers sizes
on the order of 128K or 256K bytes should be used.
<pre><b>
#define CHUNK 16384
</b></pre><!-- -->
The <tt>def()</tt> routine compresses data from an input file to an output file. The output data
will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
formats. The <em>zlib</em> format has a very small header of only two bytes to identify it as
a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
check value to verify the integrity of the uncompressed data after decoding.
<pre><b>
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
</b></pre>
Here are the local variables for <tt>def()</tt>. <tt>ret</tt> will be used for <em>zlib</em>
return codes. <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
which is either no flushing, or flush to completion after the end of the input file is reached.
<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>. The <tt>strm</tt> structure
is used to pass information to and from the <em>zlib</em> routines, and to maintain the
<tt>deflate()</tt> state. <tt>in</tt> and <tt>out</tt> are the input and output buffers for
<tt>deflate()</tt>.
<pre><b>
int ret, flush;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
</b></pre><!-- -->
The first thing we do is to initialize the <em>zlib</em> state for compression using
<tt>deflateInit()</tt>. This must be done before the first use of <tt>deflate()</tt>.
The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
structure must be initialized before calling <tt>deflateInit()</tt>. Here they are
set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
the default memory allocation routines. An application may also choose to provide
custom memory allocation routines here. <tt>deflateInit()</tt> will allocate on the
order of 256K bytes for the internal state.
(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
<p>
<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
the compression level, which is an integer in the range of -1 to 9. Lower compression
levels result in faster execution, but less compression. Higher levels result in
greater compression, but slower execution. The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
equal to -1,
provides a good compromise between compression and speed and is equivalent to level 6.
Level 0 actually does no compression at all, and in fact expands the data slightly to produce
the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
More advanced applications of <em>zlib</em>
may use <tt>deflateInit2()</tt> here instead. Such an application may want to reduce how
much memory will be used, at some price in compression. Or it may need to request a
<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
encoding with no header or trailer at all.
<p>
We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
<tt>Z_OK</tt> to make sure that it was able to
allocate memory for the internal state, and that the provided arguments were valid.
<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
file came from matches the version of <em>zlib</em> actually linked with the program. This
is especially important for environments in which <em>zlib</em> is a shared library.
<p>
Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
operate in parallel. The state information maintained in the structure allows the <em>zlib</em>
routines to be reentrant.
<pre><b>
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&amp;strm, level);
if (ret != Z_OK)
return ret;
</b></pre><!-- -->
With the pleasantries out of the way, now we can get down to business. The outer <tt>do</tt>-loop
reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
This loop contains the only call of <tt>deflate()</tt>. So we must make sure that all of the
input data has been processed and that all of the output data has been generated and consumed
before we fall out of the loop at the bottom.
<pre><b>
/* compress until end of file */
do {
</b></pre>
We start off by reading data from the input file. The number of bytes read is put directly
into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>. We also
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
<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
indicate that this is the last chunk of input data to compress. We need to use <tt>feof()</tt>
to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read. The
reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
up the compressed stream. If we are not yet at the end of the input, then the <em>zlib</em>
constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
in the middle of the uncompressed data.
<p>
If there is an error in reading from the input file, the process is aborted with
<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
the error. We wouldn't want a memory leak, now would we? <tt>deflateEnd()</tt> can be called
at any time after the state has been initialized. Once that's done, <tt>deflateInit()</tt> (or
<tt>deflateInit2()</tt>) would have to be called to start a new compression process. There is
no point here in checking the <tt>deflateEnd()</tt> return code. The deallocation can't fail.
<pre><b>
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&amp;strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
</b></pre><!-- -->
The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
keeps calling <tt>deflate()</tt> until it is done producing output. Once there is no more
new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
<tt>avail_in</tt> will be zero.
<pre><b>
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
</b></pre>
Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
of available output bytes and <tt>next_out</tt> to a pointer to that space.
<pre><b>
strm.avail_out = CHUNK;
strm.next_out = out;
</b></pre>
Now we call the compression engine itself, <tt>deflate()</tt>. It takes as many of the
<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
<tt>avail_out</tt> bytes to <tt>next_out</tt>. Those counters and pointers are then
updated past the input data consumed and the output data written. It is the amount of
output space available that may limit how much input is consumed.
Hence the inner loop to make sure that
all of the input is consumed by providing more output space each time. Since <tt>avail_in</tt>
and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
between <tt>deflate()</tt> calls until it's all used up.
<p>
The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
the input and output information and the internal compression engine state, and a parameter
indicating whether and how to flush data to the output. Normally <tt>deflate</tt> will consume
several K bytes of input data before producing any output (except for the header), in order
to accumulate statistics on the data for optimum compression. It will then put out a burst of
compressed data, and proceed to consume more input before the next burst. Eventually,
<tt>deflate()</tt>
must be told to terminate the stream, complete the compression with provided input data, and
write out the trailer check value. <tt>deflate()</tt> will continue to compress normally as long
as the flush parameter is <tt>Z_NO_FLUSH</tt>. Once the <tt>Z_FINISH</tt> parameter is provided,
<tt>deflate()</tt> will begin to complete the compressed output stream. However depending on how
much output space is provided, <tt>deflate()</tt> may have to be called several times until it
has provided the complete compressed stream, even after it has consumed all of the input. The flush
parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
<p>
There are other values of the flush parameter that are used in more advanced applications. You can
force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
so far, even if it wouldn't have otherwise, for example to control data latency on a link with
compressed data. You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
that point so that what follows can be decompressed independently, for example for random access
applications. Both requests will degrade compression by an amount depending on how often such
requests are made.
<p>
<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here. Why
not? Well, it turns out that <tt>deflate()</tt> can do no wrong here. Let's go through
<tt>deflate()</tt>'s return values and dispense with them one by one. The possible values are
<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>. <tt>Z_OK</tt>
is, well, ok. <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
<tt>deflate()</tt>. This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
until it has no more output. <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
initialized properly, but we did initialize it properly. There is no harm in checking for
<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
<tt>Z_BUF_ERROR</tt> will be explained further below, but
suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
more input or produce more output. <tt>deflate()</tt> can be called again with more output space
or more available input, which it will be in this code.
<pre><b>
ret = deflate(&amp;strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
</b></pre>
Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
difference between how much space was provided before the call, and how much output space
is still available after the call. Then that data, if any, is written to the output file.
We can then reuse the output buffer for the next call of <tt>deflate()</tt>. Again if there
is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
<pre><b>
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&amp;strm);
return Z_ERRNO;
}
</b></pre>
The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
provided output buffer. Then we know that <tt>deflate()</tt> has done as much as it can with
the provided input, and that all of that input has been consumed. We can then fall out of this
loop and reuse the input buffer.
<p>
The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
the output buffer, leaving <tt>avail_out</tt> greater than zero. However suppose that
<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
As far as we know, <tt>deflate()</tt>
has more output for us. So we call it again. But now <tt>deflate()</tt> produces no output
at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>. That <tt>deflate()</tt> call
wasn't able to do anything, either consume input or produce output, and so it returns
<tt>Z_BUF_ERROR</tt>. (See, I told you I'd cover this later.) However this is not a problem at
all. Now we finally have the desired indication that <tt>deflate()</tt> is really done,
and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
<p>
With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
complete the output stream. Once that is done, subsequent calls of <tt>deflate()</tt> would return
<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
until the state is reinitialized.
<p>
Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
instead of the single inner loop we have here. The first loop would call
without flushing and feed all of the data to <tt>deflate()</tt>. The second loop would call
<tt>deflate()</tt> with no more
data and the <tt>Z_FINISH</tt> parameter to complete the process. As you can see from this
example, that can be avoided by simply keeping track of the current flush state.
<pre><b>
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
</b></pre><!-- -->
Now we check to see if we have already processed all of the input file. That information was
saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>. If so,
then we're done and we fall out of the outer loop. We're guaranteed to get <tt>Z_STREAM_END</tt>
from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
consumed and all of the output was generated.
<pre><b>
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
</b></pre><!-- -->
The process is complete, but we still need to deallocate the state to avoid a memory leak
(or rather more like a memory hemorrhage if you didn't do this). Then
finally we can return with a happy return value.
<pre><b>
/* clean up and return */
(void)deflateEnd(&amp;strm);
return Z_OK;
}
</b></pre><!-- -->
Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
uncompressed data to the output file. Much of the discussion above for <tt>def()</tt>
applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
the two.
<pre><b>
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
</b></pre>
The local variables have the same functionality as they do for <tt>def()</tt>. The
only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
can tell from the <em>zlib</em> stream itself when the stream is complete.
<pre><b>
int ret;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
</b></pre><!-- -->
The initialization of the state is the same, except that there is no compression level,
of course, and two more elements of the structure are initialized. <tt>avail_in</tt>
and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>. This
is because the application has the option to provide the start of the zlib stream in
order for <tt>inflateInit()</tt> to have access to information about the compression
method to aid in memory allocation. In the current implementation of <em>zlib</em>
(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
<tt>inflate()</tt> anyway. However those fields must be initialized since later versions
of <em>zlib</em> that provide more compression methods may take advantage of this interface.
In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
<p>
Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
indicate that no input data is being provided.
<pre><b>
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&amp;strm);
if (ret != Z_OK)
return ret;
</b></pre><!-- -->
The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
that it has reached the end of the compressed data and has produced all of the uncompressed
output. This is in contrast to <tt>def()</tt> which processes all of the input file.
If end-of-file is reached before the compressed data self-terminates, then the compressed
data is incomplete and an error is returned.
<pre><b>
/* decompress until deflate stream ends or end of file */
do {
</b></pre>
We read input data and set the <tt>strm</tt> structure accordingly. If we've reached the
end of the input file, then we leave the outer loop and report an error, since the
compressed data is incomplete. Note that we may read more data than is eventually consumed
by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
For applications where <em>zlib</em> streams are embedded in other data, this routine would
need to be modified to return the unused data, or at least indicate how much of the input
data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
<pre><b>
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&amp;strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
</b></pre><!-- -->
The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
keep calling <tt>inflate()</tt> until has generated all of the output it can with the
provided input.
<pre><b>
/* run inflate() on input until output buffer not full */
do {
</b></pre>
Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
<pre><b>
strm.avail_out = CHUNK;
strm.next_out = out;
</b></pre>
Now we run the decompression engine itself. There is no need to adjust the flush parameter, since
the <em>zlib</em> format is self-terminating. The main difference here is that there are
return values that we need to pay attention to. <tt>Z_DATA_ERROR</tt>
indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
corrupted somewhere along the way since it was compressed. The other error to be processed is
<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
<p>
Advanced applications may use
<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
first 32K or so of compression. This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
requests that that dictionary be provided before it can start to decompress. Without the dictionary,
correct decompression is not possible. For this routine, we have no idea what the dictionary is,
so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
<p>
<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
but could be checked for as noted above for <tt>def()</tt>. <tt>Z_BUF_ERROR</tt> does not need to be
checked for here, for the same reasons noted for <tt>def()</tt>. <tt>Z_STREAM_END</tt> will be
checked for later.
<pre><b>
ret = inflate(&amp;strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&amp;strm);
return ret;
}
</b></pre>
The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
<pre><b>
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&amp;strm);
return Z_ERRNO;
}
</b></pre>
The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
by not filling the output buffer, just as for <tt>deflate()</tt>.
<pre><b>
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
</b></pre><!-- -->
The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
end of the input <em>zlib</em> stream, has completed the decompression and integrity
check, and has provided all of the output. This is indicated by the <tt>inflate()</tt>
return value <tt>Z_STREAM_END</tt>. The inner loop is guaranteed to leave <tt>ret</tt>
equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
of the <em>zlib</em> stream. So if the return value is not <tt>Z_STREAM_END</tt>, the
loop continues to read more input.
<pre><b>
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
</b></pre><!-- -->
At this point, decompression successfully completed, or we broke out of the loop due to no
more data being available from the input file. If the last <tt>inflate()</tt> return value
is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
is returned. Otherwise, we return with a happy return value. Of course, <tt>inflateEnd()</tt>
is called first to avoid a memory leak.
<pre><b>
/* clean up and return */
(void)inflateEnd(&amp;strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
</b></pre><!-- -->
That ends the routines that directly use <em>zlib</em>. The following routines make this
a command-line program by running data through the above routines from <tt>stdin</tt> to
<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
<p>
<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
Note that these are only a subset of the possible return values from <tt>deflate()</tt>
and <tt>inflate()</tt>.
<pre><b>
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
</b></pre><!-- -->
Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>. The
<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used. If any other
arguments are provided, no compression or decompression is performed. Instead a usage
message is displayed. Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
<pre><b>
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
return 1;
}
}
</b></pre>
<hr>
<i>Copyright (c) 2004 by Mark Adler<br>Last modified 13 November 2004</i>
</body>
</html>

191
examples/zpipe.c Normal file
View File

@@ -0,0 +1,191 @@
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.2 9 November 2004 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
return 1;
}
}

21
gzio.c
View File

@@ -1,5 +1,5 @@
/* gzio.c -- IO on .gz files /* gzio.c -- IO on .gz files
* Copyright (C) 1995-2003 Jean-loup Gailly. * Copyright (C) 1995-2004 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
* *
* Compile this file with -DNO_GZCOMPRESS to avoid the compression code. * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
@@ -11,7 +11,7 @@
#include "zutil.h" #include "zutil.h"
#ifdef NO_DEFLATE /* for compatiblity with old definition */ #ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS # define NO_GZCOMPRESS
#endif #endif
@@ -220,7 +220,7 @@ gzFile ZEXPORT gzdopen (fd, mode)
int fd; int fd;
const char *mode; const char *mode;
{ {
char name[20]; char name[46]; /* allow for up to 128-bit integers */
if (fd < 0) return (gzFile)Z_NULL; if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */ sprintf(name, "<fd:%d>", fd); /* for debugging */
@@ -455,6 +455,10 @@ int ZEXPORT gzread (file, buf, len)
s->z_err = Z_ERRNO; s->z_err = Z_ERRNO;
break; break;
} }
if (feof(s->file)) { /* avoid error for empty file */
s->z_err = Z_STREAM_END;
break;
}
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
@@ -937,7 +941,6 @@ local uLong getLong (s)
int ZEXPORT gzclose (file) int ZEXPORT gzclose (file)
gzFile file; gzFile file;
{ {
int err;
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
if (s == NULL) return Z_STREAM_ERROR; if (s == NULL) return Z_STREAM_ERROR;
@@ -946,8 +949,8 @@ int ZEXPORT gzclose (file)
#ifdef NO_GZCOMPRESS #ifdef NO_GZCOMPRESS
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
#else #else
err = do_flush (file, Z_FINISH); if (do_flush (file, Z_FINISH) != Z_OK)
if (err != Z_OK) return destroy((gz_stream*)file); return destroy((gz_stream*)file);
putLong (s->file, s->crc); putLong (s->file, s->crc);
putLong (s->file, (uLong)(s->in & 0xffffffff)); putLong (s->file, (uLong)(s->in & 0xffffffff));
@@ -956,6 +959,12 @@ int ZEXPORT gzclose (file)
return destroy((gz_stream*)file); return destroy((gz_stream*)file);
} }
#ifdef STDC
# define zstrerror(errnum) strerror(errnum)
#else
# define zstrerror(errnum) ""
#endif
/* =========================================================================== /* ===========================================================================
Returns the error message for the last error which occured on the Returns the error message for the last error which occured on the
given compressed file. errnum is set to zlib error number. If an given compressed file. errnum is set to zlib error number. If an

View File

@@ -1,5 +1,5 @@
/* infback.c -- inflate using a call-back interface /* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -26,7 +26,7 @@ local void fixedtables OF((struct inflate_state FAR *state));
window and output buffer that is 2**windowBits bytes. window and output buffer that is 2**windowBits bytes.
*/ */
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_stream FAR *strm; z_streamp strm;
int windowBits; int windowBits;
unsigned char FAR *window; unsigned char FAR *window;
const char *version; const char *version;
@@ -51,6 +51,7 @@ int stream_size;
if (state == Z_NULL) return Z_MEM_ERROR; if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n")); Tracev((stderr, "inflate: allocated\n"));
strm->state = (voidpf)state; strm->state = (voidpf)state;
state->dmax = 32768U;
state->wbits = windowBits; state->wbits = windowBits;
state->wsize = 1U << windowBits; state->wsize = 1U << windowBits;
state->window = window; state->window = window;
@@ -238,7 +239,7 @@ struct inflate_state FAR *state;
are not correct, i.e. strm is Z_NULL or the state was not initialized. are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/ */
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_stream FAR *strm; z_streamp strm;
in_func in; in_func in;
void FAR *in_desc; void FAR *in_desc;
out_func out; out_func out;
@@ -434,6 +435,9 @@ void FAR *out_desc;
} }
} }
/* handle error breaks in while */
if (state->mode == BAD) break;
/* build code tables */ /* build code tables */
state->next = state->codes; state->next = state->codes;
state->lencode = (code const FAR *)(state->next); state->lencode = (code const FAR *)(state->next);
@@ -608,7 +612,7 @@ void FAR *out_desc;
} }
int ZEXPORT inflateBackEnd(strm) int ZEXPORT inflateBackEnd(strm)
z_stream FAR *strm; z_streamp strm;
{ {
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;

View File

@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding /* inffast.c -- fast decoding
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -19,7 +19,7 @@
- none - none
No measurable difference: No measurable difference:
- Pentium III (Anderson) - Pentium III (Anderson)
- 68060 (Nikl) - M68060 (Nikl)
*/ */
#ifdef POSTINC #ifdef POSTINC
# define OFF 0 # define OFF 0
@@ -74,6 +74,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */ unsigned char FAR *end; /* while out < end, enough space available */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */ unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */ unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */ unsigned write; /* window write index */
@@ -98,6 +101,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
out = strm->next_out - OFF; out = strm->next_out - OFF;
beg = out - (start - strm->avail_out); beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257); end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize; wsize = state->wsize;
whave = state->whave; whave = state->whave;
write = state->write; write = state->write;
@@ -167,6 +173,13 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
} }
} }
dist += (unsigned)hold & ((1U << op) - 1); dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op; hold >>= op;
bits -= op; bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist)); Tracevv((stderr, "inflate: distance %u\n", dist));

View File

@@ -1,5 +1,5 @@
/* inflate.c -- zlib decompression /* inflate.c -- zlib decompression
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -109,9 +109,12 @@ z_streamp strm;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0; strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL; strm->msg = Z_NULL;
strm->adler = 1; /* to support ill-conceived Java test suite */
state->mode = HEAD; state->mode = HEAD;
state->last = 0; state->last = 0;
state->havedict = 0; state->havedict = 0;
state->dmax = 32768U;
state->head = Z_NULL;
state->wsize = 0; state->wsize = 0;
state->whave = 0; state->whave = 0;
state->hold = 0; state->hold = 0;
@@ -581,6 +584,8 @@ int flush;
break; break;
} }
state->flags = 0; /* expect zlib header */ state->flags = 0; /* expect zlib header */
if (state->head != Z_NULL)
state->head->done = -1;
if (!(state->wrap & 1) || /* check if zlib header allowed */ if (!(state->wrap & 1) || /* check if zlib header allowed */
#else #else
if ( if (
@@ -596,11 +601,13 @@ int flush;
break; break;
} }
DROPBITS(4); DROPBITS(4);
if (BITS(4) + 8 > state->wbits) { len = BITS(4) + 8;
if (len > state->wbits) {
strm->msg = (char *)"invalid window size"; strm->msg = (char *)"invalid window size";
state->mode = BAD; state->mode = BAD;
break; break;
} }
state->dmax = 1U << len;
Tracev((stderr, "inflate: zlib header ok\n")); Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0); strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE; state->mode = hold & 0x200 ? DICTID : TYPE;
@@ -620,16 +627,24 @@ int flush;
state->mode = BAD; state->mode = BAD;
break; break;
} }
if (state->head != Z_NULL)
state->head->text = (int)((hold >> 8) & 1);
if (state->flags & 0x0200) CRC2(state->check, hold); if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = TIME; state->mode = TIME;
case TIME: case TIME:
NEEDBITS(32); NEEDBITS(32);
if (state->head != Z_NULL)
state->head->time = hold;
if (state->flags & 0x0200) CRC4(state->check, hold); if (state->flags & 0x0200) CRC4(state->check, hold);
INITBITS(); INITBITS();
state->mode = OS; state->mode = OS;
case OS: case OS:
NEEDBITS(16); NEEDBITS(16);
if (state->head != Z_NULL) {
state->head->xflags = (int)(hold & 0xff);
state->head->os = (int)(hold >> 8);
}
if (state->flags & 0x0200) CRC2(state->check, hold); if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS(); INITBITS();
state->mode = EXLEN; state->mode = EXLEN;
@@ -637,15 +652,26 @@ int flush;
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
NEEDBITS(16); NEEDBITS(16);
state->length = (unsigned)(hold); state->length = (unsigned)(hold);
if (state->head != Z_NULL)
state->head->extra_len = (unsigned)hold;
if (state->flags & 0x0200) CRC2(state->check, hold); if (state->flags & 0x0200) CRC2(state->check, hold);
INITBITS(); INITBITS();
} }
else if (state->head != Z_NULL)
state->head->extra = Z_NULL;
state->mode = EXTRA; state->mode = EXTRA;
case EXTRA: case EXTRA:
if (state->flags & 0x0400) { if (state->flags & 0x0400) {
copy = state->length; copy = state->length;
if (copy > have) copy = have; if (copy > have) copy = have;
if (copy) { if (copy) {
if (state->head != Z_NULL &&
state->head->extra != Z_NULL) {
len = state->head->extra_len - state->length;
zmemcpy(state->head->extra + len, next,
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
}
if (state->flags & 0x0200) if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy); state->check = crc32(state->check, next, copy);
have -= copy; have -= copy;
@@ -654,6 +680,7 @@ int flush;
} }
if (state->length) goto inf_leave; if (state->length) goto inf_leave;
} }
state->length = 0;
state->mode = NAME; state->mode = NAME;
case NAME: case NAME:
if (state->flags & 0x0800) { if (state->flags & 0x0800) {
@@ -661,13 +688,20 @@ int flush;
copy = 0; copy = 0;
do { do {
len = (unsigned)(next[copy++]); len = (unsigned)(next[copy++]);
if (state->head != Z_NULL &&
state->head->name != Z_NULL &&
state->length < state->head->name_max)
state->head->name[state->length++] = len;
} while (len && copy < have); } while (len && copy < have);
if (state->flags & 0x02000) if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy); state->check = crc32(state->check, next, copy);
have -= copy; have -= copy;
next += copy; next += copy;
if (len) goto inf_leave; if (len) goto inf_leave;
} }
else if (state->head != Z_NULL)
state->head->name = Z_NULL;
state->length = 0;
state->mode = COMMENT; state->mode = COMMENT;
case COMMENT: case COMMENT:
if (state->flags & 0x1000) { if (state->flags & 0x1000) {
@@ -675,13 +709,19 @@ int flush;
copy = 0; copy = 0;
do { do {
len = (unsigned)(next[copy++]); len = (unsigned)(next[copy++]);
if (state->head != Z_NULL &&
state->head->comment != Z_NULL &&
state->length < state->head->comm_max)
state->head->comment[state->length++] = len;
} while (len && copy < have); } while (len && copy < have);
if (state->flags & 0x02000) if (state->flags & 0x0200)
state->check = crc32(state->check, next, copy); state->check = crc32(state->check, next, copy);
have -= copy; have -= copy;
next += copy; next += copy;
if (len) goto inf_leave; if (len) goto inf_leave;
} }
else if (state->head != Z_NULL)
state->head->comment = Z_NULL;
state->mode = HCRC; state->mode = HCRC;
case HCRC: case HCRC:
if (state->flags & 0x0200) { if (state->flags & 0x0200) {
@@ -693,6 +733,10 @@ int flush;
} }
INITBITS(); INITBITS();
} }
if (state->head != Z_NULL) {
state->head->hcrc = (int)((state->flags >> 9) & 1);
state->head->done = 1;
}
strm->adler = state->check = crc32(0L, Z_NULL, 0); strm->adler = state->check = crc32(0L, Z_NULL, 0);
state->mode = TYPE; state->mode = TYPE;
break; break;
@@ -861,6 +905,9 @@ int flush;
} }
} }
/* handle error breaks in while */
if (state->mode == BAD) break;
/* build code tables */ /* build code tables */
state->next = state->codes; state->next = state->codes;
state->lencode = (code const FAR *)(state->next); state->lencode = (code const FAR *)(state->next);
@@ -965,6 +1012,13 @@ int flush;
state->offset += BITS(state->extra); state->offset += BITS(state->extra);
DROPBITS(state->extra); DROPBITS(state->extra);
} }
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
if (state->offset > state->whave + out - left) { if (state->offset > state->whave + out - left) {
strm->msg = (char *)"invalid distance too far back"; strm->msg = (char *)"invalid distance too far back";
state->mode = BAD; state->mode = BAD;
@@ -1106,12 +1160,16 @@ uInt dictLength;
/* check state */ /* check state */
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
if (state->mode != DICT) return Z_STREAM_ERROR; if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR;
/* check for correct dictionary id */ /* check for correct dictionary id */
if (state->mode == DICT) {
id = adler32(0L, Z_NULL, 0); id = adler32(0L, Z_NULL, 0);
id = adler32(id, dictionary, dictLength); id = adler32(id, dictionary, dictLength);
if (id != state->check) return Z_DATA_ERROR; if (id != state->check)
return Z_DATA_ERROR;
}
/* copy dictionary to window */ /* copy dictionary to window */
if (updatewindow(strm, strm->avail_out)) { if (updatewindow(strm, strm->avail_out)) {
@@ -1133,6 +1191,23 @@ uInt dictLength;
return Z_OK; return Z_OK;
} }
int ZEXPORT inflateGetHeader(strm, head)
z_streamp strm;
gz_headerp head;
{
struct inflate_state FAR *state;
/* check state */
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
/* save header structure */
state->head = head;
head->done = 0;
return Z_OK;
}
/* /*
Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
or when out of input. When called, *have is the number of pattern bytes or when out of input. When called, *have is the number of pattern bytes
@@ -1257,8 +1332,8 @@ z_streamp source;
} }
/* copy state */ /* copy state */
*dest = *source; zmemcpy(dest, source, sizeof(z_stream));
*copy = *state; zmemcpy(copy, state, sizeof(struct inflate_state));
copy->lencode = copy->codes + (state->lencode - state->codes); copy->lencode = copy->codes + (state->lencode - state->codes);
copy->distcode = copy->codes + (state->distcode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes);
copy->next = copy->codes + (state->next - state->codes); copy->next = copy->codes + (state->next - state->codes);

View File

@@ -1,5 +1,5 @@
/* inflate.h -- internal inflate state definition /* inflate.h -- internal inflate state definition
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -19,7 +19,6 @@
/* Possible inflate modes between inflate() calls */ /* Possible inflate modes between inflate() calls */
typedef enum { typedef enum {
HEAD, /* i: waiting for magic header */ HEAD, /* i: waiting for magic header */
#ifdef GUNZIP
FLAGS, /* i: waiting for method and flags (gzip) */ FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */ TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */
@@ -28,7 +27,6 @@ typedef enum {
NAME, /* i: waiting for end of file name (gzip) */ NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */ HCRC, /* i: waiting for header crc (gzip) */
#endif
DICTID, /* i: waiting for dictionary check value */ DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */ DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */ TYPE, /* i: waiting for type bits, including last-flag bit */
@@ -45,9 +43,7 @@ typedef enum {
MATCH, /* o: waiting for output space to copy string */ MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */ LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */ CHECK, /* i: waiting for 32-bit check value */
#ifdef GUNZIP
LENGTH, /* i: waiting for 32-bit length (gzip) */ LENGTH, /* i: waiting for 32-bit length (gzip) */
#endif
DONE, /* finished check, done -- remain here until reset */ DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */ BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */
@@ -84,8 +80,10 @@ struct inflate_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */ int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */ int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */ unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */ unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */ /* sliding window */
unsigned wbits; /* log base 2 of requested window size */ unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */ unsigned wsize; /* window size or zero if not using window */

View File

@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate_copyright[] = const char inflate_copyright[] =
" inflate 1.2.0.8 Copyright 1995-2003 Mark Adler "; " inflate 1.2.2.2 Copyright 1995-2004 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 203}; 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 199};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -114,7 +114,15 @@ unsigned short FAR *work;
for (max = MAXBITS; max >= 1; max--) for (max = MAXBITS; max >= 1; max--)
if (count[max] != 0) break; if (count[max] != 0) break;
if (root > max) root = max; if (root > max) root = max;
if (max == 0) return -1; /* no codes! */ if (max == 0) { /* no symbols to code at all */
this.op = (unsigned char)64; /* invalid code marker */
this.bits = (unsigned char)1;
this.val = (unsigned short)0;
*(*table)++ = this; /* make a table to force an error */
*(*table)++ = this;
*bits = 1;
return 0; /* no symbols, but wait for decoding to report error */
}
for (min = 1; min <= MAXBITS; min++) for (min = 1; min <= MAXBITS; min++)
if (count[min] != 0) break; if (count[min] != 0) break;
if (root < min) root = min; if (root < min) root = min;
@@ -295,7 +303,6 @@ unsigned short FAR *work;
drop = 0; drop = 0;
len = root; len = root;
next = *table; next = *table;
curr = root;
this.bits = (unsigned char)len; this.bits = (unsigned char)len;
} }

23
old/Make_vms.com → make_vms.com Executable file → Normal file
View File

@@ -32,25 +32,24 @@ $ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - $ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
compress.c zlib.h zconf.h compress.c zlib.h zconf.h
$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - $ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
crc32.c zlib.h zconf.h crc32.c crc32.h zlib.h zconf.h zutil.h
$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - $ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
deflate.c deflate.h zutil.h zlib.h zconf.h deflate.c deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - $ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio /define=""NO_vsnprintf""" -
gzio.c zutil.h zlib.h zconf.h gzio.c zutil.h zlib.h zconf.h
$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - $ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
infblock.c zutil.h zlib.h zconf.h infblock.h infback.c zutil.h zlib.h zconf.h -
$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - "inftrees.h inflate.h inffast.h inffixed.h"
infcodes.c zutil.h zlib.h zconf.h inftrees.h
$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - $ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
inffast.c zutil.h zlib.h zconf.h inffast.h inffast.c zutil.h zlib.h zconf.h -
"inftrees.h inflate.h inffast.h"
$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - $ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
inflate.c zutil.h zlib.h zconf.h infblock.h inflate.c zutil.h zlib.h zconf.h -
"inftrees.h inflate.h inffast.h inffixed.h"
$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - $ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
inftrees.c zutil.h zlib.h zconf.h inftrees.h inftrees.c zutil.h zlib.h zconf.h inftrees.h
$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" -
infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - $ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
trees.c deflate.h zutil.h zlib.h zconf.h trees.c trees.h deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - $ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
uncompr.c zlib.h zconf.h uncompr.c zlib.h zconf.h
$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - $ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
@@ -65,7 +64,7 @@ $ write sys$output "Building minigzip..."
$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - $ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
minigzip.c zlib.h zconf.h minigzip.c zlib.h zconf.h
$ call make minigzip.exe - $ call make minigzip.exe -
"LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - "LINK minigzip,libz.olb/lib" -
minigzip.obj libz.olb minigzip.obj libz.olb
$ else $ else
$ mms/macro=('comp') $ mms/macro=('comp')

View File

@@ -1,5 +1,5 @@
/* minigzip.c -- simulate gzip using the zlib compression library /* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995-2002 Jean-loup Gailly. * Copyright (C) 1995-2004 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -21,8 +21,6 @@
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h> # include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
#ifdef USE_MMAP #ifdef USE_MMAP

View File

@@ -1,3 +1,3 @@
This directory contains files that have not been updated for zlib 1.2. This directory contains files that have not been updated for zlib 1.2.x
(Volunteers are encouraged to help clean this up. Thanks.) (Volunteers are encouraged to help clean this up. Thanks.)

41
projects/README.projects Normal file
View File

@@ -0,0 +1,41 @@
This directory contains project files for building zlib under various
Integrated Development Environments (IDE).
If you wish to submit a new project to this directory, you should comply
to the following requirements. Otherwise (e.g. if you wish to integrate
a custom piece of code that changes the zlib interface or its behavior),
please consider submitting the project to the contrib directory.
Requirements
============
- The project must build zlib using the source files from the official
zlib source distribution, exclusively.
- If the project produces redistributable builds (e.g. shared objects
or DLL files), these builds must be compatible to those produced by
makefiles, if such makefiles exist in the zlib distribution.
In particular, if the project produces a DLL build for the Win32
platform, this build must comply to the officially-ammended Win32 DLL
Application Binary Interface (ABI), described in win32/DLL_FAQ.txt.
- The project may provide additional build targets, which depend on
3rd-party (unofficially-supported) software, present in the contrib
directory. For example, it is possible to provide an "ASM build",
besides the officially-supported build, and have ASM source files
among its dependencies.
- If there are significant differences between the project files created
by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name
of the project directory should contain the version number of the IDE
for which the project is intended (e.g. "visualc6" for Visual C++ 6.0,
or "visualc7" for Visual C++ 7.0 and 7.1).
Current projects
================
visualc6/ by Simon-Pierre Cadieux <methodex@methodex.ca>
and Cosmin Truta <cosmint@cs.ubbcluj.ro>
Project for Microsoft Visual C++ 6.0

View File

@@ -0,0 +1,73 @@
Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
Copyright (C) 2000-2004 Simon-Pierre Cadieux.
Copyright (C) 2004 Cosmin Truta.
For conditions of distribution and use, see copyright notice in zlib.h.
This project builds the zlib binaries as follows:
* Win32_DLL_Release\zlib1.dll DLL build
* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
* Win32_LIB_Release\zlib.lib static build
* Win32_LIB_Debug\zlibd.lib static build (debug version)
* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
For more information regarding the DLL builds, please see the DLL FAQ
in ..\..\win32\DLL_FAQ.txt.
To build and test:
1) On the main menu, select "File | Open Workspace".
Open "zlib.dsw".
2) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
3) Select "Build | Clean".
4) Select "Build | Build ... (F7)". Ignore warning messages about
not being able to find certain include files (e.g. alloc.h).
5) If you built one of the sample programs (example or minigzip),
select "Build | Execute ... (Ctrl+F5)".
To use:
1) Select "Project | Settings (Alt+F7)".
Make note of the configuration names used in your project.
Usually, these names are "Win32 Release" and "Win32 Debug".
2) In the Workspace window, select the "FileView" tab.
Right-click on the root item "Workspace '...'".
Select "Insert Project into Workspace".
Switch on the checkbox "Dependency of:", and select the name
of your project. Open "zlib.dsp".
3) Select "Build | Configurations".
For each configuration of your project:
3.1) Choose the zlib configuration you wish to use.
3.2) Click on "Add".
3.3) Set the new zlib configuration name to the name used by
the configuration from the current iteration.
4) Select "Build | Set Active Configuration".
Choose the configuration you wish to build.
5) Select "Build | Build ... (F7)".
6) If you built an executable program, select
"Build | Execute ... (Ctrl+F5)".
Note:
To build the ASM-enabled code, you need Microsoft Assembler
(ML.EXE). You can get it by downloading and installing the
latest Processor Pack for Visual C++ 6.0.

View File

@@ -0,0 +1,278 @@
# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=example - Win32 LIB Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "example.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "example - Win32 DLL Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "example___Win32_DLL_Release"
# PROP BASE Intermediate_Dir "example___Win32_DLL_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_Release"
# PROP Intermediate_Dir "Win32_DLL_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "example - Win32 DLL Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "example___Win32_DLL_Debug"
# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_Debug"
# PROP Intermediate_Dir "Win32_DLL_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"
# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_ASM_Release"
# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"
# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_ASM_Debug"
# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "example - Win32 LIB Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "example___Win32_LIB_Release"
# PROP BASE Intermediate_Dir "example___Win32_LIB_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_Release"
# PROP Intermediate_Dir "Win32_LIB_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "example - Win32 LIB Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "example___Win32_LIB_Debug"
# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_Debug"
# PROP Intermediate_Dir "Win32_LIB_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"
# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_ASM_Release"
# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"
# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_ASM_Debug"
# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "example - Win32 DLL Release"
# Name "example - Win32 DLL Debug"
# Name "example - Win32 DLL ASM Release"
# Name "example - Win32 DLL ASM Debug"
# Name "example - Win32 LIB Release"
# Name "example - Win32 LIB Debug"
# Name "example - Win32 LIB ASM Release"
# Name "example - Win32 LIB ASM Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\example.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\zconf.h
# End Source File
# Begin Source File
SOURCE=..\..\zlib.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,278 @@
# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=minigzip - Win32 LIB Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "minigzip.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "minigzip - Win32 DLL Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "minigzip___Win32_DLL_Release"
# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_Release"
# PROP Intermediate_Dir "Win32_DLL_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"
# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_Debug"
# PROP Intermediate_Dir "Win32_DLL_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"
# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_ASM_Release"
# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"
# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_ASM_Debug"
# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "minigzip___Win32_LIB_Release"
# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_Release"
# PROP Intermediate_Dir "Win32_LIB_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"
# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_Debug"
# PROP Intermediate_Dir "Win32_LIB_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"
# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_ASM_Release"
# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"
# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_ASM_Debug"
# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "minigzip - Win32 DLL Release"
# Name "minigzip - Win32 DLL Debug"
# Name "minigzip - Win32 DLL ASM Release"
# Name "minigzip - Win32 DLL ASM Debug"
# Name "minigzip - Win32 LIB Release"
# Name "minigzip - Win32 LIB Debug"
# Name "minigzip - Win32 LIB ASM Release"
# Name "minigzip - Win32 LIB ASM Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\minigzip.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\zconf.h
# End Source File
# Begin Source File
SOURCE=..\..\zlib.h
# End Source File
# End Group
# End Target
# End Project

609
projects/visualc6/zlib.dsp Normal file
View File

@@ -0,0 +1,609 @@
# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=zlib - Win32 LIB Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "zlib.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")
!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")
!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
!IF "$(CFG)" == "zlib - Win32 DLL Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "zlib___Win32_DLL_Release"
# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_Release"
# PROP Intermediate_Dir "Win32_DLL_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
MTL=midl.exe
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"
!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "zlib___Win32_DLL_Debug"
# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_Debug"
# PROP Intermediate_Dir "Win32_DLL_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
MTL=midl.exe
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"
# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_DLL_ASM_Release"
# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
MTL=midl.exe
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"
# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_DLL_ASM_Debug"
# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
MTL=midl.exe
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# 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
# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "zlib___Win32_LIB_Release"
# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_Release"
# PROP Intermediate_Dir "Win32_LIB_Release"
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "zlib___Win32_LIB_Debug"
# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_Debug"
# PROP Intermediate_Dir "Win32_LIB_Debug"
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"
# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Win32_LIB_ASM_Release"
# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"
# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Win32_LIB_ASM_Debug"
# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
# PROP Target_Dir ""
CPP=cl.exe
# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
RSC=rc.exe
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"
!ENDIF
# Begin Target
# Name "zlib - Win32 DLL Release"
# Name "zlib - Win32 DLL Debug"
# Name "zlib - Win32 DLL ASM Release"
# Name "zlib - Win32 DLL ASM Debug"
# Name "zlib - Win32 LIB Release"
# Name "zlib - Win32 LIB Debug"
# Name "zlib - Win32 LIB ASM Release"
# Name "zlib - Win32 LIB ASM Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\adler32.c
# End Source File
# Begin Source File
SOURCE=..\..\compress.c
# End Source File
# Begin Source File
SOURCE=..\..\crc32.c
# End Source File
# Begin Source File
SOURCE=..\..\deflate.c
# End Source File
# Begin Source File
SOURCE=..\..\gzio.c
# End Source File
# Begin Source File
SOURCE=..\..\infback.c
# End Source File
# Begin Source File
SOURCE=..\..\inffast.c
# End Source File
# Begin Source File
SOURCE=..\..\inflate.c
# End Source File
# Begin Source File
SOURCE=..\..\inftrees.c
# End Source File
# Begin Source File
SOURCE=..\..\trees.c
# End Source File
# Begin Source File
SOURCE=..\..\uncompr.c
# End Source File
# Begin Source File
SOURCE=..\..\win32\zlib.def
!IF "$(CFG)" == "zlib - Win32 DLL Release"
!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\zutil.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\crc32.h
# End Source File
# Begin Source File
SOURCE=..\..\deflate.h
# End Source File
# Begin Source File
SOURCE=..\..\inffast.h
# End Source File
# Begin Source File
SOURCE=..\..\inffixed.h
# End Source File
# Begin Source File
SOURCE=..\..\inflate.h
# End Source File
# Begin Source File
SOURCE=..\..\inftrees.h
# End Source File
# Begin Source File
SOURCE=..\..\trees.h
# End Source File
# Begin Source File
SOURCE=..\..\zconf.h
# End Source File
# Begin Source File
SOURCE=..\..\zlib.h
# End Source File
# Begin Source File
SOURCE=..\..\zutil.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=..\..\win32\zlib1.rc
# End Source File
# End Group
# Begin Group "Assembler Files (Unsupported)"
# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"
# Begin Source File
SOURCE=..\..\contrib\masmx86\gvmat32.asm
!IF "$(CFG)" == "zlib - Win32 DLL Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
# Begin Custom Build - Assembling...
IntDir=.\Win32_DLL_ASM_Release
InputPath=..\..\contrib\masmx86\gvmat32.asm
InputName=gvmat32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
# Begin Custom Build - Assembling...
IntDir=.\Win32_DLL_ASM_Debug
InputPath=..\..\contrib\masmx86\gvmat32.asm
InputName=gvmat32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
# Begin Custom Build - Assembling...
IntDir=.\Win32_LIB_ASM_Release
InputPath=..\..\contrib\masmx86\gvmat32.asm
InputName=gvmat32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
# Begin Custom Build - Assembling...
IntDir=.\Win32_LIB_ASM_Debug
InputPath=..\..\contrib\masmx86\gvmat32.asm
InputName=gvmat32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\contrib\masmx86\gvmat32c.c
!IF "$(CFG)" == "zlib - Win32 DLL Release"
# PROP Exclude_From_Build 1
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
# PROP Exclude_From_Build 1
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
# PROP Exclude_From_Build 1
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
# PROP Exclude_From_Build 1
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
# ADD CPP /I "..\.."
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
# ADD CPP /I "..\.."
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\contrib\masmx86\inffas32.asm
!IF "$(CFG)" == "zlib - Win32 DLL Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
# Begin Custom Build - Assembling...
IntDir=.\Win32_DLL_ASM_Release
InputPath=..\..\contrib\masmx86\inffas32.asm
InputName=inffas32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
# Begin Custom Build - Assembling...
IntDir=.\Win32_DLL_ASM_Debug
InputPath=..\..\contrib\masmx86\inffas32.asm
InputName=inffas32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
# Begin Custom Build - Assembling...
IntDir=.\Win32_LIB_ASM_Release
InputPath=..\..\contrib\masmx86\inffas32.asm
InputName=inffas32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
# Begin Custom Build - Assembling...
IntDir=.\Win32_LIB_ASM_Debug
InputPath=..\..\contrib\masmx86\inffas32.asm
InputName=inffas32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Source File
SOURCE=.\README.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,59 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "example"=.\example.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
}}}
###############################################################################
Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
}}}
###############################################################################
Project: "zlib"=.\zlib.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -25,10 +25,10 @@
<QPG:Files> <QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../libz.so.1.2.0.8" install="/opt/lib/" user="root:bin" permission="644"/> <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.0.8"/> <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.2"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.0.8"/> <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.2"/>
<QPG:Add file="../libz.so.1.2.0.8" install="/opt/lib/" component="slib"/> <QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" component="slib"/>
</QPG:Files> </QPG:Files>
<QPG:PackageFilter> <QPG:PackageFilter>
@@ -63,7 +63,7 @@
</QPM:ProductDescription> </QPM:ProductDescription>
<QPM:ReleaseDescription> <QPM:ReleaseDescription>
<QPM:ReleaseVersion>1.2.0.8</QPM:ReleaseVersion> <QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency> <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability> <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor> <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>

34
trees.c
View File

@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2003 Jean-loup Gailly * Copyright (C) 1995-2004 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -930,8 +930,9 @@ void _tr_flush_block(s, buf, stored_len, eof)
/* Build the Huffman trees unless a stored block is forced */ /* Build the Huffman trees unless a stored block is forced */
if (s->level > 0) { if (s->level > 0) {
/* Check if the file is ascii or binary */ /* Check if the file is binary or text */
if (s->data_type == Z_UNKNOWN) set_data_type(s); if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
set_data_type(s);
/* Construct the literal and distance trees */ /* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc))); build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -982,7 +983,7 @@ void _tr_flush_block(s, buf, stored_len, eof)
#ifdef FORCE_STATIC #ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */ } else if (static_lenb >= 0) { /* force static trees */
#else #else
} else if (static_lenb == opt_lenb) { } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif #endif
send_bits(s, (STATIC_TREES<<1)+eof, 3); send_bits(s, (STATIC_TREES<<1)+eof, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
@@ -1117,21 +1118,24 @@ local void compress_block(s, ltree, dtree)
} }
/* =========================================================================== /* ===========================================================================
* Set the data type to ASCII or BINARY, using a crude approximation: * Set the data type to BINARY or TEXT, using a crude approximation:
* binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
* IN assertion: the fields freq of dyn_ltree are set and the total of all * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
* frequencies does not exceed 64K (to fit in an int on 16 bit machines). * IN assertion: the fields Freq of dyn_ltree are set.
*/ */
local void set_data_type(s) local void set_data_type(s)
deflate_state *s; deflate_state *s;
{ {
int n = 0; int n;
unsigned ascii_freq = 0;
unsigned bin_freq = 0; for (n = 0; n < 9; n++)
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; if (s->dyn_ltree[n].Freq != 0)
while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; break;
while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; if (n == 9)
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); for (n = 14; n < 32; n++)
if (s->dyn_ltree[n].Freq != 0)
break;
s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
} }
/* =========================================================================== /* ===========================================================================

View File

@@ -12,7 +12,7 @@ in the zlib distribution, or at the following location:
1. What is ZLIB1.DLL, and how can I get it? 1. What is ZLIB1.DLL, and how can I get it?
- ZLIB1.DLL is the official build of zlib as a DLL. - ZLIB1.DLL is the official build of zlib as a DLL.
(Please remark the symbol '1' in the name.) (Please remark the character '1' in the name.)
Pointers to a precompiled ZLIB1.DLL can be found in the zlib Pointers to a precompiled ZLIB1.DLL can be found in the zlib
web site at: web site at:
@@ -37,20 +37,19 @@ in the zlib distribution, or at the following location:
and build settings. If you do build the DLL yourself, please and build settings. If you do build the DLL yourself, please
make sure that it complies with all the above requirements, make sure that it complies with all the above requirements,
and it runs with the precompiled test programs, bundled with and it runs with the precompiled test programs, bundled with
the original ZLIB1.DLL distribution and available at the zlib the original ZLIB1.DLL distribution.
web site.
If, for any reason, you need to build an incompatible DLL, If, for any reason, you need to build an incompatible DLL,
please use a different name. please use a different file name.
2. Why did you change the name of the DLL to ZLIB1.DLL? 2. Why did you change the name of the DLL to ZLIB1.DLL?
What happened to the old ZLIB.DLL? What happened to the old ZLIB.DLL?
- The old ZLIB.DLL, built from zlib-1.1.x and earlier, required - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
compilation settings that were incompatible to those used by a compilation settings that were incompatible to those used by
static build. The DLL settings were supposed to be enabled by a static build. The DLL settings were supposed to be enabled
defining the macro ZLIB_DLL, before including "zlib.h". by defining the macro ZLIB_DLL, before including "zlib.h".
Incorrect handling of this macro was silently accepted at Incorrect handling of this macro was silently accepted at
build time, resulting in two major problems: build time, resulting in two major problems:
@@ -65,8 +64,8 @@ in the zlib distribution, or at the following location:
functions. Failure to do so resulted in creating binaries functions. Failure to do so resulted in creating binaries
that were unable to run with the official ZLIB.DLL build. that were unable to run with the official ZLIB.DLL build.
The only possible solution that we could foresee was to make a The only possible solution that we could foresee was to make
binary-incompatible change in the DLL interfacing, in order to a binary-incompatible change in the DLL interface, in order to
remove the dependency on the ZLIB_DLL macro, and to release remove the dependency on the ZLIB_DLL macro, and to release
the new DLL under a different name. the new DLL under a different name.
@@ -85,17 +84,13 @@ in the zlib distribution, or at the following location:
- In principle, you can do it by assigning calling convention - In principle, you can do it by assigning calling convention
keywords to the macros ZEXPORT and ZEXPORTVA. In practice, keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
it depends on what you mean by "an old ZLIB.DLL", because it depends on what you mean by "an old ZLIB.DLL", because the
the old DLL exists in several mutually-incompatible versions. old DLL exists in several mutually-incompatible versions.
You have to find out first what kind of calling convention is
If you have a compiled application that works with a certain being used in your particular ZLIB.DLL build, and to use the
ZLIB.DLL without any known security issues, there is hardly same one in the new build. If you don't know what this is all
a need to rebuild the DLL from new sources only to link it to about, you might be better off if you would just leave the old
the old app binary. But if you really want to do it, you have DLL intact.
to find out first what kind of calling convention uses your
particular ZLIB.DLL build, and to use the same one in the new
build. If you don't know what this is all about, you might be
better off if you would just forget it.
4. Can I compile my application using the new zlib interface, and 4. Can I compile my application using the new zlib interface, and
@@ -170,19 +165,19 @@ in the zlib distribution, or at the following location:
the K&R-style function prototypes, where the argument types the K&R-style function prototypes, where the argument types
are not specified; but that is another story for another day. are not specified; but that is another story for another day.
The fact that remains is that CDECL is the default convention. The remaining fact is that CDECL is the default convention.
Even if an explicit convention (such as STDCALL or FASTCALL) Even if an explicit convention is hard-coded into the function
is hard-coded into the function prototypes inside C headers, prototypes inside C headers, problems may appear. The
problems may appear. One problem, for example, deals with the necessity to expose the convention in users' callbacks is one
necessity to expose the convention in users' callbacks. of these problems.
The calling convention issues are also important when using The calling convention issues are also important when using
zlib in other programming languages. Some of them, like Ada zlib in other programming languages. Some of them, like Ada
(GNAT) and Fortran (GNU G77), have C bindings implemented (GNAT) and Fortran (GNU G77), have C bindings implemented
initially on Unix, and relying on the C calling convention. initially on Unix, and relying on the C calling convention.
On the other hand, the pre- .NET versions of Microsoft Visual On the other hand, the pre- .NET versions of Microsoft Visual
Basic require STDCALL, while Borland Delphi prefers (although Basic require STDCALL, while Borland Delphi prefers, although
it does not require) FASTCALL. it does not require, FASTCALL.
In fairness to all possible uses of zlib outside the C In fairness to all possible uses of zlib outside the C
programming language, we choose the default "C" convention. programming language, we choose the default "C" convention.
@@ -208,7 +203,14 @@ in the zlib distribution, or at the following location:
zlib distribution. zlib distribution.
8. If my application uses ZLIB1.DLL, should I link it to 8. I need to use zlib in my Microsoft .NET project. What can I
do?
- Henrik Ravn has contributed a .NET wrapper around zlib. Look
into contrib/dotzlib/, inside the zlib distribution.
9. If my application uses ZLIB1.DLL, should I link it to
MSVCRT.DLL? Why? MSVCRT.DLL? Why?
- It is not required, but it is recommended to link your - It is not required, but it is recommended to link your
@@ -223,8 +225,8 @@ in the zlib distribution, or at the following location:
depend on it should also be linked to MSVCRT.DLL. depend on it should also be linked to MSVCRT.DLL.
9. Why are you saying that ZLIB1.DLL and my application must be 10. Why are you saying that ZLIB1.DLL and my application should
linked to the same C run-time (CRT) library? I linked my be linked to the same C run-time (CRT) library? I linked my
application and my DLLs to different C libraries (e.g. my application and my DLLs to different C libraries (e.g. my
application to a static library, and my DLLs to MSVCRT.DLL), application to a static library, and my DLLs to MSVCRT.DLL),
and everything works fine. and everything works fine.
@@ -255,11 +257,11 @@ in the zlib distribution, or at the following location:
and DLLs are avoiding the corruption of each of the CRTs' and DLLs are avoiding the corruption of each of the CRTs'
internal states, maybe by careful design, or maybe by fortune. internal states, maybe by careful design, or maybe by fortune.
Also note that linking ZLIB1.DLL to non-Microsoft CRTs (such Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
as those provided by Borland) raises similar problems. as those provided by Borland, raises similar problems.
10. Why are you linking ZLIB1.DLL to MSVCRT.DLL? 11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
- MSVCRT.DLL exists on every Windows 95 with a new service pack - MSVCRT.DLL exists on every Windows 95 with a new service pack
installed, or with Microsoft Internet Explorer 4 or later, and installed, or with Microsoft Internet Explorer 4 or later, and
@@ -269,21 +271,14 @@ in the zlib distribution, or at the following location:
software provider for free. software provider for free.
The fact that MSVCRT.DLL does not exist on a virgin Windows 95 The fact that MSVCRT.DLL does not exist on a virgin Windows 95
is not so problematic. The number of Windows 95 installations is not so problematic. Windows 95 is scarcely found nowadays,
is rapidly decreasing, Microsoft stopped supporting it a long Microsoft ended its support a long time ago, and many recent
time ago, and many recent applications from various vendors, applications from various vendors, including Microsoft, do not
including Microsoft, do not even run on it. Furthermore, no even run on it. Furthermore, no serious user should run
serious user should run Windows 95 without a proper update Windows 95 without a proper update installed.
installed.
There is also the fact that the mainstream C compilers for
Windows are Microsoft Visual C++ 6.0, and gcc/MinGW. Both
are producing executables that link to MSVCRT.DLL by default,
without offering other dynamic CRTs as alternatives easy to
select by users.
11. Why are you not linking ZLIB1.DLL to 12. Why are you not linking ZLIB1.DLL to
<<my favorite C run-time library>> ? <<my favorite C run-time library>> ?
- We considered and abandoned the following alternatives: - We considered and abandoned the following alternatives:
@@ -294,27 +289,60 @@ in the zlib distribution, or at the following location:
to a static C library, you may as well consider linking zlib to a static C library, you may as well consider linking zlib
in statically, too. in statically, too.
* Linking ZLIB1.DLL to CRTDLL.DLL looks very appealing, * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
because CRTDLL.DLL is present on every Win32 installation. CRTDLL.DLL is present on every Win32 installation.
Unfortunately, it has a series of problems: it raises Unfortunately, it has a series of problems: it does not
difficulties when using it with C++ code, it does not work work properly with Microsoft's C++ libraries, it does not
with 64-bit file offsets, (and so on...), and Microsoft provide support for 64-bit file offsets, (and so on...),
discontinued its support a long time ago. and Microsoft discontinued its support a long time ago.
* Linking ZLIB1.DLL to MSVCR70.DLL, supplied with the * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
Microsoft .NET platform and Visual C++ 7.0 or newer, is not with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
a good option. Although it is available for free download raises problems related to the status of ZLIB1.DLL as a
and distribution, its presence is scarce on today's Win32 system component. According to the Microsoft Knowledge Base
installations. If it will ever become more popular than article KB326922 "INFO: Redistribution of the Shared C
MSVCRT.DLL and will be pre-installed on the future Win32 Runtime Component in Visual C++ .NET", MSVCR70.DLL and
systems, we will probably think again about it. MSVCR71.DLL are not supposed to function as system DLLs,
because they may clash with MSVCRT.DLL. Instead, the
application's installer is supposed to put these DLLs
(if needed) in the application's private directory.
If ZLIB1.DLL depends on a non-system runtime, it cannot
function as a redistributable system component.
* Linking ZLIB1.DLL to NTDLL.DLL is not possible. * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
NTDLL.DLL exports only a part of the C library, and only on Borland's, or Cygwin's, raises problems related to the
Windows NT systems. reliable presence of these runtimes on Win32 systems.
It's easier to let the DLL build of zlib up to the people
who distribute these runtimes, and who may proceed as
explained in the answer to Question 14.
12. I need to link my own DLL build to a CRT different than 13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
(Visual Studio .NET) or newer?
- Due to the problems explained in the Microsoft Knowledge Base
article KB326922 (see the previous answer), the C runtime that
comes with the VC7 environment is no longer considered a
system component. That is, it should not be assumed that this
runtime exists, or may be installed in a system directory.
Since ZLIB1.DLL is supposed to be a system component, it may
not depend on a non-system component.
In order to link ZLIB1.DLL and your application to MSVCRT.DLL
in VC7, you need the library of Visual C++ 6.0 or older. If
you don't have this library at hand, it's probably best not to
use ZLIB1.DLL.
We are hoping that, in the future, Microsoft will provide a
way to build applications linked to a proper system runtime,
from the Visual C++ environment. Until then, you have a
couple of alternatives, such as linking zlib in statically.
If your application requires dynamic linking, you may proceed
as explained in the answer to Question 14.
14. I need to link my own DLL build to a CRT different than
MSVCRT.DLL. What can I do? MSVCRT.DLL. What can I do?
- Feel free to rebuild the DLL from the zlib sources, and link - Feel free to rebuild the DLL from the zlib sources, and link
@@ -330,7 +358,7 @@ in the zlib distribution, or at the following location:
CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
13. May I include additional pieces of code that I find useful, 15. May I include additional pieces of code that I find useful,
link them in ZLIB1.DLL, and export them? link them in ZLIB1.DLL, and export them?
- No. A legitimate build of ZLIB1.DLL must not include code - No. A legitimate build of ZLIB1.DLL must not include code
@@ -338,14 +366,12 @@ in the zlib distribution, or at the following location:
But you can make your own private DLL build, under a different But you can make your own private DLL build, under a different
file name, as suggested in the previous answer. file name, as suggested in the previous answer.
For example, in Borland Delphi and C++ Builder, zlib is a part For example, zlib is a part of the VCL library, distributed
of the standard VCL library. If an application links to VCL with Borland Delphi and C++ Builder. The DLL build of VCL
dynamically, the name of the distributable binary (VCLxx.DLL) is a redistributable file, named VCLxx.DLL.
does not posess any danger of clashing with a legitimate but
incompatible ZLIB1.DLL.
14. May I remove some functionality out of ZLIB1.DLL, by enabling 16. May I remove some functionality out of ZLIB1.DLL, by enabling
macros like NO_GZCOMPRESS or NO_GZIP at compile time? macros like NO_GZCOMPRESS or NO_GZIP at compile time?
- No. A legitimate build of ZLIB1.DLL must provide the complete - No. A legitimate build of ZLIB1.DLL must provide the complete
@@ -354,7 +380,7 @@ in the zlib distribution, or at the following location:
different file name, as suggested in the previous answer. different file name, as suggested in the previous answer.
15. I made my own ZLIB1.DLL build. Can I test it for compliance? 17. I made my own ZLIB1.DLL build. Can I test it for compliance?
- We prefer that you download the official DLL from the zlib - We prefer that you download the official DLL from the zlib
web site. If you need something peculiar from this DLL, you web site. If you need something peculiar from this DLL, you

3
win32/VisualC.txt Normal file
View File

@@ -0,0 +1,3 @@
To build zlib using the Microsoft Visual C++ environment,
use the appropriate project from the projects/ directory.

Some files were not shown because too many files have changed in this diff Show More