zlib 1.2.2.3
diff --git a/ChangeLog b/ChangeLog
index d162e90..855303b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,27 @@
 
                 ChangeLog file for zlib
 
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
 Changes in 1.2.2.2 (30 December 2004)
 - Replace structure assignments in deflate.c and inflate.c with zmemcpy to
   avoid implicit memcpy calls (portability for no-library compilation)
diff --git a/Makefile b/Makefile
index 29f53de..535779d 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@
 
 LIBS=libz.a
 SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.2.2
+SHAREDLIBV=libz.so.1.2.2.3
 SHAREDLIBM=libz.so.1
 
 AR=ar rc
diff --git a/Makefile.in b/Makefile.in
index 29f53de..535779d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -30,7 +30,7 @@
 
 LIBS=libz.a
 SHAREDLIB=libz.so
-SHAREDLIBV=libz.so.1.2.2.2
+SHAREDLIBV=libz.so.1.2.2.3
 SHAREDLIBM=libz.so.1
 
 AR=ar rc
diff --git a/README b/README
index e91a7a4..9bba2e4 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.2.2 is a general purpose data compression library.  All the code is
+zlib 1.2.2.3 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -33,7 +33,7 @@
 issue of  Dr. Dobb's Journal; a copy of the article is available in
 http://dogma.net/markn/articles/zlibtool/zlibtool.htm
 
-The changes made in version 1.2.2.2 are documented in the file ChangeLog.
+The changes made in version 1.2.2.3 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory "contrib".
 
diff --git a/as400/zlib.inc b/as400/zlib.inc
index 04c3309..2905ee0 100644
--- a/as400/zlib.inc
+++ b/as400/zlib.inc
@@ -1,7 +1,7 @@
       *  ZLIB.INC - Interface to the general purpose compression library
       *
       *  ILE RPG400 version by Patrick Monnerat, DATASPHERE.
-      *  Version 1.2.2.2
+      *  Version 1.2.2.3
       *
       *
       *  WARNING:
@@ -20,8 +20,12 @@
       *                               Constants
       **************************************************************************
       *
-     D ZLIB_VERSION    C                   '1.2.2.2'                            Header's version
-     D ZLIB_VERNUM     C                   X'1222'
+      *  Versioning information.
+      *
+     D ZLIB_VERSION    C                   '1.2.2.3'
+     D ZLIB_VERNUM     C                   X'1223'
+      *
+      *  Other equates.
       *
      D Z_NO_FLUSH      C                   0
      D Z_SYNC_FLUSH    C                   2
diff --git a/contrib/README.contrib b/contrib/README.contrib
index 732d48c..20afc62 100644
--- a/contrib/README.contrib
+++ b/contrib/README.contrib
@@ -42,6 +42,10 @@
             and Chuck Walbourn <chuckw@kinesoft.com>
         asm code for Pentium Pro/PII, using the MASM syntax
 
+masmx64/    by Gilles Vollant <info@winimage.com>
+	x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+	replace longest_match() and inflate_fast()
+
 masmx86/    by Gilles Vollant <info@winimage.com>
         x86 asm code to replace longest_match() and inflate_fast(),
         for Visual C++ and MASM
diff --git a/contrib/asm586/match.S b/contrib/asm586/match.S
index 8f16140..371c9a0 100644
--- a/contrib/asm586/match.S
+++ b/contrib/asm586/match.S
@@ -1,354 +1,364 @@
-/* match.s -- Pentium-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define	match_init	_match_init
-#define	longest_match	_longest_match
-#endif
-
-#define	MAX_MATCH	(258)
-#define	MIN_MATCH	(3)
-#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
-#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define	wmask			0	/* local copy of s->wmask	*/
-#define	window			4	/* local copy of s->window	*/
-#define	windowbestlen		8	/* s->window + bestlen		*/
-#define	chainlenscanend		12	/* high word: current chain len	*/
-					/* low word: last bytes sought	*/
-#define	scanstart		16	/* first two bytes of string	*/
-#define	scanalign		20	/* dword-misalignment of string	*/
-#define	nicematch		24	/* a good enough match size	*/
-#define	bestlen			28	/* size of best match so far	*/
-#define	scan			32	/* ptr to string wanting match	*/
-
-#define	LocalVarsSize		(36)
-/*	saved ebx		36 */
-/*	saved edi		40 */
-/*	saved esi		44 */
-/*	saved ebp		48 */
-/*	return address		52 */
-#define	deflatestate		56	/* the function arguments	*/
-#define	curmatch		60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define	dsWSize			36
-#define	dsWMask			44
-#define	dsWindow		48
-#define	dsPrev			56
-#define	dsMatchLen		88
-#define	dsPrevMatch		92
-#define	dsStrStart		100
-#define	dsMatchStart		104
-#define	dsLookahead		108
-#define	dsPrevLen		112
-#define	dsMaxChainLen		116
-#define	dsGoodMatch		132
-#define	dsNiceMatch		136
-
-
-.file "match.S"
-
-.globl	match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to	*/
-/* make room for our stack frame.					*/
-
-		pushl	%ebp
-		pushl	%edi
-		pushl	%esi
-		pushl	%ebx
-		subl	$LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match		*/
-/* throughout the entire function. %edx will hold the pointer to the	*/
-/* deflate_state structure during the function's setup (before		*/
-/* entering the main loop).						*/
-
-		movl	deflatestate(%esp), %edx
-		movl	curmatch(%esp), %ecx
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
-
-		movl	dsNiceMatch(%edx), %eax
-		movl	dsLookahead(%edx), %ebx
-		cmpl	%eax, %ebx
-		jl	LookaheadLess
-		movl	%eax, %ebx
-LookaheadLess:	movl	%ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart;			*/
-
-		movl	dsWindow(%edx), %esi
-		movl	%esi, window(%esp)
-		movl	dsStrStart(%edx), %ebp
-		lea	(%esi,%ebp), %edi
-		movl	%edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being		*/
-/* dword-aligned.							*/
-
-		movl	%edi, %eax
-		negl	%eax
-		andl	$3, %eax
-		movl	%eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
-/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
-
-		movl	dsWSize(%edx), %eax
-		subl	$MIN_LOOKAHEAD, %eax
-		subl	%eax, %ebp
-		jg	LimitPositive
-		xorl	%ebp, %ebp
-LimitPositive:
-
-/* unsigned chain_length = s->max_chain_length;				*/
-/* if (s->prev_length >= s->good_match) {				*/
-/*     chain_length >>= 2;						*/
-/* }									*/
-
-		movl	dsPrevLen(%edx), %eax
-		movl	dsGoodMatch(%edx), %ebx
-		cmpl	%ebx, %eax
-		movl	dsMaxChainLen(%edx), %ebx
-		jl	LastMatchGood
-		shrl	$2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can	*/
-/* use the sign flag instead of the zero flag for the exit test.	*/
-/* It is then shifted into the high word, to make room for the scanend	*/
-/* scanend value, which it will always accompany.			*/
-
-		decl	%ebx
-		shll	$16, %ebx
-
-/* int best_len = s->prev_length;					*/
-
-		movl	dsPrevLen(%edx), %eax
-		movl	%eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
-
-		addl	%eax, %esi
-		movl	%esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan;				*/
-/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
-
-		movw	(%edi), %bx
-		movw	%bx, scanstart(%esp)
-		movw	-1(%edi,%eax), %bx
-		movl	%ebx, chainlenscanend(%esp)
-
-/* Posf *prev = s->prev;						*/
-/* uInt wmask = s->w_mask;						*/
-
-		movl	dsPrev(%edx), %edi
-		movl	dsWMask(%edx), %edx
-		mov	%edx, wmask(%esp)
-
-/* Jump into the main loop.						*/
-
-		jmp	LoopEntry
-
-.balign 16
-
-/* do {
- *     match = s->window + cur_match;
- *     if (*(ushf*)(match+best_len-1) != scan_end ||
- *         *(ushf*)match != scan_start) continue;
- *     [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- *          && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
- * %ecx = curmatch
- * %edx = curmatch & wmask
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- *
- * Two optimization notes on the choice of instructions:
- *
- * The first instruction uses a 16-bit address, which costs an extra,
- * unpairable cycle. This is cheaper than doing a 32-bit access and
- * zeroing the high word, due to the 3-cycle misalignment penalty which
- * would occur half the time. This also turns out to be cheaper than
- * doing two separate 8-bit accesses, as the memory is so rarely in the
- * L1 cache.
- *
- * The window buffer, however, apparently spends a lot of time in the
- * cache, and so it is faster to retrieve the word at the end of the
- * match string with two 8-bit loads. The instructions that test the
- * word at the beginning of the match string, however, are executed
- * much less frequently, and there it was cheaper to use 16-bit
- * instructions, which avoided the necessity of saving off and
- * subsequently reloading one of the other registers.
- */
-LookupLoop:
-							/* 1 U & V  */
-		movw	(%edi,%edx,2), %cx		/* 2 U pipe */
-		movl	wmask(%esp), %edx		/* 2 V pipe */
-		cmpl	%ebp, %ecx			/* 3 U pipe */
-		jbe	LeaveNow			/* 3 V pipe */
-		subl	$0x00010000, %ebx		/* 4 U pipe */
-		js	LeaveNow			/* 4 V pipe */
-LoopEntry:	movb	-1(%esi,%ecx), %al		/* 5 U pipe */
-		andl	%ecx, %edx			/* 5 V pipe */
-		cmpb	%bl, %al			/* 6 U pipe */
-		jnz	LookupLoop			/* 6 V pipe */
-		movb	(%esi,%ecx), %ah
-		cmpb	%bh, %ah
-		jnz	LookupLoop
-		movl	window(%esp), %eax
-		movw	(%eax,%ecx), %ax
-		cmpw	scanstart(%esp), %ax
-		jnz	LookupLoop
-
-/* Store the current value of chainlen.					*/
-
-		movl	%ebx, chainlenscanend(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we	*/
-/* are hoping to match it up with. In actuality, %esi and %edi are	*/
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
-/* initialized to -(MAX_MATCH_8 - scanalign).				*/
-
-		movl	window(%esp), %esi
-		movl	scan(%esp), %edi
-		addl	%ecx, %esi
-		movl	scanalign(%esp), %eax
-		movl	$(-MAX_MATCH_8), %edx
-		lea	MAX_MATCH_8(%edi,%eax), %edi
-		lea	MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
-		movl	(%esi,%edx), %eax
-		movl	(%edi,%edx), %ebx
-		xorl	%ebx, %eax
-		jnz	LeaveLoopCmps
-		movl	4(%esi,%edx), %eax
-		movl	4(%edi,%edx), %ebx
-		xorl	%ebx, %eax
-		jnz	LeaveLoopCmps4
-		addl	$8, %edx
-		jnz	LoopCmps
-		jmp	LenMaximum
-LeaveLoopCmps4:	addl	$4, %edx
-LeaveLoopCmps:	testl	$0x0000FFFF, %eax
-		jnz	LenLower
-		addl	$2, %edx
-		shrl	$16, %eax
-LenLower:	subb	$1, %al
-		adcl	$0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
-/* then automatically accept it as the best possible match and leave.	*/
-
-		lea	(%edi,%edx), %eax
-		movl	scan(%esp), %edi
-		subl	%edi, %eax
-		cmpl	$MAX_MATCH, %eax
-		jge	LenMaximum
-
-/* If the length of the match is not longer than the best match we	*/
-/* have so far, then forget it and return to the lookup loop.		*/
-
-		movl	deflatestate(%esp), %edx
-		movl	bestlen(%esp), %ebx
-		cmpl	%ebx, %eax
-		jg	LongerMatch
-		movl	chainlenscanend(%esp), %ebx
-		movl	windowbestlen(%esp), %esi
-		movl	dsPrev(%edx), %edi
-		movl	wmask(%esp), %edx
-		andl	%ecx, %edx
-		jmp	LookupLoop
-
-/*         s->match_start = cur_match;					*/
-/*         best_len = len;						*/
-/*         if (len >= nice_match) break;				*/
-/*         scan_end = *(ushf*)(scan+best_len-1);			*/
-
-LongerMatch:	movl	nicematch(%esp), %ebx
-		movl	%eax, bestlen(%esp)
-		movl	%ecx, dsMatchStart(%edx)
-		cmpl	%ebx, %eax
-		jge	LeaveNow
-		movl	window(%esp), %esi
-		addl	%eax, %esi
-		movl	%esi, windowbestlen(%esp)
-		movl	chainlenscanend(%esp), %ebx
-		movw	-1(%edi,%eax), %bx
-		movl	dsPrev(%edx), %edi
-		movl	%ebx, chainlenscanend(%esp)
-		movl	wmask(%esp), %edx
-		andl	%ecx, %edx
-		jmp	LookupLoop
-
-/* Accept the current string, with the maximum possible length.		*/
-
-LenMaximum:	movl	deflatestate(%esp), %edx
-		movl	$MAX_MATCH, bestlen(%esp)
-		movl	%ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
-/* return s->lookahead;							*/
-
-LeaveNow:
-		movl	deflatestate(%esp), %edx
-		movl	bestlen(%esp), %ebx
-		movl	dsLookahead(%edx), %eax
-		cmpl	%eax, %ebx
-		jg	LookaheadRet
-		movl	%ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came.			*/
-
-		addl	$LocalVarsSize, %esp
-		popl	%ebx
-		popl	%esi
-		popl	%edi
-		popl	%ebp
-match_init:	ret
+/* match.s -- Pentium-optimized version of longest_match()

+ * Written for zlib 1.1.2

+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>

+ *

+ * This is free software; you can redistribute it and/or modify it

+ * under the terms of the GNU General Public License.

+ */

+

+#ifndef NO_UNDERLINE

+#define	match_init	_match_init

+#define	longest_match	_longest_match

+#endif

+

+#define	MAX_MATCH	(258)

+#define	MIN_MATCH	(3)

+#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)

+#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)

+

+/* stack frame offsets */

+

+#define	wmask			0	/* local copy of s->wmask	*/

+#define	window			4	/* local copy of s->window	*/

+#define	windowbestlen		8	/* s->window + bestlen		*/

+#define	chainlenscanend		12	/* high word: current chain len	*/

+					/* low word: last bytes sought	*/

+#define	scanstart		16	/* first two bytes of string	*/

+#define	scanalign		20	/* dword-misalignment of string	*/

+#define	nicematch		24	/* a good enough match size	*/

+#define	bestlen			28	/* size of best match so far	*/

+#define	scan			32	/* ptr to string wanting match	*/

+

+#define	LocalVarsSize		(36)

+/*	saved ebx		36 */

+/*	saved edi		40 */

+/*	saved esi		44 */

+/*	saved ebp		48 */

+/*	return address		52 */

+#define	deflatestate		56	/* the function arguments	*/

+#define	curmatch		60

+

+/* Offsets for fields in the deflate_state structure. These numbers

+ * are calculated from the definition of deflate_state, with the

+ * assumption that the compiler will dword-align the fields. (Thus,

+ * changing the definition of deflate_state could easily cause this

+ * program to crash horribly, without so much as a warning at

+ * compile time. Sigh.)

+ */

+

+/* All the +zlib1222add offsets are due to the addition of fields

+ *  in zlib in the deflate_state structure since the asm code was first written

+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").

+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").

+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").

+ */

+

+#define zlib1222add		(8)

+

+#define	dsWSize			(36+zlib1222add)

+#define	dsWMask			(44+zlib1222add)

+#define	dsWindow		(48+zlib1222add)

+#define	dsPrev			(56+zlib1222add)

+#define	dsMatchLen		(88+zlib1222add)

+#define	dsPrevMatch		(92+zlib1222add)

+#define	dsStrStart		(100+zlib1222add)

+#define	dsMatchStart		(104+zlib1222add)

+#define	dsLookahead		(108+zlib1222add)

+#define	dsPrevLen		(112+zlib1222add)

+#define	dsMaxChainLen		(116+zlib1222add)

+#define	dsGoodMatch		(132+zlib1222add)

+#define	dsNiceMatch		(136+zlib1222add)

+

+

+.file "match.S"

+

+.globl	match_init, longest_match

+

+.text

+

+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */

+

+longest_match:

+

+/* Save registers that the compiler may be using, and adjust %esp to	*/

+/* make room for our stack frame.					*/

+

+		pushl	%ebp

+		pushl	%edi

+		pushl	%esi

+		pushl	%ebx

+		subl	$LocalVarsSize, %esp

+

+/* Retrieve the function arguments. %ecx will hold cur_match		*/

+/* throughout the entire function. %edx will hold the pointer to the	*/

+/* deflate_state structure during the function's setup (before		*/

+/* entering the main loop).						*/

+

+		movl	deflatestate(%esp), %edx

+		movl	curmatch(%esp), %ecx

+

+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/

+

+		movl	dsNiceMatch(%edx), %eax

+		movl	dsLookahead(%edx), %ebx

+		cmpl	%eax, %ebx

+		jl	LookaheadLess

+		movl	%eax, %ebx

+LookaheadLess:	movl	%ebx, nicematch(%esp)

+

+/* register Bytef *scan = s->window + s->strstart;			*/

+

+		movl	dsWindow(%edx), %esi

+		movl	%esi, window(%esp)

+		movl	dsStrStart(%edx), %ebp

+		lea	(%esi,%ebp), %edi

+		movl	%edi, scan(%esp)

+

+/* Determine how many bytes the scan ptr is off from being		*/

+/* dword-aligned.							*/

+

+		movl	%edi, %eax

+		negl	%eax

+		andl	$3, %eax

+		movl	%eax, scanalign(%esp)

+

+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/

+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/

+

+		movl	dsWSize(%edx), %eax

+		subl	$MIN_LOOKAHEAD, %eax

+		subl	%eax, %ebp

+		jg	LimitPositive

+		xorl	%ebp, %ebp

+LimitPositive:

+

+/* unsigned chain_length = s->max_chain_length;				*/

+/* if (s->prev_length >= s->good_match) {				*/

+/*     chain_length >>= 2;						*/

+/* }									*/

+

+		movl	dsPrevLen(%edx), %eax

+		movl	dsGoodMatch(%edx), %ebx

+		cmpl	%ebx, %eax

+		movl	dsMaxChainLen(%edx), %ebx

+		jl	LastMatchGood

+		shrl	$2, %ebx

+LastMatchGood:

+

+/* chainlen is decremented once beforehand so that the function can	*/

+/* use the sign flag instead of the zero flag for the exit test.	*/

+/* It is then shifted into the high word, to make room for the scanend	*/

+/* scanend value, which it will always accompany.			*/

+

+		decl	%ebx

+		shll	$16, %ebx

+

+/* int best_len = s->prev_length;					*/

+

+		movl	dsPrevLen(%edx), %eax

+		movl	%eax, bestlen(%esp)

+

+/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/

+

+		addl	%eax, %esi

+		movl	%esi, windowbestlen(%esp)

+

+/* register ush scan_start = *(ushf*)scan;				*/

+/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/

+

+		movw	(%edi), %bx

+		movw	%bx, scanstart(%esp)

+		movw	-1(%edi,%eax), %bx

+		movl	%ebx, chainlenscanend(%esp)

+

+/* Posf *prev = s->prev;						*/

+/* uInt wmask = s->w_mask;						*/

+

+		movl	dsPrev(%edx), %edi

+		movl	dsWMask(%edx), %edx

+		mov	%edx, wmask(%esp)

+

+/* Jump into the main loop.						*/

+

+		jmp	LoopEntry

+

+.balign 16

+

+/* do {

+ *     match = s->window + cur_match;

+ *     if (*(ushf*)(match+best_len-1) != scan_end ||

+ *         *(ushf*)match != scan_start) continue;

+ *     [...]

+ * } while ((cur_match = prev[cur_match & wmask]) > limit

+ *          && --chain_length != 0);

+ *

+ * Here is the inner loop of the function. The function will spend the

+ * majority of its time in this loop, and majority of that time will

+ * be spent in the first ten instructions.

+ *

+ * Within this loop:

+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)

+ * %ecx = curmatch

+ * %edx = curmatch & wmask

+ * %esi = windowbestlen - i.e., (window + bestlen)

+ * %edi = prev

+ * %ebp = limit

+ *

+ * Two optimization notes on the choice of instructions:

+ *

+ * The first instruction uses a 16-bit address, which costs an extra,

+ * unpairable cycle. This is cheaper than doing a 32-bit access and

+ * zeroing the high word, due to the 3-cycle misalignment penalty which

+ * would occur half the time. This also turns out to be cheaper than

+ * doing two separate 8-bit accesses, as the memory is so rarely in the

+ * L1 cache.

+ *

+ * The window buffer, however, apparently spends a lot of time in the

+ * cache, and so it is faster to retrieve the word at the end of the

+ * match string with two 8-bit loads. The instructions that test the

+ * word at the beginning of the match string, however, are executed

+ * much less frequently, and there it was cheaper to use 16-bit

+ * instructions, which avoided the necessity of saving off and

+ * subsequently reloading one of the other registers.

+ */

+LookupLoop:

+							/* 1 U & V  */

+		movw	(%edi,%edx,2), %cx		/* 2 U pipe */

+		movl	wmask(%esp), %edx		/* 2 V pipe */

+		cmpl	%ebp, %ecx			/* 3 U pipe */

+		jbe	LeaveNow			/* 3 V pipe */

+		subl	$0x00010000, %ebx		/* 4 U pipe */

+		js	LeaveNow			/* 4 V pipe */

+LoopEntry:	movb	-1(%esi,%ecx), %al		/* 5 U pipe */

+		andl	%ecx, %edx			/* 5 V pipe */

+		cmpb	%bl, %al			/* 6 U pipe */

+		jnz	LookupLoop			/* 6 V pipe */

+		movb	(%esi,%ecx), %ah

+		cmpb	%bh, %ah

+		jnz	LookupLoop

+		movl	window(%esp), %eax

+		movw	(%eax,%ecx), %ax

+		cmpw	scanstart(%esp), %ax

+		jnz	LookupLoop

+

+/* Store the current value of chainlen.					*/

+

+		movl	%ebx, chainlenscanend(%esp)

+

+/* Point %edi to the string under scrutiny, and %esi to the string we	*/

+/* are hoping to match it up with. In actuality, %esi and %edi are	*/

+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/

+/* initialized to -(MAX_MATCH_8 - scanalign).				*/

+

+		movl	window(%esp), %esi

+		movl	scan(%esp), %edi

+		addl	%ecx, %esi

+		movl	scanalign(%esp), %eax

+		movl	$(-MAX_MATCH_8), %edx

+		lea	MAX_MATCH_8(%edi,%eax), %edi

+		lea	MAX_MATCH_8(%esi,%eax), %esi

+

+/* Test the strings for equality, 8 bytes at a time. At the end,

+ * adjust %edx so that it is offset to the exact byte that mismatched.

+ *

+ * We already know at this point that the first three bytes of the

+ * strings match each other, and they can be safely passed over before

+ * starting the compare loop. So what this code does is skip over 0-3

+ * bytes, as much as necessary in order to dword-align the %edi

+ * pointer. (%esi will still be misaligned three times out of four.)

+ *

+ * It should be confessed that this loop usually does not represent

+ * much of the total running time. Replacing it with a more

+ * straightforward "rep cmpsb" would not drastically degrade

+ * performance.

+ */

+LoopCmps:

+		movl	(%esi,%edx), %eax

+		movl	(%edi,%edx), %ebx

+		xorl	%ebx, %eax

+		jnz	LeaveLoopCmps

+		movl	4(%esi,%edx), %eax

+		movl	4(%edi,%edx), %ebx

+		xorl	%ebx, %eax

+		jnz	LeaveLoopCmps4

+		addl	$8, %edx

+		jnz	LoopCmps

+		jmp	LenMaximum

+LeaveLoopCmps4:	addl	$4, %edx

+LeaveLoopCmps:	testl	$0x0000FFFF, %eax

+		jnz	LenLower

+		addl	$2, %edx

+		shrl	$16, %eax

+LenLower:	subb	$1, %al

+		adcl	$0, %edx

+

+/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/

+/* then automatically accept it as the best possible match and leave.	*/

+

+		lea	(%edi,%edx), %eax

+		movl	scan(%esp), %edi

+		subl	%edi, %eax

+		cmpl	$MAX_MATCH, %eax

+		jge	LenMaximum

+

+/* If the length of the match is not longer than the best match we	*/

+/* have so far, then forget it and return to the lookup loop.		*/

+

+		movl	deflatestate(%esp), %edx

+		movl	bestlen(%esp), %ebx

+		cmpl	%ebx, %eax

+		jg	LongerMatch

+		movl	chainlenscanend(%esp), %ebx

+		movl	windowbestlen(%esp), %esi

+		movl	dsPrev(%edx), %edi

+		movl	wmask(%esp), %edx

+		andl	%ecx, %edx

+		jmp	LookupLoop

+

+/*         s->match_start = cur_match;					*/

+/*         best_len = len;						*/

+/*         if (len >= nice_match) break;				*/

+/*         scan_end = *(ushf*)(scan+best_len-1);			*/

+

+LongerMatch:	movl	nicematch(%esp), %ebx

+		movl	%eax, bestlen(%esp)

+		movl	%ecx, dsMatchStart(%edx)

+		cmpl	%ebx, %eax

+		jge	LeaveNow

+		movl	window(%esp), %esi

+		addl	%eax, %esi

+		movl	%esi, windowbestlen(%esp)

+		movl	chainlenscanend(%esp), %ebx

+		movw	-1(%edi,%eax), %bx

+		movl	dsPrev(%edx), %edi

+		movl	%ebx, chainlenscanend(%esp)

+		movl	wmask(%esp), %edx

+		andl	%ecx, %edx

+		jmp	LookupLoop

+

+/* Accept the current string, with the maximum possible length.		*/

+

+LenMaximum:	movl	deflatestate(%esp), %edx

+		movl	$MAX_MATCH, bestlen(%esp)

+		movl	%ecx, dsMatchStart(%edx)

+

+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/

+/* return s->lookahead;							*/

+

+LeaveNow:

+		movl	deflatestate(%esp), %edx

+		movl	bestlen(%esp), %ebx

+		movl	dsLookahead(%edx), %eax

+		cmpl	%eax, %ebx

+		jg	LookaheadRet

+		movl	%ebx, %eax

+LookaheadRet:

+

+/* Restore the stack and return from whence we came.			*/

+

+		addl	$LocalVarsSize, %esp

+		popl	%ebx

+		popl	%esi

+		popl	%edi

+		popl	%ebp

+match_init:	ret

diff --git a/contrib/asm686/match.S b/contrib/asm686/match.S
index 8e86c33..c24be4d 100644
--- a/contrib/asm686/match.S
+++ b/contrib/asm686/match.S
@@ -1,327 +1,329 @@
-/* match.s -- Pentium-Pro-optimized version of longest_match()
- * Written for zlib 1.1.2
- * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License.
- */
-
-#ifndef NO_UNDERLINE
-#define	match_init	_match_init
-#define	longest_match	_longest_match
-#endif
-
-#define	MAX_MATCH	(258)
-#define	MIN_MATCH	(3)
-#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
-#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
-
-/* stack frame offsets */
-
-#define	chainlenwmask		0	/* high word: current chain len	*/
-					/* low word: s->wmask		*/
-#define	window			4	/* local copy of s->window	*/
-#define	windowbestlen		8	/* s->window + bestlen		*/
-#define	scanstart		16	/* first two bytes of string	*/
-#define	scanend			12	/* last two bytes of string	*/
-#define	scanalign		20	/* dword-misalignment of string	*/
-#define	nicematch		24	/* a good enough match size	*/
-#define	bestlen			28	/* size of best match so far	*/
-#define	scan			32	/* ptr to string wanting match	*/
-
-#define	LocalVarsSize		(36)
-/*	saved ebx		36 */
-/*	saved edi		40 */
-/*	saved esi		44 */
-/*	saved ebp		48 */
-/*	return address		52 */
-#define	deflatestate		56	/* the function arguments	*/
-#define	curmatch		60
-
-/* Offsets for fields in the deflate_state structure. These numbers
- * are calculated from the definition of deflate_state, with the
- * assumption that the compiler will dword-align the fields. (Thus,
- * changing the definition of deflate_state could easily cause this
- * program to crash horribly, without so much as a warning at
- * compile time. Sigh.)
- */
-#define	dsWSize			36
-#define	dsWMask			44
-#define	dsWindow		48
-#define	dsPrev			56
-#define	dsMatchLen		88
-#define	dsPrevMatch		92
-#define	dsStrStart		100
-#define	dsMatchStart		104
-#define	dsLookahead		108
-#define	dsPrevLen		112
-#define	dsMaxChainLen		116
-#define	dsGoodMatch		132
-#define	dsNiceMatch		136
-
-
-.file "match.S"
-
-.globl	match_init, longest_match
-
-.text
-
-/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-
-longest_match:
-
-/* Save registers that the compiler may be using, and adjust %esp to	*/
-/* make room for our stack frame.					*/
-
-		pushl	%ebp
-		pushl	%edi
-		pushl	%esi
-		pushl	%ebx
-		subl	$LocalVarsSize, %esp
-
-/* Retrieve the function arguments. %ecx will hold cur_match		*/
-/* throughout the entire function. %edx will hold the pointer to the	*/
-/* deflate_state structure during the function's setup (before		*/
-/* entering the main loop).						*/
-
-		movl	deflatestate(%esp), %edx
-		movl	curmatch(%esp), %ecx
-
-/* uInt wmask = s->w_mask;						*/
-/* unsigned chain_length = s->max_chain_length;				*/
-/* if (s->prev_length >= s->good_match) {				*/
-/*     chain_length >>= 2;						*/
-/* }									*/
-
-		movl	dsPrevLen(%edx), %eax
-		movl	dsGoodMatch(%edx), %ebx
-		cmpl	%ebx, %eax
-		movl	dsWMask(%edx), %eax
-		movl	dsMaxChainLen(%edx), %ebx
-		jl	LastMatchGood
-		shrl	$2, %ebx
-LastMatchGood:
-
-/* chainlen is decremented once beforehand so that the function can	*/
-/* use the sign flag instead of the zero flag for the exit test.	*/
-/* It is then shifted into the high word, to make room for the wmask	*/
-/* value, which it will always accompany.				*/
-
-		decl	%ebx
-		shll	$16, %ebx
-		orl	%eax, %ebx
-		movl	%ebx, chainlenwmask(%esp)
-
-/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
-
-		movl	dsNiceMatch(%edx), %eax
-		movl	dsLookahead(%edx), %ebx
-		cmpl	%eax, %ebx
-		jl	LookaheadLess
-		movl	%eax, %ebx
-LookaheadLess:	movl	%ebx, nicematch(%esp)
-
-/* register Bytef *scan = s->window + s->strstart;			*/
-
-		movl	dsWindow(%edx), %esi
-		movl	%esi, window(%esp)
-		movl	dsStrStart(%edx), %ebp
-		lea	(%esi,%ebp), %edi
-		movl	%edi, scan(%esp)
-
-/* Determine how many bytes the scan ptr is off from being		*/
-/* dword-aligned.							*/
-
-		movl	%edi, %eax
-		negl	%eax
-		andl	$3, %eax
-		movl	%eax, scanalign(%esp)
-
-/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
-/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
-
-		movl	dsWSize(%edx), %eax
-		subl	$MIN_LOOKAHEAD, %eax
-		subl	%eax, %ebp
-		jg	LimitPositive
-		xorl	%ebp, %ebp
-LimitPositive:
-
-/* int best_len = s->prev_length;					*/
-
-		movl	dsPrevLen(%edx), %eax
-		movl	%eax, bestlen(%esp)
-
-/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
-
-		addl	%eax, %esi
-		movl	%esi, windowbestlen(%esp)
-
-/* register ush scan_start = *(ushf*)scan;				*/
-/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
-/* Posf *prev = s->prev;						*/
-
-		movzwl	(%edi), %ebx
-		movl	%ebx, scanstart(%esp)
-		movzwl	-1(%edi,%eax), %ebx
-		movl	%ebx, scanend(%esp)
-		movl	dsPrev(%edx), %edi
-
-/* Jump into the main loop.						*/
-
-		movl	chainlenwmask(%esp), %edx
-		jmp	LoopEntry
-
-.balign 16
-
-/* do {
- *     match = s->window + cur_match;
- *     if (*(ushf*)(match+best_len-1) != scan_end ||
- *         *(ushf*)match != scan_start) continue;
- *     [...]
- * } while ((cur_match = prev[cur_match & wmask]) > limit
- *          && --chain_length != 0);
- *
- * Here is the inner loop of the function. The function will spend the
- * majority of its time in this loop, and majority of that time will
- * be spent in the first ten instructions.
- *
- * Within this loop:
- * %ebx = scanend
- * %ecx = curmatch
- * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
- * %esi = windowbestlen - i.e., (window + bestlen)
- * %edi = prev
- * %ebp = limit
- */
-LookupLoop:
-		andl	%edx, %ecx
-		movzwl	(%edi,%ecx,2), %ecx
-		cmpl	%ebp, %ecx
-		jbe	LeaveNow
-		subl	$0x00010000, %edx
-		js	LeaveNow
-LoopEntry:	movzwl	-1(%esi,%ecx), %eax
-		cmpl	%ebx, %eax
-		jnz	LookupLoop
-		movl	window(%esp), %eax
-		movzwl	(%eax,%ecx), %eax
-		cmpl	scanstart(%esp), %eax
-		jnz	LookupLoop
-
-/* Store the current value of chainlen.					*/
-
-		movl	%edx, chainlenwmask(%esp)
-
-/* Point %edi to the string under scrutiny, and %esi to the string we	*/
-/* are hoping to match it up with. In actuality, %esi and %edi are	*/
-/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
-/* initialized to -(MAX_MATCH_8 - scanalign).				*/
-
-		movl	window(%esp), %esi
-		movl	scan(%esp), %edi
-		addl	%ecx, %esi
-		movl	scanalign(%esp), %eax
-		movl	$(-MAX_MATCH_8), %edx
-		lea	MAX_MATCH_8(%edi,%eax), %edi
-		lea	MAX_MATCH_8(%esi,%eax), %esi
-
-/* Test the strings for equality, 8 bytes at a time. At the end,
- * adjust %edx so that it is offset to the exact byte that mismatched.
- *
- * We already know at this point that the first three bytes of the
- * strings match each other, and they can be safely passed over before
- * starting the compare loop. So what this code does is skip over 0-3
- * bytes, as much as necessary in order to dword-align the %edi
- * pointer. (%esi will still be misaligned three times out of four.)
- *
- * It should be confessed that this loop usually does not represent
- * much of the total running time. Replacing it with a more
- * straightforward "rep cmpsb" would not drastically degrade
- * performance.
- */
-LoopCmps:
-		movl	(%esi,%edx), %eax
-		xorl	(%edi,%edx), %eax
-		jnz	LeaveLoopCmps
-		movl	4(%esi,%edx), %eax
-		xorl	4(%edi,%edx), %eax
-		jnz	LeaveLoopCmps4
-		addl	$8, %edx
-		jnz	LoopCmps
-		jmp	LenMaximum
-LeaveLoopCmps4:	addl	$4, %edx
-LeaveLoopCmps:	testl	$0x0000FFFF, %eax
-		jnz	LenLower
-		addl	$2, %edx
-		shrl	$16, %eax
-LenLower:	subb	$1, %al
-		adcl	$0, %edx
-
-/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
-/* then automatically accept it as the best possible match and leave.	*/
-
-		lea	(%edi,%edx), %eax
-		movl	scan(%esp), %edi
-		subl	%edi, %eax
-		cmpl	$MAX_MATCH, %eax
-		jge	LenMaximum
-
-/* If the length of the match is not longer than the best match we	*/
-/* have so far, then forget it and return to the lookup loop.		*/
-
-		movl	deflatestate(%esp), %edx
-		movl	bestlen(%esp), %ebx
-		cmpl	%ebx, %eax
-		jg	LongerMatch
-		movl	windowbestlen(%esp), %esi
-		movl	dsPrev(%edx), %edi
-		movl	scanend(%esp), %ebx
-		movl	chainlenwmask(%esp), %edx
-		jmp	LookupLoop
-
-/*         s->match_start = cur_match;					*/
-/*         best_len = len;						*/
-/*         if (len >= nice_match) break;				*/
-/*         scan_end = *(ushf*)(scan+best_len-1);			*/
-
-LongerMatch:	movl	nicematch(%esp), %ebx
-		movl	%eax, bestlen(%esp)
-		movl	%ecx, dsMatchStart(%edx)
-		cmpl	%ebx, %eax
-		jge	LeaveNow
-		movl	window(%esp), %esi
-		addl	%eax, %esi
-		movl	%esi, windowbestlen(%esp)
-		movzwl	-1(%edi,%eax), %ebx
-		movl	dsPrev(%edx), %edi
-		movl	%ebx, scanend(%esp)
-		movl	chainlenwmask(%esp), %edx
-		jmp	LookupLoop
-
-/* Accept the current string, with the maximum possible length.		*/
-
-LenMaximum:	movl	deflatestate(%esp), %edx
-		movl	$MAX_MATCH, bestlen(%esp)
-		movl	%ecx, dsMatchStart(%edx)
-
-/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
-/* return s->lookahead;							*/
-
-LeaveNow:
-		movl	deflatestate(%esp), %edx
-		movl	bestlen(%esp), %ebx
-		movl	dsLookahead(%edx), %eax
-		cmpl	%eax, %ebx
-		jg	LookaheadRet
-		movl	%ebx, %eax
-LookaheadRet:
-
-/* Restore the stack and return from whence we came.			*/
-
-		addl	$LocalVarsSize, %esp
-		popl	%ebx
-		popl	%esi
-		popl	%edi
-		popl	%ebp
-match_init:	ret
+/* match.s -- Pentium-Pro-optimized version of longest_match()

+ * Written for zlib 1.1.2

+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>

+ *

+ * This is free software; you can redistribute it and/or modify it

+ * under the terms of the GNU General Public License.

+ */

+

+#ifndef NO_UNDERLINE

+#define	match_init	_match_init

+#define	longest_match	_longest_match

+#endif

+

+#define	MAX_MATCH	(258)

+#define	MIN_MATCH	(3)

+#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)

+#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)

+

+/* stack frame offsets */

+

+#define	chainlenwmask		0	/* high word: current chain len	*/

+					/* low word: s->wmask		*/

+#define	window			4	/* local copy of s->window	*/

+#define	windowbestlen		8	/* s->window + bestlen		*/

+#define	scanstart		16	/* first two bytes of string	*/

+#define	scanend			12	/* last two bytes of string	*/

+#define	scanalign		20	/* dword-misalignment of string	*/

+#define	nicematch		24	/* a good enough match size	*/

+#define	bestlen			28	/* size of best match so far	*/

+#define	scan			32	/* ptr to string wanting match	*/

+

+#define	LocalVarsSize		(36)

+/*	saved ebx		36 */

+/*	saved edi		40 */

+/*	saved esi		44 */

+/*	saved ebp		48 */

+/*	return address		52 */

+#define	deflatestate		56	/* the function arguments	*/

+#define	curmatch		60

+

+/* All the +zlib1222add offsets are due to the addition of fields

+ *  in zlib in the deflate_state structure since the asm code was first written

+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").

+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").

+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").

+ */

+

+#define zlib1222add		(8)

+

+#define	dsWSize			(36+zlib1222add)

+#define	dsWMask			(44+zlib1222add)

+#define	dsWindow		(48+zlib1222add)

+#define	dsPrev			(56+zlib1222add)

+#define	dsMatchLen		(88+zlib1222add)

+#define	dsPrevMatch		(92+zlib1222add)

+#define	dsStrStart		(100+zlib1222add)

+#define	dsMatchStart		(104+zlib1222add)

+#define	dsLookahead		(108+zlib1222add)

+#define	dsPrevLen		(112+zlib1222add)

+#define	dsMaxChainLen		(116+zlib1222add)

+#define	dsGoodMatch		(132+zlib1222add)

+#define	dsNiceMatch		(136+zlib1222add)

+

+

+.file "match.S"

+

+.globl	match_init, longest_match

+

+.text

+

+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */

+

+longest_match:

+

+/* Save registers that the compiler may be using, and adjust %esp to	*/

+/* make room for our stack frame.					*/

+

+		pushl	%ebp

+		pushl	%edi

+		pushl	%esi

+		pushl	%ebx

+		subl	$LocalVarsSize, %esp

+

+/* Retrieve the function arguments. %ecx will hold cur_match		*/

+/* throughout the entire function. %edx will hold the pointer to the	*/

+/* deflate_state structure during the function's setup (before		*/

+/* entering the main loop).						*/

+

+		movl	deflatestate(%esp), %edx

+		movl	curmatch(%esp), %ecx

+

+/* uInt wmask = s->w_mask;						*/

+/* unsigned chain_length = s->max_chain_length;				*/

+/* if (s->prev_length >= s->good_match) {				*/

+/*     chain_length >>= 2;						*/

+/* }									*/

+

+		movl	dsPrevLen(%edx), %eax

+		movl	dsGoodMatch(%edx), %ebx

+		cmpl	%ebx, %eax

+		movl	dsWMask(%edx), %eax

+		movl	dsMaxChainLen(%edx), %ebx

+		jl	LastMatchGood

+		shrl	$2, %ebx

+LastMatchGood:

+

+/* chainlen is decremented once beforehand so that the function can	*/

+/* use the sign flag instead of the zero flag for the exit test.	*/

+/* It is then shifted into the high word, to make room for the wmask	*/

+/* value, which it will always accompany.				*/

+

+		decl	%ebx

+		shll	$16, %ebx

+		orl	%eax, %ebx

+		movl	%ebx, chainlenwmask(%esp)

+

+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/

+

+		movl	dsNiceMatch(%edx), %eax

+		movl	dsLookahead(%edx), %ebx

+		cmpl	%eax, %ebx

+		jl	LookaheadLess

+		movl	%eax, %ebx

+LookaheadLess:	movl	%ebx, nicematch(%esp)

+

+/* register Bytef *scan = s->window + s->strstart;			*/

+

+		movl	dsWindow(%edx), %esi

+		movl	%esi, window(%esp)

+		movl	dsStrStart(%edx), %ebp

+		lea	(%esi,%ebp), %edi

+		movl	%edi, scan(%esp)

+

+/* Determine how many bytes the scan ptr is off from being		*/

+/* dword-aligned.							*/

+

+		movl	%edi, %eax

+		negl	%eax

+		andl	$3, %eax

+		movl	%eax, scanalign(%esp)

+

+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/

+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/

+

+		movl	dsWSize(%edx), %eax

+		subl	$MIN_LOOKAHEAD, %eax

+		subl	%eax, %ebp

+		jg	LimitPositive

+		xorl	%ebp, %ebp

+LimitPositive:

+

+/* int best_len = s->prev_length;					*/

+

+		movl	dsPrevLen(%edx), %eax

+		movl	%eax, bestlen(%esp)

+

+/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/

+

+		addl	%eax, %esi

+		movl	%esi, windowbestlen(%esp)

+

+/* register ush scan_start = *(ushf*)scan;				*/

+/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/

+/* Posf *prev = s->prev;						*/

+

+		movzwl	(%edi), %ebx

+		movl	%ebx, scanstart(%esp)

+		movzwl	-1(%edi,%eax), %ebx

+		movl	%ebx, scanend(%esp)

+		movl	dsPrev(%edx), %edi

+

+/* Jump into the main loop.						*/

+

+		movl	chainlenwmask(%esp), %edx

+		jmp	LoopEntry

+

+.balign 16

+

+/* do {

+ *     match = s->window + cur_match;

+ *     if (*(ushf*)(match+best_len-1) != scan_end ||

+ *         *(ushf*)match != scan_start) continue;

+ *     [...]

+ * } while ((cur_match = prev[cur_match & wmask]) > limit

+ *          && --chain_length != 0);

+ *

+ * Here is the inner loop of the function. The function will spend the

+ * majority of its time in this loop, and majority of that time will

+ * be spent in the first ten instructions.

+ *

+ * Within this loop:

+ * %ebx = scanend

+ * %ecx = curmatch

+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)

+ * %esi = windowbestlen - i.e., (window + bestlen)

+ * %edi = prev

+ * %ebp = limit

+ */

+LookupLoop:

+		andl	%edx, %ecx

+		movzwl	(%edi,%ecx,2), %ecx

+		cmpl	%ebp, %ecx

+		jbe	LeaveNow

+		subl	$0x00010000, %edx

+		js	LeaveNow

+LoopEntry:	movzwl	-1(%esi,%ecx), %eax

+		cmpl	%ebx, %eax

+		jnz	LookupLoop

+		movl	window(%esp), %eax

+		movzwl	(%eax,%ecx), %eax

+		cmpl	scanstart(%esp), %eax

+		jnz	LookupLoop

+

+/* Store the current value of chainlen.					*/

+

+		movl	%edx, chainlenwmask(%esp)

+

+/* Point %edi to the string under scrutiny, and %esi to the string we	*/

+/* are hoping to match it up with. In actuality, %esi and %edi are	*/

+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/

+/* initialized to -(MAX_MATCH_8 - scanalign).				*/

+

+		movl	window(%esp), %esi

+		movl	scan(%esp), %edi

+		addl	%ecx, %esi

+		movl	scanalign(%esp), %eax

+		movl	$(-MAX_MATCH_8), %edx

+		lea	MAX_MATCH_8(%edi,%eax), %edi

+		lea	MAX_MATCH_8(%esi,%eax), %esi

+

+/* Test the strings for equality, 8 bytes at a time. At the end,

+ * adjust %edx so that it is offset to the exact byte that mismatched.

+ *

+ * We already know at this point that the first three bytes of the

+ * strings match each other, and they can be safely passed over before

+ * starting the compare loop. So what this code does is skip over 0-3

+ * bytes, as much as necessary in order to dword-align the %edi

+ * pointer. (%esi will still be misaligned three times out of four.)

+ *

+ * It should be confessed that this loop usually does not represent

+ * much of the total running time. Replacing it with a more

+ * straightforward "rep cmpsb" would not drastically degrade

+ * performance.

+ */

+LoopCmps:

+		movl	(%esi,%edx), %eax

+		xorl	(%edi,%edx), %eax

+		jnz	LeaveLoopCmps

+		movl	4(%esi,%edx), %eax

+		xorl	4(%edi,%edx), %eax

+		jnz	LeaveLoopCmps4

+		addl	$8, %edx

+		jnz	LoopCmps

+		jmp	LenMaximum

+LeaveLoopCmps4:	addl	$4, %edx

+LeaveLoopCmps:	testl	$0x0000FFFF, %eax

+		jnz	LenLower

+		addl	$2, %edx

+		shrl	$16, %eax

+LenLower:	subb	$1, %al

+		adcl	$0, %edx

+

+/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/

+/* then automatically accept it as the best possible match and leave.	*/

+

+		lea	(%edi,%edx), %eax

+		movl	scan(%esp), %edi

+		subl	%edi, %eax

+		cmpl	$MAX_MATCH, %eax

+		jge	LenMaximum

+

+/* If the length of the match is not longer than the best match we	*/

+/* have so far, then forget it and return to the lookup loop.		*/

+

+		movl	deflatestate(%esp), %edx

+		movl	bestlen(%esp), %ebx

+		cmpl	%ebx, %eax

+		jg	LongerMatch

+		movl	windowbestlen(%esp), %esi

+		movl	dsPrev(%edx), %edi

+		movl	scanend(%esp), %ebx

+		movl	chainlenwmask(%esp), %edx

+		jmp	LookupLoop

+

+/*         s->match_start = cur_match;					*/

+/*         best_len = len;						*/

+/*         if (len >= nice_match) break;				*/

+/*         scan_end = *(ushf*)(scan+best_len-1);			*/

+

+LongerMatch:	movl	nicematch(%esp), %ebx

+		movl	%eax, bestlen(%esp)

+		movl	%ecx, dsMatchStart(%edx)

+		cmpl	%ebx, %eax

+		jge	LeaveNow

+		movl	window(%esp), %esi

+		addl	%eax, %esi

+		movl	%esi, windowbestlen(%esp)

+		movzwl	-1(%edi,%eax), %ebx

+		movl	dsPrev(%edx), %edi

+		movl	%ebx, scanend(%esp)

+		movl	chainlenwmask(%esp), %edx

+		jmp	LookupLoop

+

+/* Accept the current string, with the maximum possible length.		*/

+

+LenMaximum:	movl	deflatestate(%esp), %edx

+		movl	$MAX_MATCH, bestlen(%esp)

+		movl	%ecx, dsMatchStart(%edx)

+

+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/

+/* return s->lookahead;							*/

+

+LeaveNow:

+		movl	deflatestate(%esp), %edx

+		movl	bestlen(%esp), %ebx

+		movl	dsLookahead(%edx), %eax

+		cmpl	%eax, %ebx

+		jg	LookaheadRet

+		movl	%ebx, %eax

+LookaheadRet:

+

+/* Restore the stack and return from whence we came.			*/

+

+		addl	$LocalVarsSize, %esp

+		popl	%ebx

+		popl	%esi

+		popl	%edi

+		popl	%ebp

+match_init:	ret

diff --git a/contrib/infback9/infback9.h b/contrib/infback9/infback9.h
index 10bf58c..1073c0a 100644
--- a/contrib/infback9/infback9.h
+++ b/contrib/infback9/infback9.h
@@ -16,6 +16,10 @@
  * zlib.h must be included before this header file.
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
                                     in_func in, void FAR *in_desc,
                                     out_func out, void FAR *out_desc));
@@ -27,3 +31,7 @@
 #define inflateBack9Init(strm, window) \
         inflateBack9Init_((strm), (window), \
         ZLIB_VERSION, sizeof(z_stream))
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/infback9/inftree9.c b/contrib/infback9/inftree9.c
index 29bef6a..ac4575c 100644
--- a/contrib/infback9/inftree9.c
+++ b/contrib/infback9/inftree9.c
@@ -1,5 +1,5 @@
 /* inftree9.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -9,7 +9,7 @@
 #define MAXBITS 15
 
 const char inflate9_copyright[] =
-   " inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler ";
+   " inflate9 1.2.2.3 Copyright 1995-2005 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
         130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
-        133, 133, 133, 133, 144, 72, 199};
+        133, 133, 133, 133, 144, 66, 71};
     static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
         65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
diff --git a/contrib/masm686/match.asm b/contrib/masm686/match.asm
index 2287804..4b03a71 100644
--- a/contrib/masm686/match.asm
+++ b/contrib/masm686/match.asm
@@ -1,408 +1,413 @@
-
-; match.asm -- Pentium-Pro optimized version of longest_match()
-;
-; Updated for zlib 1.1.3 and converted to MASM 6.1x
-; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
-;                    and Chuck Walbourn <chuckw@kinesoft.com>
-; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
-;
-; This is free software; you can redistribute it and/or modify it
-; under the terms of the GNU General Public License.
-
-; Based on match.S
-; Written for zlib 1.1.2
-; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-
-	.686P
-	.MODEL	FLAT
-
-;===========================================================================
-; EQUATES
-;===========================================================================
-
-MAX_MATCH	EQU 258
-MIN_MATCH	EQU 3
-MIN_LOOKAHEAD	EQU (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8	EQU ((MAX_MATCH + 7) AND (NOT 7))
-
-;===========================================================================
-; STRUCTURES
-;===========================================================================
-
-; This STRUCT assumes a 4-byte alignment
-
-DEFLATE_STATE	STRUCT
-ds_strm			dd ?
-ds_status		dd ?
-ds_pending_buf		dd ?
-ds_pending_buf_size	dd ?
-ds_pending_out		dd ?
-ds_pending		dd ?
-ds_wrap			dd ?
-ds_data_type		db ?
-ds_method		db ?
-			db ?	; padding
-			db ?	; padding
-ds_last_flush		dd ?
-ds_w_size		dd ?	; used
-ds_w_bits		dd ?
-ds_w_mask		dd ?	; used
-ds_window		dd ?	; used
-ds_window_size		dd ?
-ds_prev			dd ?	; used
-ds_head			dd ?
-ds_ins_h		dd ?
-ds_hash_size		dd ?
-ds_hash_bits		dd ?
-ds_hash_mask		dd ?
-ds_hash_shift		dd ?
-ds_block_start		dd ?
-ds_match_length		dd ?	; used
-ds_prev_match		dd ?	; used
-ds_match_available	dd ?
-ds_strstart		dd ?	; used
-ds_match_start		dd ?	; used
-ds_lookahead		dd ?	; used
-ds_prev_length		dd ?	; used
-ds_max_chain_length	dd ?	; used
-ds_max_laxy_match	dd ?
-ds_level		dd ?
-ds_strategy		dd ?
-ds_good_match		dd ?	; used
-ds_nice_match		dd ?	; used
-
-; Don't need anymore of the struct for match
-DEFLATE_STATE	ENDS
-
-;===========================================================================
-; CODE
-;===========================================================================
-_TEXT	SEGMENT
-
-;---------------------------------------------------------------------------
-; match_init
-;---------------------------------------------------------------------------
-	ALIGN	4
-PUBLIC	_match_init
-_match_init	PROC
-	; no initialization needed
-	ret
-_match_init	ENDP
-
-;---------------------------------------------------------------------------
-; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-;---------------------------------------------------------------------------
-	ALIGN	4
-
-PUBLIC	_longest_match
-_longest_match	PROC
-
-; Since this code uses EBP for a scratch register, the stack frame must
-; be manually constructed and referenced relative to the ESP register.
-
-; Stack image
-; Variables
-chainlenwmask	=  0	; high word: current chain len
-			; low word: s->wmask
-window		=  4	; local copy of s->window
-windowbestlen	=  8	; s->window + bestlen
-scanend		= 12	; last two bytes of string
-scanstart	= 16	; first two bytes of string
-scanalign	= 20	; dword-misalignment of string
-nicematch	= 24	; a good enough match size
-bestlen		= 28	; size of best match so far
-scan		= 32	; ptr to string wanting match
-varsize		= 36	; number of bytes (also offset to last saved register)
-
-; Saved Registers (actually pushed into place)
-ebx_save	= 36
-edi_save	= 40
-esi_save	= 44
-ebp_save	= 48
-
-; Parameters
-retaddr		= 52
-deflatestate	= 56
-curmatch	= 60
-
-; Save registers that the compiler may be using
-	push	ebp
-	push	edi
-	push	esi
-	push	ebx
-
-; Allocate local variable space
-	sub	esp,varsize
-
-; Retrieve the function arguments. ecx will hold cur_match
-; throughout the entire function. edx will hold the pointer to the
-; deflate_state structure during the function's setup (before
-; entering the main loop).
-
-	mov	edx, [esp+deflatestate]
-ASSUME	edx:PTR DEFLATE_STATE
-
-	mov	ecx, [esp+curmatch]
-
-; uInt wmask = s->w_mask;
-; unsigned chain_length = s->max_chain_length;
-; if (s->prev_length >= s->good_match) {
-;     chain_length >>= 2;
-; }
-
-	mov	eax, [edx].ds_prev_length
-	mov	ebx, [edx].ds_good_match
-	cmp	eax, ebx
-	mov	eax, [edx].ds_w_mask
-	mov	ebx, [edx].ds_max_chain_length
-	jl	SHORT LastMatchGood
-	shr	ebx, 2
-LastMatchGood:
-
-; chainlen is decremented once beforehand so that the function can
-; use the sign flag instead of the zero flag for the exit test.
-; It is then shifted into the high word, to make room for the wmask
-; value, which it will always accompany.
-
-	dec	ebx
-	shl	ebx, 16
-	or	ebx, eax
-	mov	[esp+chainlenwmask], ebx
-
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-	mov	eax, [edx].ds_nice_match
-	mov	ebx, [edx].ds_lookahead
-	cmp	ebx, eax
-	jl	SHORT LookaheadLess
-	mov	ebx, eax
-LookaheadLess:
-	mov	[esp+nicematch], ebx
-
-;/* register Bytef *scan = s->window + s->strstart;                     */
-
-	mov	esi, [edx].ds_window
-	mov	[esp+window], esi
-	mov	ebp, [edx].ds_strstart
-	lea	edi, [esi+ebp]
-	mov	[esp+scan],edi
-
-;/* Determine how many bytes the scan ptr is off from being             */
-;/* dword-aligned.                                                      */
-
-	mov	eax, edi
-	neg	eax
-	and	eax, 3
-	mov	[esp+scanalign], eax
-
-;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?                      */
-;/*     s->strstart - (IPos)MAX_DIST(s) : NIL;                          */
-
-	mov	eax, [edx].ds_w_size
-	sub	eax, MIN_LOOKAHEAD
-	sub	ebp, eax
-	jg	SHORT LimitPositive
-	xor	ebp, ebp
-LimitPositive:
-
-;/* int best_len = s->prev_length;                                      */
-
-	mov	eax, [edx].ds_prev_length
-	mov	[esp+bestlen], eax
-
-;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-
-	add	esi, eax
-	mov	[esp+windowbestlen], esi
-
-;/* register ush scan_start = *(ushf*)scan;                             */
-;/* register ush scan_end   = *(ushf*)(scan+best_len-1);                */
-;/* Posf *prev = s->prev;                                               */
-
-	movzx	ebx, WORD PTR[edi]
-	mov	[esp+scanstart], ebx
-	movzx	ebx, WORD PTR[eax+edi-1]
-	mov	[esp+scanend], ebx
-	mov	edi, [edx].ds_prev
-
-;/* Jump into the main loop.                                            */
-
-	mov	edx, [esp+chainlenwmask]
-	jmp	SHORT LoopEntry
-
-;/* do {
-; *     match = s->window + cur_match;
-; *     if (*(ushf*)(match+best_len-1) != scan_end ||
-; *         *(ushf*)match != scan_start) continue;
-; *     [...]
-; * } while ((cur_match = prev[cur_match & wmask]) > limit
-; *          && --chain_length != 0);
-; *
-; * Here is the inner loop of the function. The function will spend the
-; * majority of its time in this loop, and majority of that time will
-; * be spent in the first ten instructions.
-; *
-; * Within this loop:
-; * %ebx = scanend
-; * %ecx = curmatch
-; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-; * %esi = windowbestlen - i.e., (window + bestlen)
-; * %edi = prev
-; * %ebp = limit
-; */
-
-	ALIGN	4
-LookupLoop:
-	and	ecx, edx
-	movzx	ecx, WORD PTR[edi+ecx*2]
-	cmp	ecx, ebp
-	jbe	LeaveNow
-	sub	edx, 000010000H
-	js	LeaveNow
-
-LoopEntry:
-	movzx	eax, WORD PTR[esi+ecx-1]
-	cmp	eax, ebx
-	jnz	SHORT LookupLoop
-
-	mov	eax, [esp+window]
-	movzx	eax, WORD PTR[eax+ecx]
-	cmp	eax, [esp+scanstart]
-	jnz	SHORT LookupLoop
-
-;/* Store the current value of chainlen.                                */
-
-	mov	[esp+chainlenwmask], edx
-
-;/* Point %edi to the string under scrutiny, and %esi to the string we  */
-;/* are hoping to match it up with. In actuality, %esi and %edi are     */
-;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is     */
-;/* initialized to -(MAX_MATCH_8 - scanalign).                          */
-
-	mov	esi, [esp+window]
-	mov	edi, [esp+scan]
-	add	esi, ecx
-	mov	eax, [esp+scanalign]
-	mov	edx, -MAX_MATCH_8
-	lea	edi, [edi+eax+MAX_MATCH_8]
-	lea	esi, [esi+eax+MAX_MATCH_8]
-
-;/* Test the strings for equality, 8 bytes at a time. At the end,
-; * adjust %edx so that it is offset to the exact byte that mismatched.
-; *
-; * We already know at this point that the first three bytes of the
-; * strings match each other, and they can be safely passed over before
-; * starting the compare loop. So what this code does is skip over 0-3
-; * bytes, as much as necessary in order to dword-align the %edi
-; * pointer. (%esi will still be misaligned three times out of four.)
-; *
-; * It should be confessed that this loop usually does not represent
-; * much of the total running time. Replacing it with a more
-; * straightforward "rep cmpsb" would not drastically degrade
-; * performance.
-; */
-
-LoopCmps:
-	mov	eax, DWORD PTR[esi+edx]
-	xor	eax, DWORD PTR[edi+edx]
-	jnz	SHORT LeaveLoopCmps
-
-	mov	eax, DWORD PTR[esi+edx+4]
-	xor	eax, DWORD PTR[edi+edx+4]
-	jnz	SHORT LeaveLoopCmps4
-
-	add	edx, 8
-	jnz	SHORT LoopCmps
-	jmp	LenMaximum
-	ALIGN	4
-
-LeaveLoopCmps4:
-	add	edx, 4
-
-LeaveLoopCmps:
-	test	eax, 00000FFFFH
-	jnz	SHORT LenLower
-
-	add	edx, 2
-	shr	eax, 16
-
-LenLower:
-	sub	al, 1
-	adc	edx, 0
-
-;/* Calculate the length of the match. If it is longer than MAX_MATCH,  */
-;/* then automatically accept it as the best possible match and leave.  */
-
-	lea	eax, [edi+edx]
-	mov	edi, [esp+scan]
-	sub	eax, edi
-	cmp	eax, MAX_MATCH
-	jge	SHORT LenMaximum
-
-;/* If the length of the match is not longer than the best match we     */
-;/* have so far, then forget it and return to the lookup loop.          */
-
-	mov	edx, [esp+deflatestate]
-	mov	ebx, [esp+bestlen]
-	cmp	eax, ebx
-	jg	SHORT LongerMatch
-	mov	esi, [esp+windowbestlen]
-	mov	edi, [edx].ds_prev
-	mov	ebx, [esp+scanend]
-	mov	edx, [esp+chainlenwmask]
-	jmp	LookupLoop
-	ALIGN	4
-
-;/*         s->match_start = cur_match;                                 */
-;/*         best_len = len;                                             */
-;/*         if (len >= nice_match) break;                               */
-;/*         scan_end = *(ushf*)(scan+best_len-1);                       */
-
-LongerMatch:
-	mov	ebx, [esp+nicematch]
-	mov	[esp+bestlen], eax
-	mov	[edx].ds_match_start, ecx
-	cmp	eax, ebx
-	jge	SHORT LeaveNow
-	mov	esi, [esp+window]
-	add	esi, eax
-	mov	[esp+windowbestlen], esi
-	movzx	ebx, WORD PTR[edi+eax-1]
-	mov	edi, [edx].ds_prev
-	mov	[esp+scanend], ebx
-	mov	edx, [esp+chainlenwmask]
-	jmp	LookupLoop
-	ALIGN	4
-
-;/* Accept the current string, with the maximum possible length.        */
-
-LenMaximum:
-	mov	edx, [esp+deflatestate]
-	mov	DWORD PTR[esp+bestlen], MAX_MATCH
-	mov	[edx].ds_match_start, ecx
-
-;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;          */
-;/* return s->lookahead;                                                */
-
-LeaveNow:
-	mov	edx, [esp+deflatestate]
-	mov	ebx, [esp+bestlen]
-	mov	eax, [edx].ds_lookahead
-	cmp	ebx, eax
-	jg	SHORT LookaheadRet
-	mov	eax, ebx
-LookaheadRet:
-
-; Restore the stack and return from whence we came.
-
-	add	esp, varsize
-	pop	ebx
-	pop	esi
-	pop	edi
-	pop	ebp
-	ret
-
-_longest_match	ENDP
-
-_TEXT	ENDS
-END
+

+; match.asm -- Pentium-Pro optimized version of longest_match()

+;

+; Updated for zlib 1.1.3 and converted to MASM 6.1x

+; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>

+;                    and Chuck Walbourn <chuckw@kinesoft.com>

+; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>

+;

+; This is free software; you can redistribute it and/or modify it

+; under the terms of the GNU General Public License.

+

+; Based on match.S

+; Written for zlib 1.1.2

+; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>

+;

+; Modified by Gilles Vollant (2005) for add gzhead and gzindex

+

+	.686P

+	.MODEL	FLAT

+

+;===========================================================================

+; EQUATES

+;===========================================================================

+

+MAX_MATCH	EQU 258

+MIN_MATCH	EQU 3

+MIN_LOOKAHEAD	EQU (MAX_MATCH + MIN_MATCH + 1)

+MAX_MATCH_8	EQU ((MAX_MATCH + 7) AND (NOT 7))

+

+;===========================================================================

+; STRUCTURES

+;===========================================================================

+

+; This STRUCT assumes a 4-byte alignment

+

+DEFLATE_STATE	STRUCT

+ds_strm			dd ?

+ds_status		dd ?

+ds_pending_buf		dd ?

+ds_pending_buf_size	dd ?

+ds_pending_out		dd ?

+ds_pending		dd ?

+ds_wrap			dd ?

+; gzhead and gzindex are added in zlib 1.2.2.2 (see deflate.h)

+ds_gzhead               dd ?

+ds_gzindex              dd ?

+ds_data_type		db ?

+ds_method		db ?

+			db ?	; padding

+			db ?	; padding

+ds_last_flush		dd ?

+ds_w_size		dd ?	; used

+ds_w_bits		dd ?

+ds_w_mask		dd ?	; used

+ds_window		dd ?	; used

+ds_window_size		dd ?

+ds_prev			dd ?	; used

+ds_head			dd ?

+ds_ins_h		dd ?

+ds_hash_size		dd ?

+ds_hash_bits		dd ?

+ds_hash_mask		dd ?

+ds_hash_shift		dd ?

+ds_block_start		dd ?

+ds_match_length		dd ?	; used

+ds_prev_match		dd ?	; used

+ds_match_available	dd ?

+ds_strstart		dd ?	; used

+ds_match_start		dd ?	; used

+ds_lookahead		dd ?	; used

+ds_prev_length		dd ?	; used

+ds_max_chain_length	dd ?	; used

+ds_max_laxy_match	dd ?

+ds_level		dd ?

+ds_strategy		dd ?

+ds_good_match		dd ?	; used

+ds_nice_match		dd ?	; used

+

+; Don't need anymore of the struct for match

+DEFLATE_STATE	ENDS

+

+;===========================================================================

+; CODE

+;===========================================================================

+_TEXT	SEGMENT

+

+;---------------------------------------------------------------------------

+; match_init

+;---------------------------------------------------------------------------

+	ALIGN	4

+PUBLIC	_match_init

+_match_init	PROC

+	; no initialization needed

+	ret

+_match_init	ENDP

+

+;---------------------------------------------------------------------------

+; uInt longest_match(deflate_state *deflatestate, IPos curmatch)

+;---------------------------------------------------------------------------

+	ALIGN	4

+

+PUBLIC	_longest_match

+_longest_match	PROC

+

+; Since this code uses EBP for a scratch register, the stack frame must

+; be manually constructed and referenced relative to the ESP register.

+

+; Stack image

+; Variables

+chainlenwmask	=  0	; high word: current chain len

+			; low word: s->wmask

+window		=  4	; local copy of s->window

+windowbestlen	=  8	; s->window + bestlen

+scanend		= 12	; last two bytes of string

+scanstart	= 16	; first two bytes of string

+scanalign	= 20	; dword-misalignment of string

+nicematch	= 24	; a good enough match size

+bestlen		= 28	; size of best match so far

+scan		= 32	; ptr to string wanting match

+varsize		= 36	; number of bytes (also offset to last saved register)

+

+; Saved Registers (actually pushed into place)

+ebx_save	= 36

+edi_save	= 40

+esi_save	= 44

+ebp_save	= 48

+

+; Parameters

+retaddr		= 52

+deflatestate	= 56

+curmatch	= 60

+

+; Save registers that the compiler may be using

+	push	ebp

+	push	edi

+	push	esi

+	push	ebx

+

+; Allocate local variable space

+	sub	esp,varsize

+

+; Retrieve the function arguments. ecx will hold cur_match

+; throughout the entire function. edx will hold the pointer to the

+; deflate_state structure during the function's setup (before

+; entering the main loop).

+

+	mov	edx, [esp+deflatestate]

+ASSUME	edx:PTR DEFLATE_STATE

+

+	mov	ecx, [esp+curmatch]

+

+; uInt wmask = s->w_mask;

+; unsigned chain_length = s->max_chain_length;

+; if (s->prev_length >= s->good_match) {

+;     chain_length >>= 2;

+; }

+

+	mov	eax, [edx].ds_prev_length

+	mov	ebx, [edx].ds_good_match

+	cmp	eax, ebx

+	mov	eax, [edx].ds_w_mask

+	mov	ebx, [edx].ds_max_chain_length

+	jl	SHORT LastMatchGood

+	shr	ebx, 2

+LastMatchGood:

+

+; chainlen is decremented once beforehand so that the function can

+; use the sign flag instead of the zero flag for the exit test.

+; It is then shifted into the high word, to make room for the wmask

+; value, which it will always accompany.

+

+	dec	ebx

+	shl	ebx, 16

+	or	ebx, eax

+	mov	[esp+chainlenwmask], ebx

+

+; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

+

+	mov	eax, [edx].ds_nice_match

+	mov	ebx, [edx].ds_lookahead

+	cmp	ebx, eax

+	jl	SHORT LookaheadLess

+	mov	ebx, eax

+LookaheadLess:

+	mov	[esp+nicematch], ebx

+

+;/* register Bytef *scan = s->window + s->strstart;                     */

+

+	mov	esi, [edx].ds_window

+	mov	[esp+window], esi

+	mov	ebp, [edx].ds_strstart

+	lea	edi, [esi+ebp]

+	mov	[esp+scan],edi

+

+;/* Determine how many bytes the scan ptr is off from being             */

+;/* dword-aligned.                                                      */

+

+	mov	eax, edi

+	neg	eax

+	and	eax, 3

+	mov	[esp+scanalign], eax

+

+;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?                      */

+;/*     s->strstart - (IPos)MAX_DIST(s) : NIL;                          */

+

+	mov	eax, [edx].ds_w_size

+	sub	eax, MIN_LOOKAHEAD

+	sub	ebp, eax

+	jg	SHORT LimitPositive

+	xor	ebp, ebp

+LimitPositive:

+

+;/* int best_len = s->prev_length;                                      */

+

+	mov	eax, [edx].ds_prev_length

+	mov	[esp+bestlen], eax

+

+;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */

+

+	add	esi, eax

+	mov	[esp+windowbestlen], esi

+

+;/* register ush scan_start = *(ushf*)scan;                             */

+;/* register ush scan_end   = *(ushf*)(scan+best_len-1);                */

+;/* Posf *prev = s->prev;                                               */

+

+	movzx	ebx, WORD PTR[edi]

+	mov	[esp+scanstart], ebx

+	movzx	ebx, WORD PTR[eax+edi-1]

+	mov	[esp+scanend], ebx

+	mov	edi, [edx].ds_prev

+

+;/* Jump into the main loop.                                            */

+

+	mov	edx, [esp+chainlenwmask]

+	jmp	SHORT LoopEntry

+

+;/* do {

+; *     match = s->window + cur_match;

+; *     if (*(ushf*)(match+best_len-1) != scan_end ||

+; *         *(ushf*)match != scan_start) continue;

+; *     [...]

+; * } while ((cur_match = prev[cur_match & wmask]) > limit

+; *          && --chain_length != 0);

+; *

+; * Here is the inner loop of the function. The function will spend the

+; * majority of its time in this loop, and majority of that time will

+; * be spent in the first ten instructions.

+; *

+; * Within this loop:

+; * %ebx = scanend

+; * %ecx = curmatch

+; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)

+; * %esi = windowbestlen - i.e., (window + bestlen)

+; * %edi = prev

+; * %ebp = limit

+; */

+

+	ALIGN	4

+LookupLoop:

+	and	ecx, edx

+	movzx	ecx, WORD PTR[edi+ecx*2]

+	cmp	ecx, ebp

+	jbe	LeaveNow

+	sub	edx, 000010000H

+	js	LeaveNow

+

+LoopEntry:

+	movzx	eax, WORD PTR[esi+ecx-1]

+	cmp	eax, ebx

+	jnz	SHORT LookupLoop

+

+	mov	eax, [esp+window]

+	movzx	eax, WORD PTR[eax+ecx]

+	cmp	eax, [esp+scanstart]

+	jnz	SHORT LookupLoop

+

+;/* Store the current value of chainlen.                                */

+

+	mov	[esp+chainlenwmask], edx

+

+;/* Point %edi to the string under scrutiny, and %esi to the string we  */

+;/* are hoping to match it up with. In actuality, %esi and %edi are     */

+;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is     */

+;/* initialized to -(MAX_MATCH_8 - scanalign).                          */

+

+	mov	esi, [esp+window]

+	mov	edi, [esp+scan]

+	add	esi, ecx

+	mov	eax, [esp+scanalign]

+	mov	edx, -MAX_MATCH_8

+	lea	edi, [edi+eax+MAX_MATCH_8]

+	lea	esi, [esi+eax+MAX_MATCH_8]

+

+;/* Test the strings for equality, 8 bytes at a time. At the end,

+; * adjust %edx so that it is offset to the exact byte that mismatched.

+; *

+; * We already know at this point that the first three bytes of the

+; * strings match each other, and they can be safely passed over before

+; * starting the compare loop. So what this code does is skip over 0-3

+; * bytes, as much as necessary in order to dword-align the %edi

+; * pointer. (%esi will still be misaligned three times out of four.)

+; *

+; * It should be confessed that this loop usually does not represent

+; * much of the total running time. Replacing it with a more

+; * straightforward "rep cmpsb" would not drastically degrade

+; * performance.

+; */

+

+LoopCmps:

+	mov	eax, DWORD PTR[esi+edx]

+	xor	eax, DWORD PTR[edi+edx]

+	jnz	SHORT LeaveLoopCmps

+

+	mov	eax, DWORD PTR[esi+edx+4]

+	xor	eax, DWORD PTR[edi+edx+4]

+	jnz	SHORT LeaveLoopCmps4

+

+	add	edx, 8

+	jnz	SHORT LoopCmps

+	jmp	LenMaximum

+	ALIGN	4

+

+LeaveLoopCmps4:

+	add	edx, 4

+

+LeaveLoopCmps:

+	test	eax, 00000FFFFH

+	jnz	SHORT LenLower

+

+	add	edx, 2

+	shr	eax, 16

+

+LenLower:

+	sub	al, 1

+	adc	edx, 0

+

+;/* Calculate the length of the match. If it is longer than MAX_MATCH,  */

+;/* then automatically accept it as the best possible match and leave.  */

+

+	lea	eax, [edi+edx]

+	mov	edi, [esp+scan]

+	sub	eax, edi

+	cmp	eax, MAX_MATCH

+	jge	SHORT LenMaximum

+

+;/* If the length of the match is not longer than the best match we     */

+;/* have so far, then forget it and return to the lookup loop.          */

+

+	mov	edx, [esp+deflatestate]

+	mov	ebx, [esp+bestlen]

+	cmp	eax, ebx

+	jg	SHORT LongerMatch

+	mov	esi, [esp+windowbestlen]

+	mov	edi, [edx].ds_prev

+	mov	ebx, [esp+scanend]

+	mov	edx, [esp+chainlenwmask]

+	jmp	LookupLoop

+	ALIGN	4

+

+;/*         s->match_start = cur_match;                                 */

+;/*         best_len = len;                                             */

+;/*         if (len >= nice_match) break;                               */

+;/*         scan_end = *(ushf*)(scan+best_len-1);                       */

+

+LongerMatch:

+	mov	ebx, [esp+nicematch]

+	mov	[esp+bestlen], eax

+	mov	[edx].ds_match_start, ecx

+	cmp	eax, ebx

+	jge	SHORT LeaveNow

+	mov	esi, [esp+window]

+	add	esi, eax

+	mov	[esp+windowbestlen], esi

+	movzx	ebx, WORD PTR[edi+eax-1]

+	mov	edi, [edx].ds_prev

+	mov	[esp+scanend], ebx

+	mov	edx, [esp+chainlenwmask]

+	jmp	LookupLoop

+	ALIGN	4

+

+;/* Accept the current string, with the maximum possible length.        */

+

+LenMaximum:

+	mov	edx, [esp+deflatestate]

+	mov	DWORD PTR[esp+bestlen], MAX_MATCH

+	mov	[edx].ds_match_start, ecx

+

+;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;          */

+;/* return s->lookahead;                                                */

+

+LeaveNow:

+	mov	edx, [esp+deflatestate]

+	mov	ebx, [esp+bestlen]

+	mov	eax, [edx].ds_lookahead

+	cmp	ebx, eax

+	jg	SHORT LookaheadRet

+	mov	eax, ebx

+LookaheadRet:

+

+; Restore the stack and return from whence we came.

+

+	add	esp, varsize

+	pop	ebx

+	pop	esi

+	pop	edi

+	pop	ebp

+	ret

+

+_longest_match	ENDP

+

+_TEXT	ENDS

+END

diff --git a/contrib/masmx64/bld_ml64.bat b/contrib/masmx64/bld_ml64.bat
new file mode 100644
index 0000000..8f9343d
--- /dev/null
+++ b/contrib/masmx64/bld_ml64.bat
@@ -0,0 +1,2 @@
+ml64.exe /Flinffasx64 /c /Zi inffasx64.asm

+ml64.exe /Flgvmat64   /c /Zi gvmat64.asm

diff --git a/contrib/masmx64/gvmat64.asm b/contrib/masmx64/gvmat64.asm
new file mode 100644
index 0000000..cee2145
--- /dev/null
+++ b/contrib/masmx64/gvmat64.asm
@@ -0,0 +1,464 @@
+;uInt longest_match_x64(

+;    deflate_state *s,

+;    IPos cur_match);                             /* current match */

+

+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86

+; Copyright (C) 1995-2005 Jean-loup Gailly, Brian Raiter and Gilles Vollant.

+; File written by Gilles Vollant, by modifiying the longest_match

+;  from Jean-loup Gailly in deflate.c

+;  and modifying asm686 with masm, optimised assembly code from Brian Raiter,

+;      written 1998

+;         http://www.zlib.net

+;         http://www.winimage.com/zLibDll

+;         http://www.muppetlabs.com/~breadbox/software/assembly.html

+;

+; to compile this file, I use option

+;   ml64.exe /Flgvmat64 /c /Zi gvmat64.asm

+;   with Microsoft Macro Assembler (x64) for AMD64

+;

+;   ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK

+;

+;   (you can get Windows 2003 server DDK with ml64 and cl for AMD64 from

+;      http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)

+;

+; Be carrefull to adapt zlib1222add below to your version of zLib

+

+

+;uInt longest_match(s, cur_match)

+;    deflate_state *s;

+;    IPos cur_match;                             /* current match */

+.code

+longest_match PROC

+

+

+;LocalVarsSize   equ 88

+ LocalVarsSize   equ 72

+

+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12

+; free register :  r14,r15

+; register can be saved : rsp

+

+ chainlenwmask   equ  rsp + 8 - LocalVarsSize    ; high word: current chain len

+                                                 ; low word: s->wmask

+;window          equ  rsp + xx - LocalVarsSize   ; local copy of s->window ; stored in r10

+;windowbestlen   equ  rsp + xx - LocalVarsSize   ; s->window + bestlen , use r10+r11

+;scanstart       equ  rsp + xx - LocalVarsSize   ; first two bytes of string ; stored in r12w

+;scanend         equ  rsp + xx - LocalVarsSize   ; last two bytes of string use ebx

+;scanalign       equ  rsp + xx - LocalVarsSize   ; dword-misalignment of string r13

+;bestlen         equ  rsp + xx - LocalVarsSize   ; size of best match so far -> r11d

+;scan            equ  rsp + xx - LocalVarsSize   ; ptr to string wanting match -> r9

+ nicematch       equ  rsp + 16 - LocalVarsSize   ; a good enough match size -> r14

+

+save_rdi        equ  rsp + 24 - LocalVarsSize

+save_rsi        equ  rsp + 32 - LocalVarsSize

+save_rbx        equ  rsp + 40 - LocalVarsSize

+save_rbp        equ  rsp + 48 - LocalVarsSize

+save_r12        equ  rsp + 56 - LocalVarsSize

+save_r13        equ  rsp + 64 - LocalVarsSize

+;save_r14        equ  rsp + 72 - LocalVarsSize

+;save_r15        equ  rsp + 80 - LocalVarsSize

+

+

+

+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib

+;  in the deflate_state structure since the asm code was first written

+;  (if you compile with zlib 1.0.4 or older, remove the +4).

+;  Note : these value are good with a 8 bytes boundary pack structure

+

+

+    MAX_MATCH           equ     258

+    MIN_MATCH           equ     3

+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)

+

+

+;;; Offsets for fields in the deflate_state structure. These numbers

+;;; are calculated from the definition of deflate_state, with the

+;;; assumption that the compiler will dword-align the fields. (Thus,

+;;; changing the definition of deflate_state could easily cause this

+;;; program to crash horribly, without so much as a warning at

+;;; compile time. Sigh.)

+

+;  all the +zlib1222add offsets are due to the addition of fields

+;  in zlib in the deflate_state structure since the asm code was first written

+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").

+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").

+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").

+

+zlib1222add     equ 8

+

+dsWSize         equ 56+zlib1222add+(zlib1222add/2)

+dsWMask         equ 64+zlib1222add+(zlib1222add/2)

+dsWindow        equ 72+zlib1222add

+dsPrev          equ 88+zlib1222add

+dsMatchLen      equ 128+zlib1222add

+dsPrevMatch     equ 132+zlib1222add

+dsStrStart      equ 140+zlib1222add

+dsMatchStart    equ 144+zlib1222add

+dsLookahead     equ 148+zlib1222add

+dsPrevLen       equ 152+zlib1222add

+dsMaxChainLen   equ 156+zlib1222add

+dsGoodMatch     equ 172+zlib1222add

+dsNiceMatch     equ 176+zlib1222add

+

+

+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)

+

+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and

+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp

+;

+; All registers must be preserved across the call, except for

+;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.

+

+

+

+;;; Save registers that the compiler may be using, and adjust esp to

+;;; make room for our stack frame.

+

+

+;;; Retrieve the function arguments. r8d will hold cur_match

+;;; throughout the entire function. edx will hold the pointer to the

+;;; deflate_state structure during the function's setup (before

+;;; entering the main loop.

+

+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)

+

+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx

+

+

+        mov [save_rdi],rdi

+        mov [save_rsi],rsi

+        mov [save_rbx],rbx

+        mov [save_rbp],rbp

+        mov r8d,edx

+        mov [save_r12],r12

+        mov [save_r13],r13

+;        mov [save_r14],r14

+;        mov [save_r15],r15

+

+

+;;; uInt wmask = s->w_mask;

+;;; unsigned chain_length = s->max_chain_length;

+;;; if (s->prev_length >= s->good_match) {

+;;;     chain_length >>= 2;

+;;; }

+

+        mov edi, [rcx + dsPrevLen]

+        mov esi, [rcx + dsGoodMatch]

+        mov eax, [rcx + dsWMask]

+        mov ebx, [rcx + dsMaxChainLen]

+        cmp edi, esi

+        jl  LastMatchGood

+        shr ebx, 2

+LastMatchGood:

+

+;;; chainlen is decremented once beforehand so that the function can

+;;; use the sign flag instead of the zero flag for the exit test.

+;;; It is then shifted into the high word, to make room for the wmask

+;;; value, which it will always accompany.

+

+        dec ebx

+        shl ebx, 16

+        or  ebx, eax

+        mov [chainlenwmask], ebx

+

+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

+

+        mov eax, [rcx + dsNiceMatch]

+        mov r10d, [rcx + dsLookahead]

+        cmp r10d, eax

+        cmovnl r10d, eax

+        mov [nicematch],r10d

+LookaheadLess:

+

+;;; register Bytef *scan = s->window + s->strstart;

+

+        mov r10, [rcx + dsWindow]

+        mov ebp, [rcx + dsStrStart]

+        lea r13, [r10 + rbp]

+

+;;; Determine how many bytes the scan ptr is off from being

+;;; dword-aligned.

+

+         mov r9,r13

+         neg r13

+         and r13,3

+

+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?

+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;

+

+        mov eax, [rcx + dsWSize]

+        sub eax, MIN_LOOKAHEAD

+        xor edi,edi

+        sub ebp, eax

+

+        mov r11d, [rcx + dsPrevLen]

+

+        cmovng ebp,edi

+

+;;; int best_len = s->prev_length;

+

+

+;;; Store the sum of s->window + best_len in esi locally, and in esi.

+

+       lea  rsi,[r10+r11]

+

+;;; register ush scan_start = *(ushf*)scan;

+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);

+;;; Posf *prev = s->prev;

+

+        movzx r12d,word ptr [r9]

+        movzx   ebx, word ptr [r9 + r11 - 1]

+        mov rdi, [rcx + dsPrev]

+

+;;; Jump into the main loop.

+

+        mov edx, [chainlenwmask]

+

+        cmp bx,word ptr [rsi + r8 - 1]

+        jz  LookupLoopIsZero

+

+LookupLoop1:

+        and r8d, edx

+

+        movzx   r8d, word ptr [rdi + r8*2]

+        cmp r8d, ebp

+        jbe LeaveNow

+        sub edx, 00010000h

+        js  LeaveNow

+

+LoopEntry1:

+        cmp bx,word ptr [rsi + r8 - 1]

+        jz  LookupLoopIsZero

+

+LookupLoop2:

+        and r8d, edx

+

+        movzx   r8d, word ptr [rdi + r8*2]

+        cmp r8d, ebp

+        jbe LeaveNow

+        sub edx, 00010000h

+        js  LeaveNow

+

+LoopEntry2:

+        cmp bx,word ptr [rsi + r8 - 1]

+        jz  LookupLoopIsZero

+

+LookupLoop4:

+        and r8d, edx

+

+        movzx   r8d, word ptr [rdi + r8*2]

+        cmp r8d, ebp

+        jbe LeaveNow

+        sub edx, 00010000h

+        js  LeaveNow

+

+LoopEntry4:

+

+        cmp bx,word ptr [rsi + r8 - 1]

+        jnz LookupLoop1

+        jmp LookupLoopIsZero

+

+

+;;; do {

+;;;     match = s->window + cur_match;

+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||

+;;;         *(ushf*)match != scan_start) continue;

+;;;     [...]

+;;; } while ((cur_match = prev[cur_match & wmask]) > limit

+;;;          && --chain_length != 0);

+;;;

+;;; Here is the inner loop of the function. The function will spend the

+;;; majority of its time in this loop, and majority of that time will

+;;; be spent in the first ten instructions.

+;;;

+;;; Within this loop:

+;;; ebx = scanend

+;;; r8d = curmatch

+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)

+;;; esi = windowbestlen - i.e., (window + bestlen)

+;;; edi = prev

+;;; ebp = limit

+

+LookupLoop:

+        and r8d, edx

+

+        movzx   r8d, word ptr [rdi + r8*2]

+        cmp r8d, ebp

+        jbe LeaveNow

+        sub edx, 00010000h

+        js  LeaveNow

+

+LoopEntry:

+

+        cmp bx,word ptr [rsi + r8 - 1]

+        jnz LookupLoop1

+LookupLoopIsZero:

+        cmp     r12w, word ptr [r10 + r8]

+        jnz LookupLoop1

+

+

+;;; Store the current value of chainlen.

+        mov [chainlenwmask], edx

+

+;;; Point edi to the string under scrutiny, and esi to the string we

+;;; are hoping to match it up with. In actuality, esi and edi are

+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is

+;;; initialized to -(MAX_MATCH_8 - scanalign).

+

+        lea rsi,[r8+r10]

+        mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)

+        lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]

+        lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]

+

+        prefetcht1 [rsi+rdx]

+        prefetcht1 [rdi+rdx]

+;;; Test the strings for equality, 8 bytes at a time. At the end,

+;;; adjust edx so that it is offset to the exact byte that mismatched.

+;;;

+;;; We already know at this point that the first three bytes of the

+;;; strings match each other, and they can be safely passed over before

+;;; starting the compare loop. So what this code does is skip over 0-3

+;;; bytes, as much as necessary in order to dword-align the edi

+;;; pointer. (esi will still be misaligned three times out of four.)

+;;;

+;;; It should be confessed that this loop usually does not represent

+;;; much of the total running time. Replacing it with a more

+;;; straightforward "rep cmpsb" would not drastically degrade

+;;; performance.

+

+;LoopCmps:

+;        mov eax, [rsi + rdx]

+;        xor eax, [rdi + rdx]

+;        jnz LeaveLoopCmps

+;        mov eax, [rsi + rdx + 4]

+;        xor eax, [rdi + rdx + 4]

+;        jnz LeaveLoopCmps4

+;        add rdx, 8

+;        jnz LoopCmps

+;        jmp LenMaximum

+;LeaveLoopCmps4: add rdx, 4

+;LeaveLoopCmps:  test    eax, 0000FFFFh

+;        jnz LenLower

+;        add rdx,  2

+;        shr eax, 16

+;LenLower:   sub al, 1

+;        adc rdx, 0

+

+

+LoopCmps:

+        mov rax, [rsi + rdx]

+        xor rax, [rdi + rdx]

+        jnz LeaveLoopCmps

+

+        mov rax, [rsi + rdx + 8]

+        xor rax, [rdi + rdx + 8]

+        jnz LeaveLoopCmps8

+

+

+        mov rax, [rsi + rdx + 8+8]

+        xor rax, [rdi + rdx + 8+8]

+        jnz LeaveLoopCmps16

+

+        add rdx,8+8+8

+

+        jmp short LoopCmps

+LeaveLoopCmps16: add rdx,8

+LeaveLoopCmps8: add rdx,8

+LeaveLoopCmps:

+

+        test    eax, 0000FFFFh

+        jnz LenLower

+

+        test eax,0ffffffffh

+

+        jnz LenLower32

+

+        add rdx,4

+        shr rax,32

+        or ax,ax

+        jnz LenLower

+

+LenLower32:

+        shr eax,16

+        add rdx,2

+LenLower:   sub al, 1

+        adc rdx, 0

+;;; Calculate the length of the match. If it is longer than MAX_MATCH,

+;;; then automatically accept it as the best possible match and leave.

+

+        lea rax, [rdi + rdx]

+        sub rax, r9

+        cmp eax, MAX_MATCH

+        jge LenMaximum

+

+;;; If the length of the match is not longer than the best match we

+;;; have so far, then forget it and return to the lookup loop.

+;///////////////////////////////////

+

+        cmp eax, r11d

+        jg  LongerMatch

+

+        lea rsi,[r10+r11]

+

+        mov rdi, [rcx + dsPrev]

+        mov edx, [chainlenwmask]

+        jmp LookupLoop

+

+;;;         s->match_start = cur_match;

+;;;         best_len = len;

+;;;         if (len >= nice_match) break;

+;;;         scan_end = *(ushf*)(scan+best_len-1);

+

+LongerMatch:

+        mov r11d, eax

+        mov [rcx + dsMatchStart], r8d

+        cmp eax, [nicematch]

+        jge LeaveNow

+

+        lea rsi,[r10+rax]

+

+        movzx   ebx, word ptr [r9 + rax - 1]

+        mov rdi, [rcx + dsPrev]

+        mov edx, [chainlenwmask]

+        jmp LookupLoop

+

+;;; Accept the current string, with the maximum possible length.

+

+LenMaximum:

+        mov r11d,MAX_MATCH

+        mov [rcx + dsMatchStart], r8d

+

+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;

+;;; return s->lookahead;

+

+LeaveNow:

+        mov eax, [rcx + dsLookahead]

+        cmp r11d, eax

+        cmovng eax, r11d

+

+

+;;; Restore the stack and return from whence we came.

+

+

+        mov rsi,[save_rsi]

+        mov rdi,[save_rdi]

+        mov rbx,[save_rbx]

+        mov rbp,[save_rbp]

+        mov r12,[save_r12]

+        mov r13,[save_r13]

+;        mov r14,[save_r14]

+;        mov r15,[save_r15]

+

+

+        ret 0

+; please don't remove this string !

+; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!

+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0

+longest_match   ENDP

+

+match_init PROC

+  ret 0

+match_init ENDP

+

+

+END

diff --git a/contrib/masmx64/gvmat64.obj b/contrib/masmx64/gvmat64.obj
new file mode 100644
index 0000000..10a73fe
--- /dev/null
+++ b/contrib/masmx64/gvmat64.obj
Binary files differ
diff --git a/contrib/masmx64/inffas8664.c b/contrib/masmx64/inffas8664.c
new file mode 100644
index 0000000..3af764d
--- /dev/null
+++ b/contrib/masmx64/inffas8664.c
@@ -0,0 +1,186 @@
+/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding

+ * version for AMD64 on Windows using Microsoft C compiler

+ *

+ * Copyright (C) 1995-2003 Mark Adler

+ * For conditions of distribution and use, see copyright notice in zlib.h

+ *

+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>

+ * Please use the copyright conditions above.

+ *

+ * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant

+ *

+ * inffas8664.c call function inffas8664fnc in inffasx64.asm

+ *  inffasx64.asm is automatically convert from AMD64 portion of inffas86.c

+ *

+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also

+ * slightly quicker on x86 systems because, instead of using rep movsb to copy

+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single

+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates

+ * from http://fedora.linux.duke.edu/fc1_x86_64

+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with

+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,

+ * when decompressing mozilla-source-1.3.tar.gz.

+ *

+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from

+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at

+ * the moment.  I have successfully compiled and tested this code with gcc2.96,

+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S

+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX

+ * enabled.  I will attempt to merge the MMX code into this version.  Newer

+ * versions of this and inffast.S can be found at

+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/

+ *

+ */

+

+#include <stdio.h>

+#include "zutil.h"

+#include "inftrees.h"

+#include "inflate.h"

+#include "inffast.h"

+

+/* Mark Adler's comments from inffast.c: */

+

+/*

+   Decode literal, length, and distance codes and write out the resulting

+   literal and match bytes until either not enough input or output is

+   available, an end-of-block is encountered, or a data error is encountered.

+   When large enough input and output buffers are supplied to inflate(), for

+   example, a 16K input buffer and a 64K output buffer, more than 95% of the

+   inflate execution time is spent in this routine.

+

+   Entry assumptions:

+

+        state->mode == LEN

+        strm->avail_in >= 6

+        strm->avail_out >= 258

+        start >= strm->avail_out

+        state->bits < 8

+

+   On return, state->mode is one of:

+

+        LEN -- ran out of enough output space or enough available input

+        TYPE -- reached end of block code, inflate() to interpret next block

+        BAD -- error in block data

+

+   Notes:

+

+    - The maximum input bits used by a length/distance pair is 15 bits for the

+      length code, 5 bits for the length extra, 15 bits for the distance code,

+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.

+      Therefore if strm->avail_in >= 6, then there is enough input to avoid

+      checking for available input while decoding.

+

+    - The maximum bytes that a single length/distance pair can output is 258

+      bytes, which is the maximum length that can be coded.  inflate_fast()

+      requires strm->avail_out >= 258 for each loop to avoid checking for

+      output space.

+ */

+

+

+

+    typedef struct inffast_ar {

+/* 64   32                               x86  x86_64 */

+/* ar offset                              register */

+/*  0    0 */ void *esp;                /* esp save */

+/*  8    4 */ void *ebp;                /* ebp save */

+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */

+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */

+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */

+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */

+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */

+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */

+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */

+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */

+/* 80   40 */ size_t /*unsigned long */hold;       /* edx rdx  local strm->hold */

+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */

+/* 92   48 */ unsigned wsize;           /*          window size */

+/* 96   52 */ unsigned write;           /*          window write index */

+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */

+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */

+/*108   64 */ unsigned len;             /*     r14  match length */

+/*112   68 */ unsigned dist;            /*     r15  match distance */

+/*116   72 */ unsigned status;          /*          set when state chng*/

+    } type_ar;

+#ifdef ASMINF

+

+void inflate_fast(strm, start)

+z_streamp strm;

+unsigned start;         /* inflate()'s starting value for strm->avail_out */

+{

+    struct inflate_state FAR *state;

+    type_ar ar;

+    void inffas8664fnc(struct inffast_ar * par);

+

+    

+

+#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))

+#define PAD_AVAIL_IN 6

+#define PAD_AVAIL_OUT 258    

+#else

+#define PAD_AVAIL_IN 5

+#define PAD_AVAIL_OUT 257

+#endif

+

+    /* copy state to local variables */

+    state = (struct inflate_state FAR *)strm->state;

+

+    ar.in = strm->next_in;

+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);

+    ar.out = strm->next_out;

+    ar.beg = ar.out - (start - strm->avail_out);

+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);

+    ar.wsize = state->wsize;

+    ar.write = state->write;

+    ar.window = state->window;

+    ar.hold = state->hold;

+    ar.bits = state->bits;

+    ar.lcode = state->lencode;

+    ar.dcode = state->distcode;

+    ar.lmask = (1U << state->lenbits) - 1;

+    ar.dmask = (1U << state->distbits) - 1;

+

+    /* decode literals and length/distances until end-of-block or not enough

+       input data or output space */

+

+    /* align in on 1/2 hold size boundary */

+    while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {

+        ar.hold += (unsigned long)*ar.in++ << ar.bits;

+        ar.bits += 8;

+    }

+

+    inffas8664fnc(&ar);

+

+    if (ar.status > 1) {

+        if (ar.status == 2)

+            strm->msg = "invalid literal/length code";

+        else if (ar.status == 3)

+            strm->msg = "invalid distance code";

+        else

+            strm->msg = "invalid distance too far back";

+        state->mode = BAD;

+    }

+    else if ( ar.status == 1 ) {

+        state->mode = TYPE;

+    }

+

+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */

+    ar.len = ar.bits >> 3;

+    ar.in -= ar.len;

+    ar.bits -= ar.len << 3;

+    ar.hold &= (1U << ar.bits) - 1;

+

+    /* update state and return */

+    strm->next_in = ar.in;

+    strm->next_out = ar.out;

+    strm->avail_in = (unsigned)(ar.in < ar.last ?

+                                PAD_AVAIL_IN + (ar.last - ar.in) :

+                                PAD_AVAIL_IN - (ar.in - ar.last));

+    strm->avail_out = (unsigned)(ar.out < ar.end ?

+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :

+                                 PAD_AVAIL_OUT - (ar.out - ar.end));

+    state->hold = (unsigned long)ar.hold;

+    state->bits = ar.bits;

+    return;

+}

+

+#endif

diff --git a/contrib/masmx64/inffasx64.asm b/contrib/masmx64/inffasx64.asm
new file mode 100644
index 0000000..b5d93a2
--- /dev/null
+++ b/contrib/masmx64/inffasx64.asm
@@ -0,0 +1,392 @@
+; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding

+; version for AMD64 on Windows using Microsoft C compiler

+;

+; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c

+; inffasx64.asm is called by inffas8664.c, which contain more info.

+

+

+; to compile this file, I use option

+;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm

+;   with Microsoft Macro Assembler (x64) for AMD64

+;

+;   ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK

+;

+;   (you can get Windows 2003 server DDK with ml64 and cl.exe for AMD64 from 

+;      http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)

+;

+

+.code

+inffas8664fnc PROC

+

+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and

+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp

+;

+; All registers must be preserved across the call, except for

+;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.

+

+

+	mov [rsp-8],rsi

+	mov [rsp-16],rdi

+	mov [rsp-24],r12

+	mov [rsp-32],r13

+	mov [rsp-40],r14

+	mov [rsp-48],r15

+	mov [rsp-56],rbx

+

+	mov rax,rcx

+

+	mov	[rax+8], rbp       ; /* save regs rbp and rsp */

+	mov	[rax], rsp

+

+	mov	rsp, rax          ; /* make rsp point to &ar */

+

+	mov	rsi, [rsp+16]      ; /* rsi  = in */

+	mov	rdi, [rsp+32]      ; /* rdi  = out */

+	mov	r9, [rsp+24]       ; /* r9   = last */

+	mov	r10, [rsp+48]      ; /* r10  = end */

+	mov	rbp, [rsp+64]      ; /* rbp  = lcode */

+	mov	r11, [rsp+72]      ; /* r11  = dcode */

+	mov	rdx, [rsp+80]      ; /* rdx  = hold */

+	mov	ebx, [rsp+88]      ; /* ebx  = bits */

+	mov	r12d, [rsp+100]    ; /* r12d = lmask */

+	mov	r13d, [rsp+104]    ; /* r13d = dmask */

+                                          ; /* r14d = len */

+                                          ; /* r15d = dist */

+

+

+	cld

+	cmp	r10, rdi

+	je	L_one_time           ; /* if only one decode left */

+	cmp	r9, rsi

+

+    jne L_do_loop

+

+

+L_one_time:

+	mov	r8, r12           ; /* r8 = lmask */

+	cmp	bl, 32

+	ja	L_get_length_code_one_time

+

+	lodsd                         ; /* eax = *(uint *)in++ */

+	mov	cl, bl            ; /* cl = bits, needs it for shifting */

+	add	bl, 32             ; /* bits += 32 */

+	shl	rax, cl

+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */

+	jmp	L_get_length_code_one_time

+

+ALIGN 4

+L_while_test:

+	cmp	r10, rdi

+	jbe	L_break_loop

+	cmp	r9, rsi

+	jbe	L_break_loop

+

+L_do_loop:

+	mov	r8, r12           ; /* r8 = lmask */

+	cmp	bl, 32

+	ja	L_get_length_code    ; /* if (32 < bits) */

+

+	lodsd                         ; /* eax = *(uint *)in++ */

+	mov	cl, bl            ; /* cl = bits, needs it for shifting */

+	add	bl, 32             ; /* bits += 32 */

+	shl	rax, cl

+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */

+

+L_get_length_code:

+	and	r8, rdx            ; /* r8 &= hold */

+	mov	eax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */

+

+	mov	cl, ah            ; /* cl = this.bits */

+	sub	bl, ah            ; /* bits -= this.bits */

+	shr	rdx, cl           ; /* hold >>= this.bits */

+

+	test	al, al

+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */

+

+	mov	r8, r12            ; /* r8 = lmask */

+	shr	eax, 16            ; /* output this.val char */

+	stosb

+

+L_get_length_code_one_time:

+	and	r8, rdx            ; /* r8 &= hold */

+	mov	eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */

+

+L_dolen:

+	mov	cl, ah            ; /* cl = this.bits */

+	sub	bl, ah            ; /* bits -= this.bits */

+	shr	rdx, cl           ; /* hold >>= this.bits */

+

+	test	al, al

+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */

+

+	shr	eax, 16            ; /* output this.val char */

+	stosb

+	jmp	L_while_test

+

+ALIGN 4

+L_test_for_length_base:

+	mov	r14d, eax         ; /* len = this */

+	shr	r14d, 16           ; /* len = this.val */

+	mov	cl, al

+

+	test	al, 16

+	jz	L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */

+	and	cl, 15             ; /* op &= 15 */

+	jz	L_decode_distance    ; /* if (!op) */

+

+L_add_bits_to_len:

+	sub	bl, cl

+	xor	eax, eax

+	inc	eax

+	shl	eax, cl

+	dec	eax

+	and	eax, edx          ; /* eax &= hold */

+	shr	rdx, cl

+	add	r14d, eax         ; /* len += hold & mask[op] */

+

+L_decode_distance:

+	mov	r8, r13           ; /* r8 = dmask */

+	cmp	bl, 32

+	ja	L_get_distance_code  ; /* if (32 < bits) */

+

+	lodsd                         ; /* eax = *(uint *)in++ */

+	mov	cl, bl            ; /* cl = bits, needs it for shifting */

+	add	bl, 32             ; /* bits += 32 */

+	shl	rax, cl

+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */

+

+L_get_distance_code:

+	and	r8, rdx           ; /* r8 &= hold */

+	mov	eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */

+

+L_dodist:

+	mov	r15d, eax         ; /* dist = this */

+	shr	r15d, 16           ; /* dist = this.val */

+	mov	cl, ah

+	sub	bl, ah            ; /* bits -= this.bits */

+	shr	rdx, cl           ; /* hold >>= this.bits */

+	mov	cl, al            ; /* cl = this.op */

+

+	test	al, 16             ; /* if ((op & 16) == 0) */

+	jz	L_test_for_second_level_dist

+	and	cl, 15             ; /* op &= 15 */

+	jz	L_check_dist_one

+

+L_add_bits_to_dist:

+	sub	bl, cl

+	xor	eax, eax

+	inc	eax

+	shl	eax, cl

+	dec	eax                 ; /* (1 << op) - 1 */

+	and	eax, edx          ; /* eax &= hold */

+	shr	rdx, cl

+	add	r15d, eax         ; /* dist += hold & ((1 << op) - 1) */

+

+L_check_window:

+	mov	r8, rsi           ; /* save in so from can use it's reg */

+	mov	rax, rdi

+	sub	rax, [rsp+40]      ; /* nbytes = out - beg */

+

+	cmp	eax, r15d

+	jb	L_clip_window        ; /* if (dist > nbytes) 4.2% */

+

+	mov	ecx, r14d         ; /* ecx = len */

+	mov	rsi, rdi

+	sub	rsi, r15          ; /* from = out - dist */

+

+	sar	ecx, 1

+	jnc	L_copy_two           ; /* if len % 2 == 0 */

+

+	rep     movsw

+	mov	al, [rsi]

+	mov	[rdi], al

+	inc	rdi

+

+	mov	rsi, r8           ; /* move in back to %rsi, toss from */

+	jmp	L_while_test

+

+L_copy_two:

+	rep     movsw

+	mov	rsi, r8           ; /* move in back to %rsi, toss from */

+	jmp	L_while_test

+

+ALIGN 4

+L_check_dist_one:

+	cmp	r15d, 1            ; /* if dist 1, is a memset */

+	jne	L_check_window

+	cmp	[rsp+40], rdi      ; /* if out == beg, outside window */

+	je	L_check_window

+

+	mov	ecx, r14d         ; /* ecx = len */

+	mov	al, [rdi-1]

+	mov	ah, al

+

+	sar	ecx, 1

+	jnc	L_set_two

+	mov	[rdi], al

+	inc	rdi

+

+L_set_two:

+	rep     stosw

+	jmp	L_while_test

+

+ALIGN 4

+L_test_for_second_level_length:

+	test	al, 64

+	jnz	L_test_for_end_of_block ; /* if ((op & 64) != 0) */

+

+	xor	eax, eax

+	inc	eax

+	shl	eax, cl

+	dec	eax

+	and	eax, edx         ; /* eax &= hold */

+	add	eax, r14d        ; /* eax += len */

+	mov	eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/

+	jmp	L_dolen

+

+ALIGN 4

+L_test_for_second_level_dist:

+	test	al, 64

+	jnz	L_invalid_distance_code ; /* if ((op & 64) != 0) */

+

+	xor	eax, eax

+	inc	eax

+	shl	eax, cl

+	dec	eax

+	and	eax, edx         ; /* eax &= hold */

+	add	eax, r15d        ; /* eax += dist */

+	mov	eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/

+	jmp	L_dodist

+

+ALIGN 4

+L_clip_window:

+	mov	ecx, eax         ; /* ecx = nbytes */

+	mov	eax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */

+	neg	ecx                ; /* nbytes = -nbytes */

+

+	cmp	eax, r15d

+	jb	L_invalid_distance_too_far ; /* if (dist > wsize) */

+

+	add	ecx, r15d         ; /* nbytes = dist - nbytes */

+	cmp	dword ptr [rsp+96], 0

+	jne	L_wrap_around_window ; /* if (write != 0) */

+

+	mov	rsi, [rsp+56]     ; /* from  = window */

+	sub	eax, ecx         ; /* eax  -= nbytes */

+	add	rsi, rax         ; /* from += wsize - nbytes */

+

+	mov	eax, r14d        ; /* eax = len */

+	cmp	r14d, ecx

+	jbe	L_do_copy           ; /* if (nbytes >= len) */

+

+	sub	eax, ecx         ; /* eax -= nbytes */

+	rep     movsb

+	mov	rsi, rdi

+	sub	rsi, r15         ; /* from = &out[ -dist ] */

+	jmp	L_do_copy

+

+ALIGN 4

+L_wrap_around_window:

+	mov	eax, [rsp+96]     ; /* eax = write */

+	cmp	ecx, eax

+	jbe	L_contiguous_in_window ; /* if (write >= nbytes) */

+

+	mov	esi, [rsp+92]     ; /* from  = wsize */

+	add	rsi, [rsp+56]     ; /* from += window */

+	add	rsi, rax         ; /* from += write */

+	sub	rsi, rcx         ; /* from -= nbytes */

+	sub	ecx, eax         ; /* nbytes -= write */

+

+	mov	eax, r14d        ; /* eax = len */

+	cmp	eax, ecx

+	jbe	L_do_copy           ; /* if (nbytes >= len) */

+

+	sub	eax, ecx         ; /* len -= nbytes */

+	rep     movsb

+	mov	rsi, [rsp+56]     ; /* from = window */

+	mov	ecx, [rsp+96]     ; /* nbytes = write */

+	cmp	eax, ecx

+	jbe	L_do_copy           ; /* if (nbytes >= len) */

+

+	sub	eax, ecx         ; /* len -= nbytes */

+	rep     movsb

+	mov	rsi, rdi

+	sub	rsi, r15         ; /* from = out - dist */

+	jmp	L_do_copy

+

+ALIGN 4

+L_contiguous_in_window:

+	mov	rsi, [rsp+56]     ; /* rsi = window */

+	add	rsi, rax

+	sub	rsi, rcx         ; /* from += write - nbytes */

+

+	mov	eax, r14d        ; /* eax = len */

+	cmp	eax, ecx

+	jbe	L_do_copy           ; /* if (nbytes >= len) */

+

+	sub	eax, ecx         ; /* len -= nbytes */

+	rep     movsb

+	mov	rsi, rdi

+	sub	rsi, r15         ; /* from = out - dist */

+	jmp	L_do_copy           ; /* if (nbytes >= len) */

+

+ALIGN 4

+L_do_copy:

+	mov	ecx, eax         ; /* ecx = len */

+	rep     movsb

+

+	mov	rsi, r8          ; /* move in back to %esi, toss from */

+	jmp	L_while_test

+

+L_test_for_end_of_block:

+	test	al, 32

+	jz	L_invalid_literal_length_code

+	mov	dword ptr [rsp+116], 1

+	jmp	L_break_loop_with_status

+

+L_invalid_literal_length_code:

+	mov	dword ptr [rsp+116], 2

+	jmp	L_break_loop_with_status

+

+L_invalid_distance_code:

+	mov	dword ptr [rsp+116], 3

+	jmp	L_break_loop_with_status

+

+L_invalid_distance_too_far:

+	mov	dword ptr [rsp+116], 4

+	jmp	L_break_loop_with_status

+

+L_break_loop:

+	mov	dword ptr [rsp+116], 0

+

+L_break_loop_with_status:

+; /* put in, out, bits, and hold back into ar and pop esp */

+	mov	[rsp+16], rsi     ; /* in */

+	mov	[rsp+32], rdi     ; /* out */

+	mov	[rsp+88], ebx     ; /* bits */

+	mov	[rsp+80], rdx     ; /* hold */

+

+	mov	rax, [rsp]       ; /* restore rbp and rsp */

+	mov	rbp, [rsp+8]

+	mov	rsp, rax

+

+

+

+	mov rsi,[rsp-8]

+	mov rdi,[rsp-16]

+	mov r12,[rsp-24]

+	mov r13,[rsp-32]

+	mov r14,[rsp-40]

+	mov r15,[rsp-48]

+	mov rbx,[rsp-56]

+	

+    ret 0

+;          :

+;          : "m" (ar)

+;          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",

+;            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"

+;    );

+

+inffas8664fnc 	ENDP

+;_TEXT	ENDS

+END

diff --git a/contrib/masmx64/inffasx64.obj b/contrib/masmx64/inffasx64.obj
new file mode 100644
index 0000000..8df5d82
--- /dev/null
+++ b/contrib/masmx64/inffasx64.obj
Binary files differ
diff --git a/contrib/masmx64/readme.txt b/contrib/masmx64/readme.txt
new file mode 100644
index 0000000..ee03115
--- /dev/null
+++ b/contrib/masmx64/readme.txt
@@ -0,0 +1,28 @@
+Summary

+-------

+This directory contains ASM implementations of the functions

+longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),

+for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.

+

+gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits

+   assembly optimized version from Jean-loup Gailly original longest_match function

+

+inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing

+   original function from Mark Adler

+

+Use instructions

+----------------

+Copy these files into the zlib source directory.

+

+define ASMV and ASMINF in your project. Include inffas8664.c in your source tree,

+and inffasx64.obj and gvmat64.obj as object to link.

+

+

+Build instructions

+------------------

+run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)

+

+ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK

+

+You can get Windows 2003 server DDK with ml64 and cl for AMD64 from 

+  http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)

diff --git a/contrib/masmx86/bld_ml32.bat b/contrib/masmx86/bld_ml32.bat
new file mode 100644
index 0000000..99144d0
--- /dev/null
+++ b/contrib/masmx86/bld_ml32.bat
@@ -0,0 +1,2 @@
+ml /coff /Zi /c /Flgvmat32.lst  gvmat32.asm 

+ml /coff /Zi /c /Flinffas32.lst inffas32.asm 

diff --git a/contrib/masmx86/gvmat32.asm b/contrib/masmx86/gvmat32.asm
index e841a7f..874bb2d 100644
--- a/contrib/masmx86/gvmat32.asm
+++ b/contrib/masmx86/gvmat32.asm
@@ -1,909 +1,972 @@
-;
-; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
-; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
-; File written by Gilles Vollant, by modifiying the longest_match
-;  from Jean-loup Gailly in deflate.c
-; It need wmask == 0x7fff
-;     (assembly code is faster with a fixed wmask)
-;
-; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK)
-;   I compile with : "ml /coff /Zi /c gvmat32.asm"
-;
-
-;uInt longest_match_7fff(s, cur_match)
-;    deflate_state *s;
-;    IPos cur_match;                             /* current match */
-
-	NbStack         equ     76
-	cur_match       equ     dword ptr[esp+NbStack-0]
-	str_s           equ     dword ptr[esp+NbStack-4]
-; 5 dword on top (ret,ebp,esi,edi,ebx)
-	adrret          equ     dword ptr[esp+NbStack-8]
-	pushebp         equ     dword ptr[esp+NbStack-12]
-	pushedi         equ     dword ptr[esp+NbStack-16]
-	pushesi         equ     dword ptr[esp+NbStack-20]
-	pushebx         equ     dword ptr[esp+NbStack-24]
-
-	chain_length    equ     dword ptr [esp+NbStack-28]
-	limit           equ     dword ptr [esp+NbStack-32]
-	best_len        equ     dword ptr [esp+NbStack-36]
-	window          equ     dword ptr [esp+NbStack-40]
-	prev            equ     dword ptr [esp+NbStack-44]
-	scan_start      equ      word ptr [esp+NbStack-48]
-	wmask           equ     dword ptr [esp+NbStack-52]
-	match_start_ptr equ     dword ptr [esp+NbStack-56]
-	nice_match      equ     dword ptr [esp+NbStack-60]
-	scan            equ     dword ptr [esp+NbStack-64]
-
-	windowlen       equ     dword ptr [esp+NbStack-68]
-	match_start     equ     dword ptr [esp+NbStack-72]
-	strend          equ     dword ptr [esp+NbStack-76]
-	NbStackAdd      equ     (NbStack-24)
-
-    .386p
-
-    name    gvmatch
-    .MODEL  FLAT
-
-
-
-;  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
-;  (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
-
-    addstr              equ     4+8
-    dep_chain_length    equ     70h+addstr
-    dep_window          equ     2ch+addstr
-    dep_strstart        equ     60h+addstr
-    dep_prev_length     equ     6ch+addstr
-    dep_nice_match      equ     84h+addstr
-    dep_w_size          equ     20h+addstr
-    dep_prev            equ     34h+addstr
-    dep_w_mask          equ     28h+addstr
-    dep_good_match      equ     80h+addstr
-    dep_match_start     equ     64h+addstr
-    dep_lookahead       equ     68h+addstr
-
-
-_TEXT                   segment
-
-IFDEF NOUNDERLINE
-			public  longest_match_7fff
-			public  longest_match_686
-;                        public  match_init
-ELSE
-			public  _longest_match_7fff
-			public  _longest_match_686
-;                        public  _match_init
-ENDIF
-
-    MAX_MATCH           equ     258
-    MIN_MATCH           equ     3
-    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
-
-
-
-IFDEF NOUNDERLINE
-;match_init      proc near
-;                ret
-;match_init      endp
-ELSE
-;_match_init     proc near
-;                ret
-;_match_init     endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff   proc near
-ELSE
-_longest_match_7fff  proc near
-ENDIF
-
-	mov     edx,[esp+4]
-
-
-
-	push    ebp
-	push    edi
-	push    esi
-	push    ebx
-
-	sub     esp,NbStackAdd
-
-; initialize or check the variables used in match.asm.
-	mov     ebp,edx
-
-; chain_length = s->max_chain_length
-; if (prev_length>=good_match) chain_length >>= 2
-	mov     edx,[ebp+dep_chain_length]
-	mov     ebx,[ebp+dep_prev_length]
-	cmp     [ebp+dep_good_match],ebx
-	ja      noshr
-	shr     edx,2
-noshr:
-; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
-	inc     edx
-	mov     edi,[ebp+dep_nice_match]
-	mov     chain_length,edx
-	mov     eax,[ebp+dep_lookahead]
-	cmp     eax,edi
-; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-	jae     nolookaheadnicematch
-	mov     edi,eax
-nolookaheadnicematch:
-; best_len = s->prev_length
-	mov     best_len,ebx
-
-; window = s->window
-	mov     esi,[ebp+dep_window]
-	mov     ecx,[ebp+dep_strstart]
-	mov     window,esi
-
-	mov     nice_match,edi
-; scan = window + strstart
-	add     esi,ecx
-	mov     scan,esi
-; dx = *window
-	mov     dx,word ptr [esi]
-; bx = *(window+best_len-1)
-	mov     bx,word ptr [esi+ebx-1]
-	add     esi,MAX_MATCH-1
-; scan_start = *scan
-	mov     scan_start,dx
-; strend = scan + MAX_MATCH-1
-	mov     strend,esi
-; bx = scan_end = *(window+best_len-1)
-
-;    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-;        s->strstart - (IPos)MAX_DIST(s) : NIL;
-
-	mov     esi,[ebp+dep_w_size]
-	sub     esi,MIN_LOOKAHEAD
-; here esi = MAX_DIST(s)
-	sub     ecx,esi
-	ja      nodist
-	xor     ecx,ecx
-nodist:
-	mov     limit,ecx
-
-; prev = s->prev
-	mov     edx,[ebp+dep_prev]
-	mov     prev,edx
-
-;
-	mov     edx,dword ptr [ebp+dep_match_start]
-	mov     bp,scan_start
-	mov     eax,cur_match
-	mov     match_start,edx
-
-	mov     edx,window
-	mov     edi,edx
-	add     edi,best_len
-	mov     esi,prev
-	dec     edi
-; windowlen = window + best_len -1
-	mov     windowlen,edi
-
-	jmp     beginloop2
-	align   4
-
-; here, in the loop
-;       eax = ax = cur_match
-;       ecx = limit
-;        bx = scan_end
-;        bp = scan_start
-;       edi = windowlen (window + best_len -1)
-;       esi = prev
-
-
-;// here; chain_length <=16
-normalbeg0add16:
-	add     chain_length,16
-	jz      exitloop
-normalbeg0:
-	cmp     word ptr[edi+eax],bx
-	je      normalbeg2noroll
-rcontlabnoroll:
-; cur_match = prev[cur_match & wmask]
-	and     eax,7fffh
-	mov     ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
-	cmp     ecx,eax
-	jnb     exitloop
-; if --chain_length != 0, go to exitloop
-	dec     chain_length
-	jnz     normalbeg0
-	jmp     exitloop
-
-normalbeg2noroll:
-; if (scan_start==*(cur_match+window)) goto normalbeg2
-	cmp     bp,word ptr[edx+eax]
-	jne     rcontlabnoroll
-	jmp     normalbeg2
-
-contloop3:
-	mov     edi,windowlen
-
-; cur_match = prev[cur_match & wmask]
-	and     eax,7fffh
-	mov     ax,word ptr[esi+eax*2]
-; if cur_match > limit, go to exitloop
-	cmp     ecx,eax
-jnbexitloopshort1:
-	jnb     exitloop
-; if --chain_length != 0, go to exitloop
-
-
-; begin the main loop
-beginloop2:
-	sub     chain_length,16+1
-; if chain_length <=16, don't use the unrolled loop
-	jna     normalbeg0add16
-
-do16:
-	cmp     word ptr[edi+eax],bx
-	je      normalbeg2dc0
-
-maccn   MACRO   lab
-	and     eax,7fffh
-	mov     ax,word ptr[esi+eax*2]
-	cmp     ecx,eax
-	jnb     exitloop
-	cmp     word ptr[edi+eax],bx
-	je      lab
-	ENDM
-
-rcontloop0:
-	maccn   normalbeg2dc1
-
-rcontloop1:
-	maccn   normalbeg2dc2
-
-rcontloop2:
-	maccn   normalbeg2dc3
-
-rcontloop3:
-	maccn   normalbeg2dc4
-
-rcontloop4:
-	maccn   normalbeg2dc5
-
-rcontloop5:
-	maccn   normalbeg2dc6
-
-rcontloop6:
-	maccn   normalbeg2dc7
-
-rcontloop7:
-	maccn   normalbeg2dc8
-
-rcontloop8:
-	maccn   normalbeg2dc9
-
-rcontloop9:
-	maccn   normalbeg2dc10
-
-rcontloop10:
-	maccn   short normalbeg2dc11
-
-rcontloop11:
-	maccn   short normalbeg2dc12
-
-rcontloop12:
-	maccn   short normalbeg2dc13
-
-rcontloop13:
-	maccn   short normalbeg2dc14
-
-rcontloop14:
-	maccn   short normalbeg2dc15
-
-rcontloop15:
-	and     eax,7fffh
-	mov     ax,word ptr[esi+eax*2]
-	cmp     ecx,eax
-	jnb     exitloop
-
-	sub     chain_length,16
-	ja      do16
-	jmp     normalbeg0add16
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-normbeg MACRO   rcontlab,valsub
-; if we are here, we know that *(match+best_len-1) == scan_end
-	cmp     bp,word ptr[edx+eax]
-; if (match != scan_start) goto rcontlab
-	jne     rcontlab
-; calculate the good chain_length, and we'll compare scan and match string
-	add     chain_length,16-valsub
-	jmp     iseq
-	ENDM
-
-
-normalbeg2dc11:
-	normbeg rcontloop11,11
-
-normalbeg2dc12:
-	normbeg short rcontloop12,12
-
-normalbeg2dc13:
-	normbeg short rcontloop13,13
-
-normalbeg2dc14:
-	normbeg short rcontloop14,14
-
-normalbeg2dc15:
-	normbeg short rcontloop15,15
-
-normalbeg2dc10:
-	normbeg rcontloop10,10
-
-normalbeg2dc9:
-	normbeg rcontloop9,9
-
-normalbeg2dc8:
-	normbeg rcontloop8,8
-
-normalbeg2dc7:
-	normbeg rcontloop7,7
-
-normalbeg2dc6:
-	normbeg rcontloop6,6
-
-normalbeg2dc5:
-	normbeg rcontloop5,5
-
-normalbeg2dc4:
-	normbeg rcontloop4,4
-
-normalbeg2dc3:
-	normbeg rcontloop3,3
-
-normalbeg2dc2:
-	normbeg rcontloop2,2
-
-normalbeg2dc1:
-	normbeg rcontloop1,1
-
-normalbeg2dc0:
-	normbeg rcontloop0,0
-
-
-; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
-
-normalbeg2:
-	mov     edi,window
-
-	cmp     bp,word ptr[edi+eax]
-	jne     contloop3                   ; if *(ushf*)match != scan_start, continue
-
-iseq:
-; if we are here, we know that *(match+best_len-1) == scan_end
-; and (match == scan_start)
-
-	mov     edi,edx
-	mov     esi,scan                    ; esi = scan
-	add     edi,eax                     ; edi = window + cur_match = match
-
-	mov     edx,[esi+3]                 ; compare manually dword at match+3
-	xor     edx,[edi+3]                 ; and scan +3
-
-	jz      begincompare                ; if equal, go to long compare
-
-; we will determine the unmatch byte and calculate len (in esi)
-	or      dl,dl
-	je      eq1rr
-	mov     esi,3
-	jmp     trfinval
-eq1rr:
-	or      dx,dx
-	je      eq1
-
-	mov     esi,4
-	jmp     trfinval
-eq1:
-	and     edx,0ffffffh
-	jz      eq11
-	mov     esi,5
-	jmp     trfinval
-eq11:
-	mov     esi,6
-	jmp     trfinval
-
-begincompare:
-	; here we now scan and match begin same
-	add     edi,6
-	add     esi,6
-	mov     ecx,(MAX_MATCH-(2+4))/4     ; scan for at most MAX_MATCH bytes
-	repe    cmpsd                       ; loop until mismatch
-
-	je      trfin                       ; go to trfin if not unmatch
-; we determine the unmatch byte
-	sub     esi,4
-	mov     edx,[edi-4]
-	xor     edx,[esi]
-
-	or      dl,dl
-	jnz     trfin
-	inc     esi
-
-	or      dx,dx
-	jnz     trfin
-	inc     esi
-
-	and     edx,0ffffffh
-	jnz     trfin
-	inc     esi
-
-trfin:
-	sub     esi,scan          ; esi = len
-trfinval:
-; here we have finised compare, and esi contain len of equal string
-	cmp     esi,best_len        ; if len > best_len, go newbestlen
-	ja      short newbestlen
-; now we restore edx, ecx and esi, for the big loop
-	mov     esi,prev
-	mov     ecx,limit
-	mov     edx,window
-	jmp     contloop3
-
-newbestlen:
-	mov     best_len,esi        ; len become best_len
-
-	mov     match_start,eax     ; save new position as match_start
-	cmp     esi,nice_match      ; if best_len >= nice_match, exit
-	jae     exitloop
-	mov     ecx,scan
-	mov     edx,window          ; restore edx=window
-	add     ecx,esi
-	add     esi,edx
-
-	dec     esi
-	mov     windowlen,esi       ; windowlen = window + best_len-1
-	mov     bx,[ecx-1]          ; bx = *(scan+best_len-1) = scan_end
-
-; now we restore ecx and esi, for the big loop :
-	mov     esi,prev
-	mov     ecx,limit
-	jmp     contloop3
-
-exitloop:
-; exit : s->match_start=match_start
-	mov     ebx,match_start
-	mov     ebp,str_s
-	mov     ecx,best_len
-	mov     dword ptr [ebp+dep_match_start],ebx
-	mov     eax,dword ptr [ebp+dep_lookahead]
-	cmp     ecx,eax
-	ja      minexlo
-	mov     eax,ecx
-minexlo:
-; return min(best_len,s->lookahead)
-
-; restore stack and register ebx,esi,edi,ebp
-	add     esp,NbStackAdd
-
-	pop     ebx
-	pop     esi
-	pop     edi
-	pop     ebp
-	ret
-InfoAuthor:
-; please don't remove this string !
-; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
-	db     0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
-
-
-
-IFDEF NOUNDERLINE
-longest_match_7fff   endp
-ELSE
-_longest_match_7fff  endp
-ENDIF
-
-
-IFDEF NOUNDERLINE
-cpudetect32     proc near
-ELSE
-_cpudetect32    proc near
-ENDIF
-
-	push	ebx
-
-	pushfd                  ; push original EFLAGS
-	pop     eax             ; get original EFLAGS
-	mov     ecx, eax        ; save original EFLAGS
-	xor     eax, 40000h     ; flip AC bit in EFLAGS
-	push    eax             ; save new EFLAGS value on stack
-	popfd                   ; replace current EFLAGS value
-	pushfd                  ; get new EFLAGS
-	pop     eax             ; store new EFLAGS in EAX
-	xor     eax, ecx        ; canÂ’t toggle AC bit, processor=80386
-	jz      end_cpu_is_386  ; jump if 80386 processor
-	push    ecx
-	popfd                   ; restore AC bit in EFLAGS first
-
-	pushfd
-	pushfd
-	pop     ecx
-
-	mov     eax, ecx        ; get original EFLAGS
-	xor     eax, 200000h    ; flip ID bit in EFLAGS
-	push    eax             ; save new EFLAGS value on stack
-	popfd                   ; replace current EFLAGS value
-	pushfd                  ; get new EFLAGS
-	pop		eax	            ; store new EFLAGS in EAX
-	popfd                   ; restore original EFLAGS
-	xor		eax, ecx        ; canÂ’t toggle ID bit,
-	je		is_old_486		; processor=old
-
-	mov     eax,1
-	db      0fh,0a2h        ;CPUID
-
-exitcpudetect:
-	pop	ebx
-	ret
-
-end_cpu_is_386:
-	mov     eax,0300h
-	jmp     exitcpudetect
-
-is_old_486:
-	mov     eax,0400h
-	jmp     exitcpudetect
-
-IFDEF NOUNDERLINE
-cpudetect32     endp
-ELSE
-_cpudetect32    endp
-ENDIF
-
-
-
-
-MAX_MATCH       equ     258
-MIN_MATCH       equ     3
-MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)
-MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)
-
-
-;;; stack frame offsets
-
-chainlenwmask	equ  esp + 0	; high word: current chain len
-					; low word: s->wmask
-window		equ  esp + 4	; local copy of s->window
-windowbestlen	equ  esp + 8	; s->window + bestlen
-scanstart	equ  esp + 16	; first two bytes of string
-scanend		equ  esp + 12	; last two bytes of string
-scanalign	equ  esp + 20	; dword-misalignment of string
-nicematch	equ  esp + 24	; a good enough match size
-bestlen		equ  esp + 28	; size of best match so far
-scan		equ  esp + 32	; ptr to string wanting match
-
-LocalVarsSize	equ 36
-;	saved ebx	byte esp + 36
-;	saved edi	byte esp + 40
-;	saved esi	byte esp + 44
-;	saved ebp	byte esp + 48
-;	return address	byte esp + 52
-deflatestate	equ  esp + 56	; the function arguments
-curmatch	equ  esp + 60
-
-;;; Offsets for fields in the deflate_state structure. These numbers
-;;; are calculated from the definition of deflate_state, with the
-;;; assumption that the compiler will dword-align the fields. (Thus,
-;;; changing the definition of deflate_state could easily cause this
-;;; program to crash horribly, without so much as a warning at
-;;; compile time. Sigh.)
-
-dsWSize		equ 36+addstr-4
-dsWMask		equ 44+addstr-4
-dsWindow	equ 48+addstr-4
-dsPrev		equ 56+addstr-4
-dsMatchLen	equ 88+addstr-4
-dsPrevMatch	equ 92+addstr-4
-dsStrStart	equ 100+addstr-4
-dsMatchStart	equ 104+addstr-4
-dsLookahead	equ 108+addstr-4
-dsPrevLen	equ 112+addstr-4
-dsMaxChainLen	equ 116+addstr-4
-dsGoodMatch	equ 132+addstr-4
-dsNiceMatch	equ 136+addstr-4
-
-
-;;; match.asm -- Pentium-Pro-optimized version of longest_match()
-;;; Written for zlib 1.1.2
-;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
-;;;
-;;; This is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License.
-
-;GLOBAL	_longest_match, _match_init
-
-
-;SECTION	.text
-
-;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
-
-;_longest_match:
-IFDEF NOUNDERLINE
-longest_match_686   proc near
-ELSE
-_longest_match_686  proc near
-ENDIF
-
-
-;;; Save registers that the compiler may be using, and adjust esp to
-;;; make room for our stack frame.
-
-		push	ebp
-		push	edi
-		push	esi
-		push	ebx
-		sub	esp, LocalVarsSize
-
-;;; Retrieve the function arguments. ecx will hold cur_match
-;;; throughout the entire function. edx will hold the pointer to the
-;;; deflate_state structure during the function's setup (before
-;;; entering the main loop.
-
-		mov	edx, [deflatestate]
-		mov	ecx, [curmatch]
-
-;;; uInt wmask = s->w_mask;
-;;; unsigned chain_length = s->max_chain_length;
-;;; if (s->prev_length >= s->good_match) {
-;;;     chain_length >>= 2;
-;;; }
-
-		mov	eax, [edx + dsPrevLen]
-		mov	ebx, [edx + dsGoodMatch]
-		cmp	eax, ebx
-		mov	eax, [edx + dsWMask]
-		mov	ebx, [edx + dsMaxChainLen]
-		jl	LastMatchGood
-		shr	ebx, 2
-LastMatchGood:
-
-;;; chainlen is decremented once beforehand so that the function can
-;;; use the sign flag instead of the zero flag for the exit test.
-;;; It is then shifted into the high word, to make room for the wmask
-;;; value, which it will always accompany.
-
-		dec	ebx
-		shl	ebx, 16
-		or	ebx, eax
-		mov	[chainlenwmask], ebx
-
-;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-		mov	eax, [edx + dsNiceMatch]
-		mov	ebx, [edx + dsLookahead]
-		cmp	ebx, eax
-		jl	LookaheadLess
-		mov	ebx, eax
-LookaheadLess:	mov	[nicematch], ebx
-
-;;; register Bytef *scan = s->window + s->strstart;
-
-		mov	esi, [edx + dsWindow]
-		mov	[window], esi
-		mov	ebp, [edx + dsStrStart]
-		lea	edi, [esi + ebp]
-		mov	[scan], edi
-
-;;; Determine how many bytes the scan ptr is off from being
-;;; dword-aligned.
-
-		mov	eax, edi
-		neg	eax
-		and	eax, 3
-		mov	[scanalign], eax
-
-;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
-
-		mov	eax, [edx + dsWSize]
-		sub	eax, MIN_LOOKAHEAD
-		sub	ebp, eax
-		jg	LimitPositive
-		xor	ebp, ebp
-LimitPositive:
-
-;;; int best_len = s->prev_length;
-
-		mov	eax, [edx + dsPrevLen]
-		mov	[bestlen], eax
-
-;;; Store the sum of s->window + best_len in esi locally, and in esi.
-
-		add	esi, eax
-		mov	[windowbestlen], esi
-
-;;; register ush scan_start = *(ushf*)scan;
-;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
-;;; Posf *prev = s->prev;
-
-		movzx	ebx, word ptr [edi]
-		mov	[scanstart], ebx
-		movzx	ebx, word ptr [edi + eax - 1]
-		mov	[scanend], ebx
-		mov	edi, [edx + dsPrev]
-
-;;; Jump into the main loop.
-
-		mov	edx, [chainlenwmask]
-		jmp	short LoopEntry
-
-align 4
-
-;;; do {
-;;;     match = s->window + cur_match;
-;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
-;;;         *(ushf*)match != scan_start) continue;
-;;;     [...]
-;;; } while ((cur_match = prev[cur_match & wmask]) > limit
-;;;          && --chain_length != 0);
-;;;
-;;; Here is the inner loop of the function. The function will spend the
-;;; majority of its time in this loop, and majority of that time will
-;;; be spent in the first ten instructions.
-;;;
-;;; Within this loop:
-;;; ebx = scanend
-;;; ecx = curmatch
-;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-;;; esi = windowbestlen - i.e., (window + bestlen)
-;;; edi = prev
-;;; ebp = limit
-
-LookupLoop:
-		and	ecx, edx
-		movzx	ecx, word ptr [edi + ecx*2]
-		cmp	ecx, ebp
-		jbe	LeaveNow
-		sub	edx, 00010000h
-		js	LeaveNow
-LoopEntry:	movzx	eax, word ptr [esi + ecx - 1]
-		cmp	eax, ebx
-		jnz	LookupLoop
-		mov	eax, [window]
-		movzx	eax, word ptr [eax + ecx]
-		cmp	eax, [scanstart]
-		jnz	LookupLoop
-
-;;; Store the current value of chainlen.
-
-		mov	[chainlenwmask], edx
-
-;;; Point edi to the string under scrutiny, and esi to the string we
-;;; are hoping to match it up with. In actuality, esi and edi are
-;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
-;;; initialized to -(MAX_MATCH_8 - scanalign).
-
-		mov	esi, [window]
-		mov	edi, [scan]
-		add	esi, ecx
-		mov	eax, [scanalign]
-		mov	edx, 0fffffef8h; -(MAX_MATCH_8)
-		lea	edi, [edi + eax + 0108h] ;MAX_MATCH_8]
-		lea	esi, [esi + eax + 0108h] ;MAX_MATCH_8]
-
-;;; Test the strings for equality, 8 bytes at a time. At the end,
-;;; adjust edx so that it is offset to the exact byte that mismatched.
-;;;
-;;; We already know at this point that the first three bytes of the
-;;; strings match each other, and they can be safely passed over before
-;;; starting the compare loop. So what this code does is skip over 0-3
-;;; bytes, as much as necessary in order to dword-align the edi
-;;; pointer. (esi will still be misaligned three times out of four.)
-;;;
-;;; It should be confessed that this loop usually does not represent
-;;; much of the total running time. Replacing it with a more
-;;; straightforward "rep cmpsb" would not drastically degrade
-;;; performance.
-
-LoopCmps:
-		mov	eax, [esi + edx]
-		xor	eax, [edi + edx]
-		jnz	LeaveLoopCmps
-		mov	eax, [esi + edx + 4]
-		xor	eax, [edi + edx + 4]
-		jnz	LeaveLoopCmps4
-		add	edx, 8
-		jnz	LoopCmps
-		jmp	short LenMaximum
-LeaveLoopCmps4:	add	edx, 4
-LeaveLoopCmps:	test	eax, 0000FFFFh
-		jnz	LenLower
-		add	edx,  2
-		shr	eax, 16
-LenLower:	sub	al, 1
-		adc	edx, 0
-
-;;; Calculate the length of the match. If it is longer than MAX_MATCH,
-;;; then automatically accept it as the best possible match and leave.
-
-		lea	eax, [edi + edx]
-		mov	edi, [scan]
-		sub	eax, edi
-		cmp	eax, MAX_MATCH
-		jge	LenMaximum
-
-;;; If the length of the match is not longer than the best match we
-;;; have so far, then forget it and return to the lookup loop.
-
-		mov	edx, [deflatestate]
-		mov	ebx, [bestlen]
-		cmp	eax, ebx
-		jg	LongerMatch
-		mov	esi, [windowbestlen]
-		mov	edi, [edx + dsPrev]
-		mov	ebx, [scanend]
-		mov	edx, [chainlenwmask]
-		jmp	LookupLoop
-
-;;;         s->match_start = cur_match;
-;;;         best_len = len;
-;;;         if (len >= nice_match) break;
-;;;         scan_end = *(ushf*)(scan+best_len-1);
-
-LongerMatch:	mov	ebx, [nicematch]
-		mov	[bestlen], eax
-		mov	[edx + dsMatchStart], ecx
-		cmp	eax, ebx
-		jge	LeaveNow
-		mov	esi, [window]
-		add	esi, eax
-		mov	[windowbestlen], esi
-		movzx	ebx, word ptr [edi + eax - 1]
-		mov	edi, [edx + dsPrev]
-		mov	[scanend], ebx
-		mov	edx, [chainlenwmask]
-		jmp	LookupLoop
-
-;;; Accept the current string, with the maximum possible length.
-
-LenMaximum:	mov	edx, [deflatestate]
-		mov	dword ptr [bestlen], MAX_MATCH
-		mov	[edx + dsMatchStart], ecx
-
-;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-;;; return s->lookahead;
-
-LeaveNow:
-		mov	edx, [deflatestate]
-		mov	ebx, [bestlen]
-		mov	eax, [edx + dsLookahead]
-		cmp	ebx, eax
-		jg	LookaheadRet
-		mov	eax, ebx
-LookaheadRet:
-
-;;; Restore the stack and return from whence we came.
-
-		add	esp, LocalVarsSize
-		pop	ebx
-		pop	esi
-		pop	edi
-		pop	ebp
-
-		ret
-; please don't remove this string !
-; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
-	db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
-
-IFDEF NOUNDERLINE
-longest_match_686   endp
-ELSE
-_longest_match_686  endp
-ENDIF
-
-_TEXT   ends
-end
+; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86

+; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.

+; File written by Gilles Vollant, by modifiying the longest_match

+;  from Jean-loup Gailly in deflate.c

+;

+;         http://www.zlib.net

+;         http://www.winimage.com/zLibDll

+;         http://www.muppetlabs.com/~breadbox/software/assembly.html

+;

+; For Visual C++ 4.x and higher and ML 6.x and higher

+;   ml.exe is in directory \MASM611C of Win95 DDK

+;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm

+;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/

+;

+; this file contain two implementation of longest_match

+;

+;  longest_match_7fff : written 1996 by Gilles Vollant optimized for 

+;            first Pentium. Assume s->w_mask == 0x7fff

+;  longest_match_686 : written by Brian raiter (1998), optimized for Pentium Pro

+;

+;  for using an seembly version of longest_match, you need define ASMV in project

+;  There is two way in using gvmat32.asm

+;

+;  A) Suggested method

+;    if you want include both longest_match_7fff and longest_match_686

+;    compile the asm file running

+;           ml /coff /Zi /Flgvmat32.lst /c gvmat32.asm

+;    and include gvmat32c.c in your project

+;    if you have an old cpu (386,486 or first Pentium) and s->w_mask==0x7fff,

+;        longest_match_7fff will be used

+;    if you have a more modern CPU (Pentium Pro, II and higher)

+;        longest_match_686 will be used

+;    on old cpu with s->w_mask!=0x7fff, longest_match_686 will be used,

+;        but this is not a sitation you'll find often

+;

+;  B) Alternative

+;    if you are not interresed in old cpu performance and want the smaller

+;       binaries possible

+;

+;    compile the asm file running

+;           ml /coff /Zi /c /Flgvmat32.lst /DNOOLDPENTIUMCODE gvmat32.asm

+;    and do not include gvmat32c.c in your project (ou define also 

+;              NOOLDPENTIUMCODE)

+;

+; note : as I known, longest_match_686 is very faster than longest_match_7fff

+;        on pentium Pro/II/III, faster (but less) in P4, but it seem

+;        longest_match_7fff can be faster (very very litte) on AMD Athlon64/K8

+;

+; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2

+

+;uInt longest_match_7fff(s, cur_match)

+;    deflate_state *s;

+;    IPos cur_match;                             /* current match */

+

+    NbStack         equ     76

+    cur_match       equ     dword ptr[esp+NbStack-0]

+    str_s           equ     dword ptr[esp+NbStack-4]

+; 5 dword on top (ret,ebp,esi,edi,ebx)

+    adrret          equ     dword ptr[esp+NbStack-8]

+    pushebp         equ     dword ptr[esp+NbStack-12]

+    pushedi         equ     dword ptr[esp+NbStack-16]

+    pushesi         equ     dword ptr[esp+NbStack-20]

+    pushebx         equ     dword ptr[esp+NbStack-24]

+

+    chain_length    equ     dword ptr [esp+NbStack-28]

+    limit           equ     dword ptr [esp+NbStack-32]

+    best_len        equ     dword ptr [esp+NbStack-36]

+    window          equ     dword ptr [esp+NbStack-40]

+    prev            equ     dword ptr [esp+NbStack-44]

+    scan_start      equ      word ptr [esp+NbStack-48]

+    wmask           equ     dword ptr [esp+NbStack-52]

+    match_start_ptr equ     dword ptr [esp+NbStack-56]

+    nice_match      equ     dword ptr [esp+NbStack-60]

+    scan            equ     dword ptr [esp+NbStack-64]

+

+    windowlen       equ     dword ptr [esp+NbStack-68]

+    match_start     equ     dword ptr [esp+NbStack-72]

+    strend          equ     dword ptr [esp+NbStack-76]

+    NbStackAdd      equ     (NbStack-24)

+

+    .386p

+

+    name    gvmatch

+    .MODEL  FLAT

+

+

+

+;  all the +zlib1222add offsets are due to the addition of fields

+;  in zlib in the deflate_state structure since the asm code was first written

+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").

+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").

+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").

+

+    zlib1222add         equ     8

+

+;  Note : these value are good with a 8 bytes boundary pack structure

+    dep_chain_length    equ     74h+zlib1222add

+    dep_window          equ     30h+zlib1222add

+    dep_strstart        equ     64h+zlib1222add

+    dep_prev_length     equ     70h+zlib1222add

+    dep_nice_match      equ     88h+zlib1222add

+    dep_w_size          equ     24h+zlib1222add

+    dep_prev            equ     38h+zlib1222add

+    dep_w_mask          equ     2ch+zlib1222add

+    dep_good_match      equ     84h+zlib1222add

+    dep_match_start     equ     68h+zlib1222add

+    dep_lookahead       equ     6ch+zlib1222add

+

+

+_TEXT                   segment

+

+IFDEF NOUNDERLINE

+   IFDEF NOOLDPENTIUMCODE

+            public  longest_match

+            public  match_init

+   ELSE            

+            public  longest_match_7fff

+            public  cpudetect32

+            public  longest_match_686

+   ENDIF

+ELSE

+   IFDEF NOOLDPENTIUMCODE

+            public  _longest_match

+            public  _match_init

+   ELSE

+            public  _longest_match_7fff

+            public  _cpudetect32

+            public  _longest_match_686

+   ENDIF

+ENDIF

+

+    MAX_MATCH           equ     258

+    MIN_MATCH           equ     3

+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)

+

+

+

+IFNDEF NOOLDPENTIUMCODE

+IFDEF NOUNDERLINE

+longest_match_7fff   proc near

+ELSE

+_longest_match_7fff  proc near

+ENDIF

+

+    mov     edx,[esp+4]

+

+

+

+    push    ebp

+    push    edi

+    push    esi

+    push    ebx

+

+    sub     esp,NbStackAdd

+

+; initialize or check the variables used in match.asm.

+    mov     ebp,edx

+

+; chain_length = s->max_chain_length

+; if (prev_length>=good_match) chain_length >>= 2

+    mov     edx,[ebp+dep_chain_length]

+    mov     ebx,[ebp+dep_prev_length]

+    cmp     [ebp+dep_good_match],ebx

+    ja      noshr

+    shr     edx,2

+noshr:

+; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop

+    inc     edx

+    mov     edi,[ebp+dep_nice_match]

+    mov     chain_length,edx

+    mov     eax,[ebp+dep_lookahead]

+    cmp     eax,edi

+; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

+    jae     nolookaheadnicematch

+    mov     edi,eax

+nolookaheadnicematch:

+; best_len = s->prev_length

+    mov     best_len,ebx

+

+; window = s->window

+    mov     esi,[ebp+dep_window]

+    mov     ecx,[ebp+dep_strstart]

+    mov     window,esi

+

+    mov     nice_match,edi

+; scan = window + strstart

+    add     esi,ecx

+    mov     scan,esi

+; dx = *window

+    mov     dx,word ptr [esi]

+; bx = *(window+best_len-1)

+    mov     bx,word ptr [esi+ebx-1]

+    add     esi,MAX_MATCH-1

+; scan_start = *scan

+    mov     scan_start,dx

+; strend = scan + MAX_MATCH-1

+    mov     strend,esi

+; bx = scan_end = *(window+best_len-1)

+

+;    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?

+;        s->strstart - (IPos)MAX_DIST(s) : NIL;

+

+    mov     esi,[ebp+dep_w_size]

+    sub     esi,MIN_LOOKAHEAD

+; here esi = MAX_DIST(s)

+    sub     ecx,esi

+    ja      nodist

+    xor     ecx,ecx

+nodist:

+    mov     limit,ecx

+

+; prev = s->prev

+    mov     edx,[ebp+dep_prev]

+    mov     prev,edx

+

+;

+    mov     edx,dword ptr [ebp+dep_match_start]

+    mov     bp,scan_start

+    mov     eax,cur_match

+    mov     match_start,edx

+

+    mov     edx,window

+    mov     edi,edx

+    add     edi,best_len

+    mov     esi,prev

+    dec     edi

+; windowlen = window + best_len -1

+    mov     windowlen,edi

+

+    jmp     beginloop2

+    align   4

+

+; here, in the loop

+;       eax = ax = cur_match

+;       ecx = limit

+;        bx = scan_end

+;        bp = scan_start

+;       edi = windowlen (window + best_len -1)

+;       esi = prev

+

+

+;// here; chain_length <=16

+normalbeg0add16:

+    add     chain_length,16

+    jz      exitloop

+normalbeg0:

+    cmp     word ptr[edi+eax],bx

+    je      normalbeg2noroll

+rcontlabnoroll:

+; cur_match = prev[cur_match & wmask]

+    and     eax,7fffh

+    mov     ax,word ptr[esi+eax*2]

+; if cur_match > limit, go to exitloop

+    cmp     ecx,eax

+    jnb     exitloop

+; if --chain_length != 0, go to exitloop

+    dec     chain_length

+    jnz     normalbeg0

+    jmp     exitloop

+

+normalbeg2noroll:

+; if (scan_start==*(cur_match+window)) goto normalbeg2

+    cmp     bp,word ptr[edx+eax]

+    jne     rcontlabnoroll

+    jmp     normalbeg2

+

+contloop3:

+    mov     edi,windowlen

+

+; cur_match = prev[cur_match & wmask]

+    and     eax,7fffh

+    mov     ax,word ptr[esi+eax*2]

+; if cur_match > limit, go to exitloop

+    cmp     ecx,eax

+jnbexitloopshort1:

+    jnb     exitloop

+; if --chain_length != 0, go to exitloop

+

+

+; begin the main loop

+beginloop2:

+    sub     chain_length,16+1

+; if chain_length <=16, don't use the unrolled loop

+    jna     normalbeg0add16

+

+do16:

+    cmp     word ptr[edi+eax],bx

+    je      normalbeg2dc0

+

+maccn   MACRO   lab

+    and     eax,7fffh

+    mov     ax,word ptr[esi+eax*2]

+    cmp     ecx,eax

+    jnb     exitloop

+    cmp     word ptr[edi+eax],bx

+    je      lab

+    ENDM

+

+rcontloop0:

+    maccn   normalbeg2dc1

+

+rcontloop1:

+    maccn   normalbeg2dc2

+

+rcontloop2:

+    maccn   normalbeg2dc3

+

+rcontloop3:

+    maccn   normalbeg2dc4

+

+rcontloop4:

+    maccn   normalbeg2dc5

+

+rcontloop5:

+    maccn   normalbeg2dc6

+

+rcontloop6:

+    maccn   normalbeg2dc7

+

+rcontloop7:

+    maccn   normalbeg2dc8

+

+rcontloop8:

+    maccn   normalbeg2dc9

+

+rcontloop9:

+    maccn   normalbeg2dc10

+

+rcontloop10:

+    maccn   short normalbeg2dc11

+

+rcontloop11:

+    maccn   short normalbeg2dc12

+

+rcontloop12:

+    maccn   short normalbeg2dc13

+

+rcontloop13:

+    maccn   short normalbeg2dc14

+

+rcontloop14:

+    maccn   short normalbeg2dc15

+

+rcontloop15:

+    and     eax,7fffh

+    mov     ax,word ptr[esi+eax*2]

+    cmp     ecx,eax

+    jnb     exitloop

+

+    sub     chain_length,16

+    ja      do16

+    jmp     normalbeg0add16

+

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+

+normbeg MACRO   rcontlab,valsub

+; if we are here, we know that *(match+best_len-1) == scan_end

+    cmp     bp,word ptr[edx+eax]

+; if (match != scan_start) goto rcontlab

+    jne     rcontlab

+; calculate the good chain_length, and we'll compare scan and match string

+    add     chain_length,16-valsub

+    jmp     iseq

+    ENDM

+

+

+normalbeg2dc11:

+    normbeg rcontloop11,11

+

+normalbeg2dc12:

+    normbeg short rcontloop12,12

+

+normalbeg2dc13:

+    normbeg short rcontloop13,13

+

+normalbeg2dc14:

+    normbeg short rcontloop14,14

+

+normalbeg2dc15:

+    normbeg short rcontloop15,15

+

+normalbeg2dc10:

+    normbeg rcontloop10,10

+

+normalbeg2dc9:

+    normbeg rcontloop9,9

+

+normalbeg2dc8:

+    normbeg rcontloop8,8

+

+normalbeg2dc7:

+    normbeg rcontloop7,7

+

+normalbeg2dc6:

+    normbeg rcontloop6,6

+

+normalbeg2dc5:

+    normbeg rcontloop5,5

+

+normalbeg2dc4:

+    normbeg rcontloop4,4

+

+normalbeg2dc3:

+    normbeg rcontloop3,3

+

+normalbeg2dc2:

+    normbeg rcontloop2,2

+

+normalbeg2dc1:

+    normbeg rcontloop1,1

+

+normalbeg2dc0:

+    normbeg rcontloop0,0

+

+

+; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end

+

+normalbeg2:

+    mov     edi,window

+

+    cmp     bp,word ptr[edi+eax]

+    jne     contloop3                   ; if *(ushf*)match != scan_start, continue

+

+iseq:

+; if we are here, we know that *(match+best_len-1) == scan_end

+; and (match == scan_start)

+

+    mov     edi,edx

+    mov     esi,scan                    ; esi = scan

+    add     edi,eax                     ; edi = window + cur_match = match

+

+    mov     edx,[esi+3]                 ; compare manually dword at match+3

+    xor     edx,[edi+3]                 ; and scan +3

+

+    jz      begincompare                ; if equal, go to long compare

+

+; we will determine the unmatch byte and calculate len (in esi)

+    or      dl,dl

+    je      eq1rr

+    mov     esi,3

+    jmp     trfinval

+eq1rr:

+    or      dx,dx

+    je      eq1

+

+    mov     esi,4

+    jmp     trfinval

+eq1:

+    and     edx,0ffffffh

+    jz      eq11

+    mov     esi,5

+    jmp     trfinval

+eq11:

+    mov     esi,6

+    jmp     trfinval

+

+begincompare:

+    ; here we now scan and match begin same

+    add     edi,6

+    add     esi,6

+    mov     ecx,(MAX_MATCH-(2+4))/4     ; scan for at most MAX_MATCH bytes

+    repe    cmpsd                       ; loop until mismatch

+

+    je      trfin                       ; go to trfin if not unmatch

+; we determine the unmatch byte

+    sub     esi,4

+    mov     edx,[edi-4]

+    xor     edx,[esi]

+

+    or      dl,dl

+    jnz     trfin

+    inc     esi

+

+    or      dx,dx

+    jnz     trfin

+    inc     esi

+

+    and     edx,0ffffffh

+    jnz     trfin

+    inc     esi

+

+trfin:

+    sub     esi,scan          ; esi = len

+trfinval:

+; here we have finised compare, and esi contain len of equal string

+    cmp     esi,best_len        ; if len > best_len, go newbestlen

+    ja      short newbestlen

+; now we restore edx, ecx and esi, for the big loop

+    mov     esi,prev

+    mov     ecx,limit

+    mov     edx,window

+    jmp     contloop3

+

+newbestlen:

+    mov     best_len,esi        ; len become best_len

+

+    mov     match_start,eax     ; save new position as match_start

+    cmp     esi,nice_match      ; if best_len >= nice_match, exit

+    jae     exitloop

+    mov     ecx,scan

+    mov     edx,window          ; restore edx=window

+    add     ecx,esi

+    add     esi,edx

+

+    dec     esi

+    mov     windowlen,esi       ; windowlen = window + best_len-1

+    mov     bx,[ecx-1]          ; bx = *(scan+best_len-1) = scan_end

+

+; now we restore ecx and esi, for the big loop :

+    mov     esi,prev

+    mov     ecx,limit

+    jmp     contloop3

+

+exitloop:

+; exit : s->match_start=match_start

+    mov     ebx,match_start

+    mov     ebp,str_s

+    mov     ecx,best_len

+    mov     dword ptr [ebp+dep_match_start],ebx

+    mov     eax,dword ptr [ebp+dep_lookahead]

+    cmp     ecx,eax

+    ja      minexlo

+    mov     eax,ecx

+minexlo:

+; return min(best_len,s->lookahead)

+

+; restore stack and register ebx,esi,edi,ebp

+    add     esp,NbStackAdd

+

+    pop     ebx

+    pop     esi

+    pop     edi

+    pop     ebp

+    ret

+InfoAuthor:

+; please don't remove this string !

+; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!

+    db     0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah

+

+

+

+IFDEF NOUNDERLINE

+longest_match_7fff   endp

+ELSE

+_longest_match_7fff  endp

+ENDIF

+

+

+IFDEF NOUNDERLINE

+cpudetect32     proc near

+ELSE

+_cpudetect32    proc near

+ENDIF

+

+    push    ebx

+

+    pushfd                  ; push original EFLAGS

+    pop     eax             ; get original EFLAGS

+    mov     ecx, eax        ; save original EFLAGS

+    xor     eax, 40000h     ; flip AC bit in EFLAGS

+    push    eax             ; save new EFLAGS value on stack

+    popfd                   ; replace current EFLAGS value

+    pushfd                  ; get new EFLAGS

+    pop     eax             ; store new EFLAGS in EAX

+    xor     eax, ecx        ; canÂ’t toggle AC bit, processor=80386

+    jz      end_cpu_is_386  ; jump if 80386 processor

+    push    ecx

+    popfd                   ; restore AC bit in EFLAGS first

+

+    pushfd

+    pushfd

+    pop     ecx

+

+    mov     eax, ecx        ; get original EFLAGS

+    xor     eax, 200000h    ; flip ID bit in EFLAGS

+    push    eax             ; save new EFLAGS value on stack

+    popfd                   ; replace current EFLAGS value

+    pushfd                  ; get new EFLAGS

+    pop     eax             ; store new EFLAGS in EAX

+    popfd                   ; restore original EFLAGS

+    xor     eax, ecx        ; canÂ’t toggle ID bit,

+    je      is_old_486      ; processor=old

+

+    mov     eax,1

+    db      0fh,0a2h        ;CPUID

+

+exitcpudetect:

+    pop ebx

+    ret

+

+end_cpu_is_386:

+    mov     eax,0300h

+    jmp     exitcpudetect

+

+is_old_486:

+    mov     eax,0400h

+    jmp     exitcpudetect

+

+IFDEF NOUNDERLINE

+cpudetect32     endp

+ELSE

+_cpudetect32    endp

+ENDIF

+ENDIF

+

+MAX_MATCH       equ     258

+MIN_MATCH       equ     3

+MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)

+MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)

+

+

+;;; stack frame offsets

+

+chainlenwmask   equ  esp + 0    ; high word: current chain len

+                    ; low word: s->wmask

+window      equ  esp + 4    ; local copy of s->window

+windowbestlen   equ  esp + 8    ; s->window + bestlen

+scanstart   equ  esp + 16   ; first two bytes of string

+scanend     equ  esp + 12   ; last two bytes of string

+scanalign   equ  esp + 20   ; dword-misalignment of string

+nicematch   equ  esp + 24   ; a good enough match size

+bestlen     equ  esp + 28   ; size of best match so far

+scan        equ  esp + 32   ; ptr to string wanting match

+

+LocalVarsSize   equ 36

+;   saved ebx   byte esp + 36

+;   saved edi   byte esp + 40

+;   saved esi   byte esp + 44

+;   saved ebp   byte esp + 48

+;   return address  byte esp + 52

+deflatestate    equ  esp + 56   ; the function arguments

+curmatch    equ  esp + 60

+

+;;; Offsets for fields in the deflate_state structure. These numbers

+;;; are calculated from the definition of deflate_state, with the

+;;; assumption that the compiler will dword-align the fields. (Thus,

+;;; changing the definition of deflate_state could easily cause this

+;;; program to crash horribly, without so much as a warning at

+;;; compile time. Sigh.)

+

+dsWSize     equ 36+zlib1222add

+dsWMask     equ 44+zlib1222add

+dsWindow    equ 48+zlib1222add

+dsPrev      equ 56+zlib1222add

+dsMatchLen  equ 88+zlib1222add

+dsPrevMatch equ 92+zlib1222add

+dsStrStart  equ 100+zlib1222add

+dsMatchStart    equ 104+zlib1222add

+dsLookahead equ 108+zlib1222add

+dsPrevLen   equ 112+zlib1222add

+dsMaxChainLen   equ 116+zlib1222add

+dsGoodMatch equ 132+zlib1222add

+dsNiceMatch equ 136+zlib1222add

+

+

+;;; match.asm -- Pentium-Pro-optimized version of longest_match()

+;;; Written for zlib 1.1.2

+;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>

+;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html

+;;;

+;;; This is free software; you can redistribute it and/or modify it

+;;; under the terms of the GNU General Public License.

+

+;GLOBAL _longest_match, _match_init

+

+

+;SECTION    .text

+

+;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)

+

+;_longest_match:

+IFDEF NOOLDPENTIUMCODE

+    IFDEF NOUNDERLINE

+    longest_match       proc near

+    ELSE

+    _longest_match      proc near

+    ENDIF

+ELSE

+    IFDEF NOUNDERLINE

+    longest_match_686   proc near

+    ELSE

+    _longest_match_686  proc near

+    ENDIF

+ENDIF

+

+;;; Save registers that the compiler may be using, and adjust esp to

+;;; make room for our stack frame.

+

+        push    ebp

+        push    edi

+        push    esi

+        push    ebx

+        sub esp, LocalVarsSize

+

+;;; Retrieve the function arguments. ecx will hold cur_match

+;;; throughout the entire function. edx will hold the pointer to the

+;;; deflate_state structure during the function's setup (before

+;;; entering the main loop.

+

+        mov edx, [deflatestate]

+        mov ecx, [curmatch]

+

+;;; uInt wmask = s->w_mask;

+;;; unsigned chain_length = s->max_chain_length;

+;;; if (s->prev_length >= s->good_match) {

+;;;     chain_length >>= 2;

+;;; }

+

+        mov eax, [edx + dsPrevLen]

+        mov ebx, [edx + dsGoodMatch]

+        cmp eax, ebx

+        mov eax, [edx + dsWMask]

+        mov ebx, [edx + dsMaxChainLen]

+        jl  LastMatchGood

+        shr ebx, 2

+LastMatchGood:

+

+;;; chainlen is decremented once beforehand so that the function can

+;;; use the sign flag instead of the zero flag for the exit test.

+;;; It is then shifted into the high word, to make room for the wmask

+;;; value, which it will always accompany.

+

+        dec ebx

+        shl ebx, 16

+        or  ebx, eax

+        mov [chainlenwmask], ebx

+

+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

+

+        mov eax, [edx + dsNiceMatch]

+        mov ebx, [edx + dsLookahead]

+        cmp ebx, eax

+        jl  LookaheadLess

+        mov ebx, eax

+LookaheadLess:  mov [nicematch], ebx

+

+;;; register Bytef *scan = s->window + s->strstart;

+

+        mov esi, [edx + dsWindow]

+        mov [window], esi

+        mov ebp, [edx + dsStrStart]

+        lea edi, [esi + ebp]

+        mov [scan], edi

+

+;;; Determine how many bytes the scan ptr is off from being

+;;; dword-aligned.

+

+        mov eax, edi

+        neg eax

+        and eax, 3

+        mov [scanalign], eax

+

+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?

+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;

+

+        mov eax, [edx + dsWSize]

+        sub eax, MIN_LOOKAHEAD

+        sub ebp, eax

+        jg  LimitPositive

+        xor ebp, ebp

+LimitPositive:

+

+;;; int best_len = s->prev_length;

+

+        mov eax, [edx + dsPrevLen]

+        mov [bestlen], eax

+

+;;; Store the sum of s->window + best_len in esi locally, and in esi.

+

+        add esi, eax

+        mov [windowbestlen], esi

+

+;;; register ush scan_start = *(ushf*)scan;

+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);

+;;; Posf *prev = s->prev;

+

+        movzx   ebx, word ptr [edi]

+        mov [scanstart], ebx

+        movzx   ebx, word ptr [edi + eax - 1]

+        mov [scanend], ebx

+        mov edi, [edx + dsPrev]

+

+;;; Jump into the main loop.

+

+        mov edx, [chainlenwmask]

+        jmp short LoopEntry

+

+align 4

+

+;;; do {

+;;;     match = s->window + cur_match;

+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||

+;;;         *(ushf*)match != scan_start) continue;

+;;;     [...]

+;;; } while ((cur_match = prev[cur_match & wmask]) > limit

+;;;          && --chain_length != 0);

+;;;

+;;; Here is the inner loop of the function. The function will spend the

+;;; majority of its time in this loop, and majority of that time will

+;;; be spent in the first ten instructions.

+;;;

+;;; Within this loop:

+;;; ebx = scanend

+;;; ecx = curmatch

+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)

+;;; esi = windowbestlen - i.e., (window + bestlen)

+;;; edi = prev

+;;; ebp = limit

+

+LookupLoop:

+        and ecx, edx

+        movzx   ecx, word ptr [edi + ecx*2]

+        cmp ecx, ebp

+        jbe LeaveNow

+        sub edx, 00010000h

+        js  LeaveNow

+LoopEntry:  movzx   eax, word ptr [esi + ecx - 1]

+        cmp eax, ebx

+        jnz LookupLoop

+        mov eax, [window]

+        movzx   eax, word ptr [eax + ecx]

+        cmp eax, [scanstart]

+        jnz LookupLoop

+

+;;; Store the current value of chainlen.

+

+        mov [chainlenwmask], edx

+

+;;; Point edi to the string under scrutiny, and esi to the string we

+;;; are hoping to match it up with. In actuality, esi and edi are

+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is

+;;; initialized to -(MAX_MATCH_8 - scanalign).

+

+        mov esi, [window]

+        mov edi, [scan]

+        add esi, ecx

+        mov eax, [scanalign]

+        mov edx, 0fffffef8h; -(MAX_MATCH_8)

+        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]

+        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]

+

+;;; Test the strings for equality, 8 bytes at a time. At the end,

+;;; adjust edx so that it is offset to the exact byte that mismatched.

+;;;

+;;; We already know at this point that the first three bytes of the

+;;; strings match each other, and they can be safely passed over before

+;;; starting the compare loop. So what this code does is skip over 0-3

+;;; bytes, as much as necessary in order to dword-align the edi

+;;; pointer. (esi will still be misaligned three times out of four.)

+;;;

+;;; It should be confessed that this loop usually does not represent

+;;; much of the total running time. Replacing it with a more

+;;; straightforward "rep cmpsb" would not drastically degrade

+;;; performance.

+

+LoopCmps:

+        mov eax, [esi + edx]

+        xor eax, [edi + edx]

+        jnz LeaveLoopCmps

+        mov eax, [esi + edx + 4]

+        xor eax, [edi + edx + 4]

+        jnz LeaveLoopCmps4

+        add edx, 8

+        jnz LoopCmps

+        jmp short LenMaximum

+LeaveLoopCmps4: add edx, 4

+LeaveLoopCmps:  test    eax, 0000FFFFh

+        jnz LenLower

+        add edx,  2

+        shr eax, 16

+LenLower:   sub al, 1

+        adc edx, 0

+

+;;; Calculate the length of the match. If it is longer than MAX_MATCH,

+;;; then automatically accept it as the best possible match and leave.

+

+        lea eax, [edi + edx]

+        mov edi, [scan]

+        sub eax, edi

+        cmp eax, MAX_MATCH

+        jge LenMaximum

+

+;;; If the length of the match is not longer than the best match we

+;;; have so far, then forget it and return to the lookup loop.

+

+        mov edx, [deflatestate]

+        mov ebx, [bestlen]

+        cmp eax, ebx

+        jg  LongerMatch

+        mov esi, [windowbestlen]

+        mov edi, [edx + dsPrev]

+        mov ebx, [scanend]

+        mov edx, [chainlenwmask]

+        jmp LookupLoop

+

+;;;         s->match_start = cur_match;

+;;;         best_len = len;

+;;;         if (len >= nice_match) break;

+;;;         scan_end = *(ushf*)(scan+best_len-1);

+

+LongerMatch:    mov ebx, [nicematch]

+        mov [bestlen], eax

+        mov [edx + dsMatchStart], ecx

+        cmp eax, ebx

+        jge LeaveNow

+        mov esi, [window]

+        add esi, eax

+        mov [windowbestlen], esi

+        movzx   ebx, word ptr [edi + eax - 1]

+        mov edi, [edx + dsPrev]

+        mov [scanend], ebx

+        mov edx, [chainlenwmask]

+        jmp LookupLoop

+

+;;; Accept the current string, with the maximum possible length.

+

+LenMaximum: mov edx, [deflatestate]

+        mov dword ptr [bestlen], MAX_MATCH

+        mov [edx + dsMatchStart], ecx

+

+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;

+;;; return s->lookahead;

+

+LeaveNow:

+        mov edx, [deflatestate]

+        mov ebx, [bestlen]

+        mov eax, [edx + dsLookahead]

+        cmp ebx, eax

+        jg  LookaheadRet

+        mov eax, ebx

+LookaheadRet:

+

+;;; Restore the stack and return from whence we came.

+

+        add esp, LocalVarsSize

+        pop ebx

+        pop esi

+        pop edi

+        pop ebp

+

+        ret

+; please don't remove this string !

+; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!

+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah

+

+

+IFDEF NOOLDPENTIUMCODE

+    IFDEF NOUNDERLINE

+    longest_match       endp

+    ELSE

+    _longest_match      endp

+    ENDIF

+

+    IFDEF NOUNDERLINE

+    match_init      proc near

+                    ret

+    match_init      endp

+    ELSE

+    _match_init     proc near

+                    ret

+    _match_init     endp

+    ENDIF    

+ELSE

+    IFDEF NOUNDERLINE

+    longest_match_686   endp

+    ELSE

+    _longest_match_686  endp

+    ENDIF

+ENDIF

+

+_TEXT   ends

+end

diff --git a/contrib/masmx86/gvmat32c.c b/contrib/masmx86/gvmat32c.c
index 9ed25f3..7ad2b27 100644
--- a/contrib/masmx86/gvmat32c.c
+++ b/contrib/masmx86/gvmat32c.c
@@ -1,206 +1,62 @@
-/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
- * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
- * File written by Gilles Vollant, by modifiying the longest_match
- *  from Jean-loup Gailly in deflate.c
- *  it prepare all parameters and call the assembly longest_match_gvasm
- *  longest_match execute standard C code is wmask != 0x7fff
- *     (assembly code is faster with a fixed wmask)
- *
- */
-
-#include "deflate.h"
-
-#ifdef ASMV
-#define NIL 0
-
-#define UNALIGNED_OK
-
-
-/* if your C compiler don't add underline before function name,
-        define ADD_UNDERLINE_ASMFUNC */
-#ifdef ADD_UNDERLINE_ASMFUNC
-#define longest_match_7fff _longest_match_7fff
-#define longest_match_686  _longest_match_686
-#define cpudetect32        _cpudetect32
-#endif
-
-
-
-void match_init()
-{
-}
-
-unsigned long cpudetect32();
-
-uInt longest_match_c(
-    deflate_state *s,
-    IPos cur_match);                             /* current match */
-
-
-uInt longest_match_7fff(
-    deflate_state *s,
-    IPos cur_match);                             /* current match */
-
-uInt longest_match_686(
-    deflate_state *s,
-    IPos cur_match);                             /* current match */
-
-uInt longest_match(
-    deflate_state *s,
-    IPos cur_match)                             /* current match */
-{
-    static uInt iIsPPro=2;
-
-    if ((s->w_mask == 0x7fff) && (iIsPPro==0))
-        return longest_match_7fff(s,cur_match);
-
-    if (iIsPPro==1)
-        return longest_match_686(s,cur_match);
-
-    if (iIsPPro==2)
-        iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
-
-    return longest_match_c(s,cur_match);
-}
-
-
-
-uInt longest_match_c(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
-    unsigned chain_length = s->max_chain_length;/* max hash chain length */
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
-    register int len;                           /* length of current match */
-    int best_len = s->prev_length;              /* best match length so far */
-    int nice_match = s->nice_match;             /* stop if match long enough */
-    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-        s->strstart - (IPos)MAX_DIST(s) : NIL;
-    /* Stop when cur_match becomes <= limit. To simplify the code,
-     * we prevent matches with the string of window index 0.
-     */
-    Posf *prev = s->prev;
-    uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
-    /* Compare two bytes at a time. Note: this is not always beneficial.
-     * Try with and without -DUNALIGNED_OK to check.
-     */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-    register ush scan_start = *(ushf*)scan;
-    register ush scan_end   = *(ushf*)(scan+best_len-1);
-#else
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-    register Byte scan_end1  = scan[best_len-1];
-    register Byte scan_end   = scan[best_len];
-#endif
-
-    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-     * It is easy to get rid of this optimization if necessary.
-     */
-    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-    /* Do not waste too much time if we already have a good match: */
-    if (s->prev_length >= s->good_match) {
-        chain_length >>= 2;
-    }
-    /* Do not look for matches beyond the end of the input. This is necessary
-     * to make deflate deterministic.
-     */
-    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-    do {
-        Assert(cur_match < s->strstart, "no future");
-        match = s->window + cur_match;
-
-        /* Skip to next match if the match length cannot increase
-         * or if the match length is less than 2:
-         */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-        /* This code assumes sizeof(unsigned short) == 2. Do not use
-         * UNALIGNED_OK if your compiler uses a different size.
-         */
-        if (*(ushf*)(match+best_len-1) != scan_end ||
-            *(ushf*)match != scan_start) continue;
-
-        /* It is not necessary to compare scan[2] and match[2] since they are
-         * always equal when the other bytes match, given that the hash keys
-         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-         * strstart+3, +5, ... up to strstart+257. We check for insufficient
-         * lookahead only every 4th comparison; the 128th check will be made
-         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-         * necessary to put more guard bytes at the end of the window, or
-         * to check more often for insufficient lookahead.
-         */
-        Assert(scan[2] == match[2], "scan[2]?");
-        scan++, match++;
-        do {
-        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 scan < strend);
-        /* The funny "do {}" generates better code on most compilers */
-
-        /* Here, scan <= window+strstart+257 */
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-        if (*scan == *match) scan++;
-
-        len = (MAX_MATCH - 1) - (int)(strend-scan);
-        scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
-        if (match[best_len]   != scan_end  ||
-            match[best_len-1] != scan_end1 ||
-            *match            != *scan     ||
-            *++match          != scan[1])      continue;
-
-        /* The check at best_len-1 can be removed because it will be made
-         * again later. (This heuristic is not always a win.)
-         * It is not necessary to compare scan[2] and match[2] since they
-         * are always equal when the other bytes match, given that
-         * the hash keys are equal and that HASH_BITS >= 8.
-         */
-        scan += 2, match++;
-        Assert(*scan == *match, "match[2]?");
-
-        /* We check for insufficient lookahead only every 8th comparison;
-         * the 256th check will be made at strstart+258.
-         */
-        do {
-        } while (*++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 scan < strend);
-
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-        len = MAX_MATCH - (int)(strend - scan);
-        scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
-        if (len > best_len) {
-            s->match_start = cur_match;
-            best_len = len;
-            if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
-            scan_end = *(ushf*)(scan+best_len-1);
-#else
-            scan_end1  = scan[best_len-1];
-            scan_end   = scan[best_len];
-#endif
-        }
-    } while ((cur_match = prev[cur_match & wmask]) > limit
-             && --chain_length != 0);
-
-    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-    return s->lookahead;
-}
-
-#endif /* ASMV */
+/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86

+ * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.

+ * File written by Gilles Vollant, by modifiying the longest_match

+ *  from Jean-loup Gailly in deflate.c

+ *  it prepare all parameters and call the assembly longest_match_gvasm

+ *  longest_match execute standard C code is wmask != 0x7fff

+ *     (assembly code is faster with a fixed wmask)

+ *

+ * Read comment at beginning of gvmat32.asm for more information

+ */

+

+#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))

+#include "deflate.h"

+

+/* if your C compiler don't add underline before function name,

+        define ADD_UNDERLINE_ASMFUNC */

+#ifdef ADD_UNDERLINE_ASMFUNC

+#define longest_match_7fff _longest_match_7fff

+#define longest_match_686  _longest_match_686

+#define cpudetect32        _cpudetect32

+#endif

+

+

+unsigned long cpudetect32();

+

+uInt longest_match_c(

+    deflate_state *s,

+    IPos cur_match);                             /* current match */

+

+

+uInt longest_match_7fff(

+    deflate_state *s,

+    IPos cur_match);                             /* current match */

+

+uInt longest_match_686(

+    deflate_state *s,

+    IPos cur_match);                             /* current match */

+

+

+static uInt iIsPPro=2;

+

+void match_init ()

+{

+    iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;

+}

+

+uInt longest_match(

+    deflate_state *s,

+    IPos cur_match)                             /* current match */

+{

+    if (iIsPPro!=0)

+        return longest_match_686(s,cur_match);

+

+    if (s->w_mask != 0x7fff)

+        return longest_match_686(s,cur_match);

+

+    /* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */

+        return longest_match_7fff(s,cur_match);

+}

+

+

+#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */

diff --git a/contrib/masmx86/inffas32.asm b/contrib/masmx86/inffas32.asm
index 531bcef..4a20512 100644
--- a/contrib/masmx86/inffas32.asm
+++ b/contrib/masmx86/inffas32.asm
@@ -1,1036 +1,1083 @@
-; 75 "inffast.S"
-;FILE "inffast.S"
-
-;;;GLOBAL _inflate_fast
-
-;;;SECTION .text
-
-
-
-	.586p
-	.mmx
-
-	name	inflate_fast_x86
-	.MODEL	FLAT
-
-_DATA			segment
-inflate_fast_use_mmx:
-	dd	1
-
-
-_TEXT			segment
-PUBLIC _inflate_fast
-
-ALIGN 4
-_inflate_fast:
-	jmp inflate_fast_entry
-
-
-
-ALIGN 4
-	db	'Fast decoding Code from Chris Anderson'
-	db	0
-
-ALIGN 4
-invalid_literal_length_code_msg:
-	db	'invalid literal/length code'
-	db	0
-
-ALIGN 4
-invalid_distance_code_msg:
-	db	'invalid distance code'
-	db	0
-
-ALIGN 4
-invalid_distance_too_far_msg:
-	db	'invalid distance too far back'
-	db	0
-
-
-ALIGN 4
-inflate_fast_mask:
-dd	0
-dd	1
-dd	3
-dd	7
-dd	15
-dd	31
-dd	63
-dd	127
-dd	255
-dd	511
-dd	1023
-dd	2047
-dd	4095
-dd	8191
-dd	16383
-dd	32767
-dd	65535
-dd	131071
-dd	262143
-dd	524287
-dd	1048575
-dd	2097151
-dd	4194303
-dd	8388607
-dd	16777215
-dd	33554431
-dd	67108863
-dd	134217727
-dd	268435455
-dd	536870911
-dd	1073741823
-dd	2147483647
-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	*/
-wsize_state	 equ	32+addstr	;/* state->wsize */
-write_state	 equ	(36+4+addstr)	;/* state->write */
-window_state	 equ	(40+4+addstr)	;/* state->window */
-hold_state	 equ	(44+4+addstr)	;/* state->hold	*/
-bits_state	 equ	(48+4+addstr)	;/* state->bits	*/
-lencode_state	 equ	(64+4+addstr)	;/* state->lencode */
-distcode_state	 equ	(68+4+addstr)	;/* state->distcode */
-lenbits_state	 equ	(72+4+addstr)	;/* state->lenbits */
-distbits_state	 equ	(76+4+addstr)	;/* state->distbits */
-
-
-;;SECTION .text
-; 205 "inffast.S"
-;GLOBAL	inflate_fast_use_mmx
-
-;SECTION .data
-
-
-; GLOBAL inflate_fast_use_mmx:object
-;.size inflate_fast_use_mmx, 4
-; 226 "inffast.S"
-;SECTION .text
-
-ALIGN 4
-inflate_fast_entry:
-	push  edi
-	push  esi
-	push  ebp
-	push  ebx
-	pushfd
-	sub  esp,64
-	cld
-
-
-
-
-	mov  esi, [esp+88]
-	mov  edi, [esi+28]
-
-
-
-
-
-
-
-	mov  edx, [esi+4]
-	mov  eax, [esi+0]
-
-	add  edx,eax
-	sub  edx,11
-
-	mov  [esp+44],eax
-	mov  [esp+20],edx
-
-	mov  ebp, [esp+92]
-	mov  ecx, [esi+16]
-	mov  ebx, [esi+12]
-
-	sub  ebp,ecx
-	neg  ebp
-	add  ebp,ebx
-
-	sub  ecx,257
-	add  ecx,ebx
-
-	mov  [esp+60],ebx
-	mov  [esp+40],ebp
-	mov  [esp+16],ecx
-; 285 "inffast.S"
-	mov  eax, [edi+lencode_state]
-	mov  ecx, [edi+distcode_state]
-
-	mov  [esp+8],eax
-	mov  [esp+12],ecx
-
-	mov  eax,1
-	mov  ecx, [edi+lenbits_state]
-	shl  eax,cl
-	dec  eax
-	mov  [esp+0],eax
-
-	mov  eax,1
-	mov  ecx, [edi+distbits_state]
-	shl  eax,cl
-	dec  eax
-	mov  [esp+4],eax
-
-	mov  eax, [edi+wsize_state]
-	mov  ecx, [edi+write_state]
-	mov  edx, [edi+window_state]
-
-	mov  [esp+52],eax
-	mov  [esp+48],ecx
-	mov  [esp+56],edx
-
-	mov  ebp, [edi+hold_state]
-	mov  ebx, [edi+bits_state]
-; 321 "inffast.S"
-	mov  esi, [esp+44]
-	mov  ecx, [esp+20]
-	cmp  ecx,esi
-	ja   L_align_long
-
-	add  ecx,11
-	sub  ecx,esi
-	mov  eax,12
-	sub  eax,ecx
-	lea  edi, [esp+28]
-	rep movsb
-	mov  ecx,eax
-	xor  eax,eax
-	rep stosb
-	lea  esi, [esp+28]
-	mov  [esp+20],esi
-	jmp  L_is_aligned
-
-
-L_align_long:
-	test  esi,3
-	jz   L_is_aligned
-	xor  eax,eax
-	mov  al, [esi]
-	inc  esi
-	mov  ecx,ebx
-	add  ebx,8
-	shl  eax,cl
-	or  ebp,eax
-	jmp L_align_long
-
-L_is_aligned:
-	mov  edi, [esp+60]
-; 366 "inffast.S"
-L_check_mmx:
-	cmp  dword ptr [inflate_fast_use_mmx],2
-	je   L_init_mmx
-	ja   L_do_loop
-
-	push  eax
-	push  ebx
-	push  ecx
-	push  edx
-	pushfd
-	mov  eax, [esp]
-	xor  dword ptr [esp],0200000h
-
-
-
-
-	popfd
-	pushfd
-	pop  edx
-	xor  edx,eax
-	jz   L_dont_use_mmx
-	xor  eax,eax
-	cpuid
-	cmp  ebx,0756e6547h
-	jne  L_dont_use_mmx
-	cmp  ecx,06c65746eh
-	jne  L_dont_use_mmx
-	cmp  edx,049656e69h
-	jne  L_dont_use_mmx
-	mov  eax,1
-	cpuid
-	shr  eax,8
-	and  eax,15
-	cmp  eax,6
-	jne  L_dont_use_mmx
-	test  edx,0800000h
-	jnz  L_use_mmx
-	jmp  L_dont_use_mmx
-L_use_mmx:
-	mov  dword ptr [inflate_fast_use_mmx],2
-	jmp  L_check_mmx_pop
-L_dont_use_mmx:
-	mov  dword ptr [inflate_fast_use_mmx],3
-L_check_mmx_pop:
-	pop  edx
-	pop  ecx
-	pop  ebx
-	pop  eax
-	jmp  L_check_mmx
-; 426 "inffast.S"
-ALIGN 4
-L_do_loop:
-; 437 "inffast.S"
-	cmp  bl,15
-	ja   L_get_length_code
-
-	xor  eax,eax
-	lodsw
-	mov  cl,bl
-	add  bl,16
-	shl  eax,cl
-	or  ebp,eax
-
-L_get_length_code:
-	mov  edx, [esp+0]
-	mov  ecx, [esp+8]
-	and  edx,ebp
-	mov  eax, [ecx+edx*4]
-
-L_dolen:
-
-
-
-
-
-
-	mov  cl,ah
-	sub  bl,ah
-	shr  ebp,cl
-
-
-
-
-
-
-	test  al,al
-	jnz   L_test_for_length_base
-
-	shr  eax,16
-	stosb
-
-L_while_test:
-
-
-	cmp  [esp+16],edi
-	jbe  L_break_loop
-
-	cmp  [esp+20],esi
-	ja   L_do_loop
-	jmp  L_break_loop
-
-L_test_for_length_base:
-; 502 "inffast.S"
-	mov  edx,eax
-	shr  edx,16
-	mov  cl,al
-
-	test  al,16
-	jz   L_test_for_second_level_length
-	and  cl,15
-	jz   L_save_len
-	cmp  bl,cl
-	jae  L_add_bits_to_len
-
-	mov  ch,cl
-	xor  eax,eax
-	lodsw
-	mov  cl,bl
-	add  bl,16
-	shl  eax,cl
-	or  ebp,eax
-	mov  cl,ch
-
-L_add_bits_to_len:
-	mov  eax,1
-	shl  eax,cl
-	dec  eax
-	sub  bl,cl
-	and  eax,ebp
-	shr  ebp,cl
-	add  edx,eax
-
-L_save_len:
-	mov  [esp+24],edx
-
-
-L_decode_distance:
-; 549 "inffast.S"
-	cmp  bl,15
-	ja   L_get_distance_code
-
-	xor  eax,eax
-	lodsw
-	mov  cl,bl
-	add  bl,16
-	shl  eax,cl
-	or  ebp,eax
-
-L_get_distance_code:
-	mov  edx, [esp+4]
-	mov  ecx, [esp+12]
-	and  edx,ebp
-	mov  eax, [ecx+edx*4]
-
-
-L_dodist:
-	mov  edx,eax
-	shr  edx,16
-	mov  cl,ah
-	sub  bl,ah
-	shr  ebp,cl
-; 584 "inffast.S"
-	mov  cl,al
-
-	test  al,16
-	jz  L_test_for_second_level_dist
-	and  cl,15
-	jz  L_check_dist_one
-	cmp  bl,cl
-	jae  L_add_bits_to_dist
-
-	mov  ch,cl
-	xor  eax,eax
-	lodsw
-	mov  cl,bl
-	add  bl,16
-	shl  eax,cl
-	or  ebp,eax
-	mov  cl,ch
-
-L_add_bits_to_dist:
-	mov  eax,1
-	shl  eax,cl
-	dec  eax
-	sub  bl,cl
-	and  eax,ebp
-	shr  ebp,cl
-	add  edx,eax
-	jmp  L_check_window
-
-L_check_window:
-; 625 "inffast.S"
-	mov  [esp+44],esi
-	mov  eax,edi
-	sub  eax, [esp+40]
-
-	cmp  eax,edx
-	jb   L_clip_window
-
-	mov  ecx, [esp+24]
-	mov  esi,edi
-	sub  esi,edx
-
-	sub  ecx,3
-	mov  al, [esi]
-	mov  [edi],al
-	mov  al, [esi+1]
-	mov  dl, [esi+2]
-	add  esi,3
-	mov  [edi+1],al
-	mov  [edi+2],dl
-	add  edi,3
-	rep movsb
-
-	mov  esi, [esp+44]
-	jmp  L_while_test
-
-ALIGN 4
-L_check_dist_one:
-	cmp  edx,1
-	jne  L_check_window
-	cmp  [esp+40],edi
-	je  L_check_window
-
-	dec  edi
-	mov  ecx, [esp+24]
-	mov  al, [edi]
-	sub  ecx,3
-
-	mov  [edi+1],al
-	mov  [edi+2],al
-	mov  [edi+3],al
-	add  edi,4
-	rep stosb
-
-	jmp  L_while_test
-
-ALIGN 4
-L_test_for_second_level_length:
-
-
-
-
-	test  al,64
-	jnz   L_test_for_end_of_block
-
-	mov  eax,1
-	shl  eax,cl
-	dec  eax
-	and  eax,ebp
-	add  eax,edx
-	mov  edx, [esp+8]
-	mov  eax, [edx+eax*4]
-	jmp  L_dolen
-
-ALIGN 4
-L_test_for_second_level_dist:
-
-
-
-
-	test  al,64
-	jnz   L_invalid_distance_code
-
-	mov  eax,1
-	shl  eax,cl
-	dec  eax
-	and  eax,ebp
-	add  eax,edx
-	mov  edx, [esp+12]
-	mov  eax, [edx+eax*4]
-	jmp  L_dodist
-
-ALIGN 4
-L_clip_window:
-; 721 "inffast.S"
-	mov  ecx,eax
-	mov  eax, [esp+52]
-	neg  ecx
-	mov  esi, [esp+56]
-
-	cmp  eax,edx
-	jb   L_invalid_distance_too_far
-
-	add  ecx,edx
-	cmp  dword ptr [esp+48],0
-	jne  L_wrap_around_window
-
-	sub  eax,ecx
-	add  esi,eax
-; 749 "inffast.S"
-	mov  eax, [esp+24]
-	cmp  eax,ecx
-	jbe  L_do_copy1
-
-	sub  eax,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,edx
-	jmp  L_do_copy1
-
-	cmp  eax,ecx
-	jbe  L_do_copy1
-
-	sub  eax,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,edx
-	jmp  L_do_copy1
-
-L_wrap_around_window:
-; 793 "inffast.S"
-	mov  eax, [esp+48]
-	cmp  ecx,eax
-	jbe  L_contiguous_in_window
-
-	add  esi, [esp+52]
-	add  esi,eax
-	sub  esi,ecx
-	sub  ecx,eax
-
-
-	mov  eax, [esp+24]
-	cmp  eax,ecx
-	jbe  L_do_copy1
-
-	sub  eax,ecx
-	rep movsb
-	mov  esi, [esp+56]
-	mov  ecx, [esp+48]
-	cmp  eax,ecx
-	jbe  L_do_copy1
-
-	sub  eax,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,edx
-	jmp  L_do_copy1
-
-L_contiguous_in_window:
-; 836 "inffast.S"
-	add  esi,eax
-	sub  esi,ecx
-
-
-	mov  eax, [esp+24]
-	cmp  eax,ecx
-	jbe  L_do_copy1
-
-	sub  eax,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,edx
-
-L_do_copy1:
-; 862 "inffast.S"
-	mov  ecx,eax
-	rep movsb
-
-	mov  esi, [esp+44]
-	jmp  L_while_test
-; 878 "inffast.S"
-ALIGN 4
-L_init_mmx:
-	emms
-
-
-
-
-
-	movd mm0,ebp
-	mov  ebp,ebx
-; 896 "inffast.S"
-	movd mm4,[esp+0]
-	movq mm3,mm4
-	movd mm5,[esp+4]
-	movq mm2,mm5
-	pxor mm1,mm1
-	mov  ebx, [esp+8]
-	jmp  L_do_loop_mmx
-
-ALIGN 4
-L_do_loop_mmx:
-	psrlq mm0,mm1
-
-	cmp  ebp,32
-	ja  L_get_length_code_mmx
-
-	movd mm6,ebp
-	movd mm7,[esi]
-	add  esi,4
-	psllq mm7,mm6
-	add  ebp,32
-	por mm0,mm7
-
-L_get_length_code_mmx:
-	pand mm4,mm0
-	movd eax,mm4
-	movq mm4,mm3
-	mov  eax, [ebx+eax*4]
-
-L_dolen_mmx:
-	movzx  ecx,ah
-	movd mm1,ecx
-	sub  ebp,ecx
-
-	test  al,al
-	jnz L_test_for_length_base_mmx
-
-	shr  eax,16
-	stosb
-
-L_while_test_mmx:
-
-
-	cmp  [esp+16],edi
-	jbe L_break_loop
-
-	cmp  [esp+20],esi
-	ja L_do_loop_mmx
-	jmp L_break_loop
-
-L_test_for_length_base_mmx:
-
-	mov  edx,eax
-	shr  edx,16
-
-	test  al,16
-	jz  L_test_for_second_level_length_mmx
-	and  eax,15
-	jz L_decode_distance_mmx
-
-	psrlq mm0,mm1
-	movd mm1,eax
-	movd ecx,mm0
-	sub  ebp,eax
-	and  ecx, [inflate_fast_mask+eax*4]
-	add  edx,ecx
-
-L_decode_distance_mmx:
-	psrlq mm0,mm1
-
-	cmp  ebp,32
-	ja L_get_dist_code_mmx
-
-	movd mm6,ebp
-	movd mm7,[esi]
-	add  esi,4
-	psllq mm7,mm6
-	add  ebp,32
-	por mm0,mm7
-
-L_get_dist_code_mmx:
-	mov  ebx, [esp+12]
-	pand mm5,mm0
-	movd eax,mm5
-	movq mm5,mm2
-	mov  eax, [ebx+eax*4]
-
-L_dodist_mmx:
-
-	movzx  ecx,ah
-	mov  ebx,eax
-	shr  ebx,16
-	sub  ebp,ecx
-	movd mm1,ecx
-
-	test  al,16
-	jz L_test_for_second_level_dist_mmx
-	and  eax,15
-	jz L_check_dist_one_mmx
-
-L_add_bits_to_dist_mmx:
-	psrlq mm0,mm1
-	movd mm1,eax
-	movd ecx,mm0
-	sub  ebp,eax
-	and  ecx, [inflate_fast_mask+eax*4]
-	add  ebx,ecx
-
-L_check_window_mmx:
-	mov  [esp+44],esi
-	mov  eax,edi
-	sub  eax, [esp+40]
-
-	cmp  eax,ebx
-	jb L_clip_window_mmx
-
-	mov  ecx,edx
-	mov  esi,edi
-	sub  esi,ebx
-
-	sub  ecx,3
-	mov  al, [esi]
-	mov  [edi],al
-	mov  al, [esi+1]
-	mov  dl, [esi+2]
-	add  esi,3
-	mov  [edi+1],al
-	mov  [edi+2],dl
-	add  edi,3
-	rep movsb
-
-	mov  esi, [esp+44]
-	mov  ebx, [esp+8]
-	jmp  L_while_test_mmx
-
-ALIGN 4
-L_check_dist_one_mmx:
-	cmp  ebx,1
-	jne  L_check_window_mmx
-	cmp  [esp+40],edi
-	je   L_check_window_mmx
-
-	dec  edi
-	mov  ecx,edx
-	mov  al, [edi]
-	sub  ecx,3
-
-	mov  [edi+1],al
-	mov  [edi+2],al
-	mov  [edi+3],al
-	add  edi,4
-	rep stosb
-
-	mov  ebx, [esp+8]
-	jmp  L_while_test_mmx
-
-ALIGN 4
-L_test_for_second_level_length_mmx:
-	test  al,64
-	jnz L_test_for_end_of_block
-
-	and  eax,15
-	psrlq mm0,mm1
-	movd ecx,mm0
-	and  ecx, [inflate_fast_mask+eax*4]
-	add  ecx,edx
-	mov  eax, [ebx+ecx*4]
-	jmp L_dolen_mmx
-
-ALIGN 4
-L_test_for_second_level_dist_mmx:
-	test  al,64
-	jnz L_invalid_distance_code
-
-	and  eax,15
-	psrlq mm0,mm1
-	movd ecx,mm0
-	and  ecx, [inflate_fast_mask+eax*4]
-	mov  eax, [esp+12]
-	add  ecx,ebx
-	mov  eax, [eax+ecx*4]
-	jmp  L_dodist_mmx
-
-ALIGN 4
-L_clip_window_mmx:
-
-	mov  ecx,eax
-	mov  eax, [esp+52]
-	neg  ecx
-	mov  esi, [esp+56]
-
-	cmp  eax,ebx
-	jb  L_invalid_distance_too_far
-
-	add  ecx,ebx
-	cmp  dword ptr [esp+48],0
-	jne  L_wrap_around_window_mmx
-
-	sub  eax,ecx
-	add  esi,eax
-
-	cmp  edx,ecx
-	jbe  L_do_copy1_mmx
-
-	sub  edx,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,ebx
-	jmp  L_do_copy1_mmx
-
-	cmp  edx,ecx
-	jbe  L_do_copy1_mmx
-
-	sub  edx,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,ebx
-	jmp  L_do_copy1_mmx
-
-L_wrap_around_window_mmx:
-
-	mov  eax, [esp+48]
-	cmp  ecx,eax
-	jbe  L_contiguous_in_window_mmx
-
-	add  esi, [esp+52]
-	add  esi,eax
-	sub  esi,ecx
-	sub  ecx,eax
-
-
-	cmp  edx,ecx
-	jbe  L_do_copy1_mmx
-
-	sub  edx,ecx
-	rep movsb
-	mov  esi, [esp+56]
-	mov  ecx, [esp+48]
-	cmp  edx,ecx
-	jbe  L_do_copy1_mmx
-
-	sub  edx,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,ebx
-	jmp  L_do_copy1_mmx
-
-L_contiguous_in_window_mmx:
-
-	add  esi,eax
-	sub  esi,ecx
-
-
-	cmp  edx,ecx
-	jbe  L_do_copy1_mmx
-
-	sub  edx,ecx
-	rep movsb
-	mov  esi,edi
-	sub  esi,ebx
-
-L_do_copy1_mmx:
-
-
-	mov  ecx,edx
-	rep movsb
-
-	mov  esi, [esp+44]
-	mov  ebx, [esp+8]
-	jmp  L_while_test_mmx
-; 1174 "inffast.S"
-L_invalid_distance_code:
-
-
-
-
-
-	mov  ecx, invalid_distance_code_msg
-	mov  edx,26
-	jmp  L_update_stream_state
-
-L_test_for_end_of_block:
-
-
-
-
-
-	test  al,32
-	jz  L_invalid_literal_length_code
-
-	mov  ecx,0
-	mov  edx,11
-	jmp  L_update_stream_state
-
-L_invalid_literal_length_code:
-
-
-
-
-
-	mov  ecx, invalid_literal_length_code_msg
-	mov  edx,26
-	jmp  L_update_stream_state
-
-L_invalid_distance_too_far:
-
-
-
-	mov  esi, [esp+44]
-	mov  ecx, invalid_distance_too_far_msg
-	mov  edx,26
-	jmp  L_update_stream_state
-
-L_update_stream_state:
-
-	mov  eax, [esp+88]
-	test  ecx,ecx
-	jz  L_skip_msg
-	mov  [eax+24],ecx
-L_skip_msg:
-	mov  eax, [eax+28]
-	mov  [eax+mode_state],edx
-	jmp  L_break_loop
-
-ALIGN 4
-L_break_loop:
-; 1243 "inffast.S"
-	cmp  dword ptr [inflate_fast_use_mmx],2
-	jne  L_update_next_in
-
-
-
-	mov  ebx,ebp
-
-L_update_next_in:
-; 1266 "inffast.S"
-	mov  eax, [esp+88]
-	mov  ecx,ebx
-	mov  edx, [eax+28]
-	shr  ecx,3
-	sub  esi,ecx
-	shl  ecx,3
-	sub  ebx,ecx
-	mov  [eax+12],edi
-	mov  [edx+bits_state],ebx
-	mov  ecx,ebx
-
-	lea  ebx, [esp+28]
-	cmp  [esp+20],ebx
-	jne  L_buf_not_used
-
-	sub  esi,ebx
-	mov  ebx, [eax+0]
-	mov  [esp+20],ebx
-	add  esi,ebx
-	mov  ebx, [eax+4]
-	sub  ebx,11
-	add  [esp+20],ebx
-
-L_buf_not_used:
-	mov  [eax+0],esi
-
-	mov  ebx,1
-	shl  ebx,cl
-	dec  ebx
-
-
-
-
-
-	cmp  dword ptr [inflate_fast_use_mmx],2
-	jne  L_update_hold
-
-
-
-	psrlq mm0,mm1
-	movd ebp,mm0
-
-	emms
-
-L_update_hold:
-
-
-
-	and  ebp,ebx
-	mov  [edx+hold_state],ebp
-
-
-
-
-	mov  ebx, [esp+20]
-	cmp  ebx,esi
-	jbe  L_last_is_smaller
-
-	sub  ebx,esi
-	add  ebx,11
-	mov  [eax+4],ebx
-	jmp  L_fixup_out
-L_last_is_smaller:
-	sub  esi,ebx
-	neg  esi
-	add  esi,11
-	mov  [eax+4],esi
-
-
-
-
-L_fixup_out:
-
-	mov  ebx, [esp+16]
-	cmp  ebx,edi
-	jbe  L_end_is_smaller
-
-	sub  ebx,edi
-	add  ebx,257
-	mov  [eax+16],ebx
-	jmp  L_done
-L_end_is_smaller:
-	sub  edi,ebx
-	neg  edi
-	add  edi,257
-	mov  [eax+16],edi
-
-
-
-
-
-L_done:
-	add  esp,64
-	popfd
-	pop  ebx
-	pop  ebp
-	pop  esi
-	pop  edi
-	ret
-
-
-
-
-_TEXT	ends
-end
+;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding

+; *

+; * inffas32.asm is derivated from inffas86.c, with translation of assembly code

+; *

+; * Copyright (C) 1995-2003 Mark Adler

+; * For conditions of distribution and use, see copyright notice in zlib.h

+; *

+; * Copyright (C) 2003 Chris Anderson <christop@charm.net>

+; * Please use the copyright conditions above.

+; *

+; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from

+; * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at

+; * the moment.  I have successfully compiled and tested this code with gcc2.96,

+; * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S

+; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX

+; * enabled.  I will attempt to merge the MMX code into this version.  Newer

+; * versions of this and inffast.S can be found at

+; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/

+; * 

+; * 2005 : modification by Gilles Vollant

+; */

+; For Visual C++ 4.x and higher and ML 6.x and higher

+;   ml.exe is in directory \MASM611C of Win95 DDK

+;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm

+;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/

+;

+;

+;   compile with command line option

+;   ml  /coff /Zi /c /Flinffas32.lst inffas32.asm

+

+;   if you define NO_GZIP (see inflate.h), compile with

+;   ml  /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm

+

+

+; zlib122sup is 0 fort zlib 1.2.2.1 and lower

+; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head 

+;        in inflate_state in inflate.h)

+zlib1222sup      equ    8

+

+

+IFDEF GUNZIP

+  INFLATE_MODE_TYPE    equ 11

+  INFLATE_MODE_BAD     equ 26

+ELSE

+  IFNDEF NO_GUNZIP

+    INFLATE_MODE_TYPE    equ 11

+    INFLATE_MODE_BAD     equ 26

+  ELSE

+    INFLATE_MODE_TYPE    equ 3

+    INFLATE_MODE_BAD     equ 17

+  ENDIF

+ENDIF

+

+

+; 75 "inffast.S"

+;FILE "inffast.S"

+

+;;;GLOBAL _inflate_fast

+

+;;;SECTION .text

+

+

+

+	.586p

+	.mmx

+

+	name	inflate_fast_x86

+	.MODEL	FLAT

+

+_DATA			segment

+inflate_fast_use_mmx:

+	dd	1

+

+

+_TEXT			segment

+PUBLIC _inflate_fast

+

+ALIGN 4

+_inflate_fast:

+	jmp inflate_fast_entry

+

+

+

+ALIGN 4

+	db	'Fast decoding Code from Chris Anderson'

+	db	0

+

+ALIGN 4

+invalid_literal_length_code_msg:

+	db	'invalid literal/length code'

+	db	0

+

+ALIGN 4

+invalid_distance_code_msg:

+	db	'invalid distance code'

+	db	0

+

+ALIGN 4

+invalid_distance_too_far_msg:

+	db	'invalid distance too far back'

+	db	0

+

+

+ALIGN 4

+inflate_fast_mask:

+dd	0

+dd	1

+dd	3

+dd	7

+dd	15

+dd	31

+dd	63

+dd	127

+dd	255

+dd	511

+dd	1023

+dd	2047

+dd	4095

+dd	8191

+dd	16383

+dd	32767

+dd	65535

+dd	131071

+dd	262143

+dd	524287

+dd	1048575

+dd	2097151

+dd	4194303

+dd	8388607

+dd	16777215

+dd	33554431

+dd	67108863

+dd	134217727

+dd	268435455

+dd	536870911

+dd	1073741823

+dd	2147483647

+dd	4294967295

+

+

+mode_state	 equ	0	;/* state->mode	*/

+wsize_state	 equ	(32+zlib1222sup)	;/* state->wsize */

+write_state	 equ	(36+4+zlib1222sup)	;/* state->write */

+window_state	 equ	(40+4+zlib1222sup)	;/* state->window */

+hold_state	 equ	(44+4+zlib1222sup)	;/* state->hold	*/

+bits_state	 equ	(48+4+zlib1222sup)	;/* state->bits	*/

+lencode_state	 equ	(64+4+zlib1222sup)	;/* state->lencode */

+distcode_state	 equ	(68+4+zlib1222sup)	;/* state->distcode */

+lenbits_state	 equ	(72+4+zlib1222sup)	;/* state->lenbits */

+distbits_state	 equ	(76+4+zlib1222sup)	;/* state->distbits */

+

+

+;;SECTION .text

+; 205 "inffast.S"

+;GLOBAL	inflate_fast_use_mmx

+

+;SECTION .data

+

+

+; GLOBAL inflate_fast_use_mmx:object

+;.size inflate_fast_use_mmx, 4

+; 226 "inffast.S"

+;SECTION .text

+

+ALIGN 4

+inflate_fast_entry:

+	push  edi

+	push  esi

+	push  ebp

+	push  ebx

+	pushfd

+	sub  esp,64

+	cld

+

+

+

+

+	mov  esi, [esp+88]

+	mov  edi, [esi+28]

+

+

+

+

+

+

+

+	mov  edx, [esi+4]

+	mov  eax, [esi+0]

+

+	add  edx,eax

+	sub  edx,11

+

+	mov  [esp+44],eax

+	mov  [esp+20],edx

+

+	mov  ebp, [esp+92]

+	mov  ecx, [esi+16]

+	mov  ebx, [esi+12]

+

+	sub  ebp,ecx

+	neg  ebp

+	add  ebp,ebx

+

+	sub  ecx,257

+	add  ecx,ebx

+

+	mov  [esp+60],ebx

+	mov  [esp+40],ebp

+	mov  [esp+16],ecx

+; 285 "inffast.S"

+	mov  eax, [edi+lencode_state]

+	mov  ecx, [edi+distcode_state]

+

+	mov  [esp+8],eax

+	mov  [esp+12],ecx

+

+	mov  eax,1

+	mov  ecx, [edi+lenbits_state]

+	shl  eax,cl

+	dec  eax

+	mov  [esp+0],eax

+

+	mov  eax,1

+	mov  ecx, [edi+distbits_state]

+	shl  eax,cl

+	dec  eax

+	mov  [esp+4],eax

+

+	mov  eax, [edi+wsize_state]

+	mov  ecx, [edi+write_state]

+	mov  edx, [edi+window_state]

+

+	mov  [esp+52],eax

+	mov  [esp+48],ecx

+	mov  [esp+56],edx

+

+	mov  ebp, [edi+hold_state]

+	mov  ebx, [edi+bits_state]

+; 321 "inffast.S"

+	mov  esi, [esp+44]

+	mov  ecx, [esp+20]

+	cmp  ecx,esi

+	ja   L_align_long

+

+	add  ecx,11

+	sub  ecx,esi

+	mov  eax,12

+	sub  eax,ecx

+	lea  edi, [esp+28]

+	rep movsb

+	mov  ecx,eax

+	xor  eax,eax

+	rep stosb

+	lea  esi, [esp+28]

+	mov  [esp+20],esi

+	jmp  L_is_aligned

+

+

+L_align_long:

+	test  esi,3

+	jz   L_is_aligned

+	xor  eax,eax

+	mov  al, [esi]

+	inc  esi

+	mov  ecx,ebx

+	add  ebx,8

+	shl  eax,cl

+	or  ebp,eax

+	jmp L_align_long

+

+L_is_aligned:

+	mov  edi, [esp+60]

+; 366 "inffast.S"

+L_check_mmx:

+	cmp  dword ptr [inflate_fast_use_mmx],2

+	je   L_init_mmx

+	ja   L_do_loop

+

+	push  eax

+	push  ebx

+	push  ecx

+	push  edx

+	pushfd

+	mov  eax, [esp]

+	xor  dword ptr [esp],0200000h

+

+

+

+

+	popfd

+	pushfd

+	pop  edx

+	xor  edx,eax

+	jz   L_dont_use_mmx

+	xor  eax,eax

+	cpuid

+	cmp  ebx,0756e6547h

+	jne  L_dont_use_mmx

+	cmp  ecx,06c65746eh

+	jne  L_dont_use_mmx

+	cmp  edx,049656e69h

+	jne  L_dont_use_mmx

+	mov  eax,1

+	cpuid

+	shr  eax,8

+	and  eax,15

+	cmp  eax,6

+	jne  L_dont_use_mmx

+	test  edx,0800000h

+	jnz  L_use_mmx

+	jmp  L_dont_use_mmx

+L_use_mmx:

+	mov  dword ptr [inflate_fast_use_mmx],2

+	jmp  L_check_mmx_pop

+L_dont_use_mmx:

+	mov  dword ptr [inflate_fast_use_mmx],3

+L_check_mmx_pop:

+	pop  edx

+	pop  ecx

+	pop  ebx

+	pop  eax

+	jmp  L_check_mmx

+; 426 "inffast.S"

+ALIGN 4

+L_do_loop:

+; 437 "inffast.S"

+	cmp  bl,15

+	ja   L_get_length_code

+

+	xor  eax,eax

+	lodsw

+	mov  cl,bl

+	add  bl,16

+	shl  eax,cl

+	or  ebp,eax

+

+L_get_length_code:

+	mov  edx, [esp+0]

+	mov  ecx, [esp+8]

+	and  edx,ebp

+	mov  eax, [ecx+edx*4]

+

+L_dolen:

+

+

+

+

+

+

+	mov  cl,ah

+	sub  bl,ah

+	shr  ebp,cl

+

+

+

+

+

+

+	test  al,al

+	jnz   L_test_for_length_base

+

+	shr  eax,16

+	stosb

+

+L_while_test:

+

+

+	cmp  [esp+16],edi

+	jbe  L_break_loop

+

+	cmp  [esp+20],esi

+	ja   L_do_loop

+	jmp  L_break_loop

+

+L_test_for_length_base:

+; 502 "inffast.S"

+	mov  edx,eax

+	shr  edx,16

+	mov  cl,al

+

+	test  al,16

+	jz   L_test_for_second_level_length

+	and  cl,15

+	jz   L_save_len

+	cmp  bl,cl

+	jae  L_add_bits_to_len

+

+	mov  ch,cl

+	xor  eax,eax

+	lodsw

+	mov  cl,bl

+	add  bl,16

+	shl  eax,cl

+	or  ebp,eax

+	mov  cl,ch

+

+L_add_bits_to_len:

+	mov  eax,1

+	shl  eax,cl

+	dec  eax

+	sub  bl,cl

+	and  eax,ebp

+	shr  ebp,cl

+	add  edx,eax

+

+L_save_len:

+	mov  [esp+24],edx

+

+

+L_decode_distance:

+; 549 "inffast.S"

+	cmp  bl,15

+	ja   L_get_distance_code

+

+	xor  eax,eax

+	lodsw

+	mov  cl,bl

+	add  bl,16

+	shl  eax,cl

+	or  ebp,eax

+

+L_get_distance_code:

+	mov  edx, [esp+4]

+	mov  ecx, [esp+12]

+	and  edx,ebp

+	mov  eax, [ecx+edx*4]

+

+

+L_dodist:

+	mov  edx,eax

+	shr  edx,16

+	mov  cl,ah

+	sub  bl,ah

+	shr  ebp,cl

+; 584 "inffast.S"

+	mov  cl,al

+

+	test  al,16

+	jz  L_test_for_second_level_dist

+	and  cl,15

+	jz  L_check_dist_one

+	cmp  bl,cl

+	jae  L_add_bits_to_dist

+

+	mov  ch,cl

+	xor  eax,eax

+	lodsw

+	mov  cl,bl

+	add  bl,16

+	shl  eax,cl

+	or  ebp,eax

+	mov  cl,ch

+

+L_add_bits_to_dist:

+	mov  eax,1

+	shl  eax,cl

+	dec  eax

+	sub  bl,cl

+	and  eax,ebp

+	shr  ebp,cl

+	add  edx,eax

+	jmp  L_check_window

+

+L_check_window:

+; 625 "inffast.S"

+	mov  [esp+44],esi

+	mov  eax,edi

+	sub  eax, [esp+40]

+

+	cmp  eax,edx

+	jb   L_clip_window

+

+	mov  ecx, [esp+24]

+	mov  esi,edi

+	sub  esi,edx

+

+	sub  ecx,3

+	mov  al, [esi]

+	mov  [edi],al

+	mov  al, [esi+1]

+	mov  dl, [esi+2]

+	add  esi,3

+	mov  [edi+1],al

+	mov  [edi+2],dl

+	add  edi,3

+	rep movsb

+

+	mov  esi, [esp+44]

+	jmp  L_while_test

+

+ALIGN 4

+L_check_dist_one:

+	cmp  edx,1

+	jne  L_check_window

+	cmp  [esp+40],edi

+	je  L_check_window

+

+	dec  edi

+	mov  ecx, [esp+24]

+	mov  al, [edi]

+	sub  ecx,3

+

+	mov  [edi+1],al

+	mov  [edi+2],al

+	mov  [edi+3],al

+	add  edi,4

+	rep stosb

+

+	jmp  L_while_test

+

+ALIGN 4

+L_test_for_second_level_length:

+

+

+

+

+	test  al,64

+	jnz   L_test_for_end_of_block

+

+	mov  eax,1

+	shl  eax,cl

+	dec  eax

+	and  eax,ebp

+	add  eax,edx

+	mov  edx, [esp+8]

+	mov  eax, [edx+eax*4]

+	jmp  L_dolen

+

+ALIGN 4

+L_test_for_second_level_dist:

+

+

+

+

+	test  al,64

+	jnz   L_invalid_distance_code

+

+	mov  eax,1

+	shl  eax,cl

+	dec  eax

+	and  eax,ebp

+	add  eax,edx

+	mov  edx, [esp+12]

+	mov  eax, [edx+eax*4]

+	jmp  L_dodist

+

+ALIGN 4

+L_clip_window:

+; 721 "inffast.S"

+	mov  ecx,eax

+	mov  eax, [esp+52]

+	neg  ecx

+	mov  esi, [esp+56]

+

+	cmp  eax,edx

+	jb   L_invalid_distance_too_far

+

+	add  ecx,edx

+	cmp  dword ptr [esp+48],0

+	jne  L_wrap_around_window

+

+	sub  eax,ecx

+	add  esi,eax

+; 749 "inffast.S"

+	mov  eax, [esp+24]

+	cmp  eax,ecx

+	jbe  L_do_copy1

+

+	sub  eax,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,edx

+	jmp  L_do_copy1

+

+	cmp  eax,ecx

+	jbe  L_do_copy1

+

+	sub  eax,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,edx

+	jmp  L_do_copy1

+

+L_wrap_around_window:

+; 793 "inffast.S"

+	mov  eax, [esp+48]

+	cmp  ecx,eax

+	jbe  L_contiguous_in_window

+

+	add  esi, [esp+52]

+	add  esi,eax

+	sub  esi,ecx

+	sub  ecx,eax

+

+

+	mov  eax, [esp+24]

+	cmp  eax,ecx

+	jbe  L_do_copy1

+

+	sub  eax,ecx

+	rep movsb

+	mov  esi, [esp+56]

+	mov  ecx, [esp+48]

+	cmp  eax,ecx

+	jbe  L_do_copy1

+

+	sub  eax,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,edx

+	jmp  L_do_copy1

+

+L_contiguous_in_window:

+; 836 "inffast.S"

+	add  esi,eax

+	sub  esi,ecx

+

+

+	mov  eax, [esp+24]

+	cmp  eax,ecx

+	jbe  L_do_copy1

+

+	sub  eax,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,edx

+

+L_do_copy1:

+; 862 "inffast.S"

+	mov  ecx,eax

+	rep movsb

+

+	mov  esi, [esp+44]

+	jmp  L_while_test

+; 878 "inffast.S"

+ALIGN 4

+L_init_mmx:

+	emms

+

+

+

+

+

+	movd mm0,ebp

+	mov  ebp,ebx

+; 896 "inffast.S"

+	movd mm4,[esp+0]

+	movq mm3,mm4

+	movd mm5,[esp+4]

+	movq mm2,mm5

+	pxor mm1,mm1

+	mov  ebx, [esp+8]

+	jmp  L_do_loop_mmx

+

+ALIGN 4

+L_do_loop_mmx:

+	psrlq mm0,mm1

+

+	cmp  ebp,32

+	ja  L_get_length_code_mmx

+

+	movd mm6,ebp

+	movd mm7,[esi]

+	add  esi,4

+	psllq mm7,mm6

+	add  ebp,32

+	por mm0,mm7

+

+L_get_length_code_mmx:

+	pand mm4,mm0

+	movd eax,mm4

+	movq mm4,mm3

+	mov  eax, [ebx+eax*4]

+

+L_dolen_mmx:

+	movzx  ecx,ah

+	movd mm1,ecx

+	sub  ebp,ecx

+

+	test  al,al

+	jnz L_test_for_length_base_mmx

+

+	shr  eax,16

+	stosb

+

+L_while_test_mmx:

+

+

+	cmp  [esp+16],edi

+	jbe L_break_loop

+

+	cmp  [esp+20],esi

+	ja L_do_loop_mmx

+	jmp L_break_loop

+

+L_test_for_length_base_mmx:

+

+	mov  edx,eax

+	shr  edx,16

+

+	test  al,16

+	jz  L_test_for_second_level_length_mmx

+	and  eax,15

+	jz L_decode_distance_mmx

+

+	psrlq mm0,mm1

+	movd mm1,eax

+	movd ecx,mm0

+	sub  ebp,eax

+	and  ecx, [inflate_fast_mask+eax*4]

+	add  edx,ecx

+

+L_decode_distance_mmx:

+	psrlq mm0,mm1

+

+	cmp  ebp,32

+	ja L_get_dist_code_mmx

+

+	movd mm6,ebp

+	movd mm7,[esi]

+	add  esi,4

+	psllq mm7,mm6

+	add  ebp,32

+	por mm0,mm7

+

+L_get_dist_code_mmx:

+	mov  ebx, [esp+12]

+	pand mm5,mm0

+	movd eax,mm5

+	movq mm5,mm2

+	mov  eax, [ebx+eax*4]

+

+L_dodist_mmx:

+

+	movzx  ecx,ah

+	mov  ebx,eax

+	shr  ebx,16

+	sub  ebp,ecx

+	movd mm1,ecx

+

+	test  al,16

+	jz L_test_for_second_level_dist_mmx

+	and  eax,15

+	jz L_check_dist_one_mmx

+

+L_add_bits_to_dist_mmx:

+	psrlq mm0,mm1

+	movd mm1,eax

+	movd ecx,mm0

+	sub  ebp,eax

+	and  ecx, [inflate_fast_mask+eax*4]

+	add  ebx,ecx

+

+L_check_window_mmx:

+	mov  [esp+44],esi

+	mov  eax,edi

+	sub  eax, [esp+40]

+

+	cmp  eax,ebx

+	jb L_clip_window_mmx

+

+	mov  ecx,edx

+	mov  esi,edi

+	sub  esi,ebx

+

+	sub  ecx,3

+	mov  al, [esi]

+	mov  [edi],al

+	mov  al, [esi+1]

+	mov  dl, [esi+2]

+	add  esi,3

+	mov  [edi+1],al

+	mov  [edi+2],dl

+	add  edi,3

+	rep movsb

+

+	mov  esi, [esp+44]

+	mov  ebx, [esp+8]

+	jmp  L_while_test_mmx

+

+ALIGN 4

+L_check_dist_one_mmx:

+	cmp  ebx,1

+	jne  L_check_window_mmx

+	cmp  [esp+40],edi

+	je   L_check_window_mmx

+

+	dec  edi

+	mov  ecx,edx

+	mov  al, [edi]

+	sub  ecx,3

+

+	mov  [edi+1],al

+	mov  [edi+2],al

+	mov  [edi+3],al

+	add  edi,4

+	rep stosb

+

+	mov  ebx, [esp+8]

+	jmp  L_while_test_mmx

+

+ALIGN 4

+L_test_for_second_level_length_mmx:

+	test  al,64

+	jnz L_test_for_end_of_block

+

+	and  eax,15

+	psrlq mm0,mm1

+	movd ecx,mm0

+	and  ecx, [inflate_fast_mask+eax*4]

+	add  ecx,edx

+	mov  eax, [ebx+ecx*4]

+	jmp L_dolen_mmx

+

+ALIGN 4

+L_test_for_second_level_dist_mmx:

+	test  al,64

+	jnz L_invalid_distance_code

+

+	and  eax,15

+	psrlq mm0,mm1

+	movd ecx,mm0

+	and  ecx, [inflate_fast_mask+eax*4]

+	mov  eax, [esp+12]

+	add  ecx,ebx

+	mov  eax, [eax+ecx*4]

+	jmp  L_dodist_mmx

+

+ALIGN 4

+L_clip_window_mmx:

+

+	mov  ecx,eax

+	mov  eax, [esp+52]

+	neg  ecx

+	mov  esi, [esp+56]

+

+	cmp  eax,ebx

+	jb  L_invalid_distance_too_far

+

+	add  ecx,ebx

+	cmp  dword ptr [esp+48],0

+	jne  L_wrap_around_window_mmx

+

+	sub  eax,ecx

+	add  esi,eax

+

+	cmp  edx,ecx

+	jbe  L_do_copy1_mmx

+

+	sub  edx,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,ebx

+	jmp  L_do_copy1_mmx

+

+	cmp  edx,ecx

+	jbe  L_do_copy1_mmx

+

+	sub  edx,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,ebx

+	jmp  L_do_copy1_mmx

+

+L_wrap_around_window_mmx:

+

+	mov  eax, [esp+48]

+	cmp  ecx,eax

+	jbe  L_contiguous_in_window_mmx

+

+	add  esi, [esp+52]

+	add  esi,eax

+	sub  esi,ecx

+	sub  ecx,eax

+

+

+	cmp  edx,ecx

+	jbe  L_do_copy1_mmx

+

+	sub  edx,ecx

+	rep movsb

+	mov  esi, [esp+56]

+	mov  ecx, [esp+48]

+	cmp  edx,ecx

+	jbe  L_do_copy1_mmx

+

+	sub  edx,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,ebx

+	jmp  L_do_copy1_mmx

+

+L_contiguous_in_window_mmx:

+

+	add  esi,eax

+	sub  esi,ecx

+

+

+	cmp  edx,ecx

+	jbe  L_do_copy1_mmx

+

+	sub  edx,ecx

+	rep movsb

+	mov  esi,edi

+	sub  esi,ebx

+

+L_do_copy1_mmx:

+

+

+	mov  ecx,edx

+	rep movsb

+

+	mov  esi, [esp+44]

+	mov  ebx, [esp+8]

+	jmp  L_while_test_mmx

+; 1174 "inffast.S"

+L_invalid_distance_code:

+

+

+

+

+

+	mov  ecx, invalid_distance_code_msg

+	mov  edx,INFLATE_MODE_BAD

+	jmp  L_update_stream_state

+

+L_test_for_end_of_block:

+

+

+

+

+

+	test  al,32

+	jz  L_invalid_literal_length_code

+

+	mov  ecx,0

+	mov  edx,INFLATE_MODE_TYPE

+	jmp  L_update_stream_state

+

+L_invalid_literal_length_code:

+

+

+

+

+

+	mov  ecx, invalid_literal_length_code_msg

+	mov  edx,INFLATE_MODE_BAD

+	jmp  L_update_stream_state

+

+L_invalid_distance_too_far:

+

+

+

+	mov  esi, [esp+44]

+	mov  ecx, invalid_distance_too_far_msg

+	mov  edx,INFLATE_MODE_BAD

+	jmp  L_update_stream_state

+

+L_update_stream_state:

+

+	mov  eax, [esp+88]

+	test  ecx,ecx

+	jz  L_skip_msg

+	mov  [eax+24],ecx

+L_skip_msg:

+	mov  eax, [eax+28]

+	mov  [eax+mode_state],edx

+	jmp  L_break_loop

+

+ALIGN 4

+L_break_loop:

+; 1243 "inffast.S"

+	cmp  dword ptr [inflate_fast_use_mmx],2

+	jne  L_update_next_in

+

+

+

+	mov  ebx,ebp

+

+L_update_next_in:

+; 1266 "inffast.S"

+	mov  eax, [esp+88]

+	mov  ecx,ebx

+	mov  edx, [eax+28]

+	shr  ecx,3

+	sub  esi,ecx

+	shl  ecx,3

+	sub  ebx,ecx

+	mov  [eax+12],edi

+	mov  [edx+bits_state],ebx

+	mov  ecx,ebx

+

+	lea  ebx, [esp+28]

+	cmp  [esp+20],ebx

+	jne  L_buf_not_used

+

+	sub  esi,ebx

+	mov  ebx, [eax+0]

+	mov  [esp+20],ebx

+	add  esi,ebx

+	mov  ebx, [eax+4]

+	sub  ebx,11

+	add  [esp+20],ebx

+

+L_buf_not_used:

+	mov  [eax+0],esi

+

+	mov  ebx,1

+	shl  ebx,cl

+	dec  ebx

+

+

+

+

+

+	cmp  dword ptr [inflate_fast_use_mmx],2

+	jne  L_update_hold

+

+

+

+	psrlq mm0,mm1

+	movd ebp,mm0

+

+	emms

+

+L_update_hold:

+

+

+

+	and  ebp,ebx

+	mov  [edx+hold_state],ebp

+

+

+

+

+	mov  ebx, [esp+20]

+	cmp  ebx,esi

+	jbe  L_last_is_smaller

+

+	sub  ebx,esi

+	add  ebx,11

+	mov  [eax+4],ebx

+	jmp  L_fixup_out

+L_last_is_smaller:

+	sub  esi,ebx

+	neg  esi

+	add  esi,11

+	mov  [eax+4],esi

+

+

+

+

+L_fixup_out:

+

+	mov  ebx, [esp+16]

+	cmp  ebx,edi

+	jbe  L_end_is_smaller

+

+	sub  ebx,edi

+	add  ebx,257

+	mov  [eax+16],ebx

+	jmp  L_done

+L_end_is_smaller:

+	sub  edi,ebx

+	neg  edi

+	add  edi,257

+	mov  [eax+16],edi

+

+

+

+

+

+L_done:

+	add  esp,64

+	popfd

+	pop  ebx

+	pop  ebp

+	pop  esi

+	pop  edi

+	ret

+

+_TEXT	ends

+end

diff --git a/contrib/minizip/ChangeLogUnzip b/contrib/minizip/ChangeLogUnzip
index 4be4d16..e62af14 100644
--- a/contrib/minizip/ChangeLogUnzip
+++ b/contrib/minizip/ChangeLogUnzip
@@ -1,63 +1,67 @@
-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)
-- rename to 1.00
-- cosmetic code change
-
-Change in 0.22: (19 May 03)
-- crypting support (unless you define NOCRYPT)
-- append file in existing zipfile
-
-Change in 0.21: (10 Mar 03)
-- bug fixes
-
-Change in 0.17: (27 Jan 02)
-- bug fixes
-
-Change in 0.16: (19 Jan 02)
-- Support of ioapi for virtualize zip file access
-
-Change in 0.15: (19 Mar 98)
-- fix memory leak in minizip.c
-
-Change in 0.14: (10 Mar 98)
-- fix bugs in minizip.c sample for zipping big file
-- fix problem in month in date handling
-- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for
-    comment handling
-
-Change in 0.13: (6 Mar 98)
-- fix bugs in zip.c
-- add real minizip sample
-
-Change in 0.12: (4 Mar 98)
-- add zip.c and zip.h for creates .zip file
-- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)
-- fix miniunz.c for file without specific record for directory
-
-Change in 0.11: (3 Mar 98)
-- fix bug in unzGetCurrentFileInfo for get extra field and comment
-- enhance miniunz sample, remove the bad unztst.c sample
-
-Change in 0.10: (2 Mar 98)
-- fix bug in unzReadCurrentFile
-- rename unzip* to unz* function and structure
-- remove Windows-like hungary notation variable name
-- modify some structure in unzip.h
-- add somes comment in source
-- remove unzipGetcCurrentFile function
-- replace ZUNZEXPORT by ZEXPORT
-- add unzGetLocalExtrafield for get the local extrafield info
-- add a new sample, miniunz.c
-
-Change in 0.4: (25 Feb 98)
-- suppress the type unzipFileInZip.
-  Only on file in the zipfile can be open at the same time
-- fix somes typo in code
-- added tm_unz structure in unzip_file_info (date/time in readable format)
+Change in 1.01e (12 feb 05)

+- Fix in zipOpen2 for globalcomment (Rolf Kalbermatter)

+- Fix possible memory leak in unzip.c (Zoran Stevanovic)

+

+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)

+- rename to 1.00

+- cosmetic code change

+

+Change in 0.22: (19 May 03)

+- crypting support (unless you define NOCRYPT)

+- append file in existing zipfile

+

+Change in 0.21: (10 Mar 03)

+- bug fixes

+

+Change in 0.17: (27 Jan 02)

+- bug fixes

+

+Change in 0.16: (19 Jan 02)

+- Support of ioapi for virtualize zip file access

+

+Change in 0.15: (19 Mar 98)

+- fix memory leak in minizip.c

+

+Change in 0.14: (10 Mar 98)

+- fix bugs in minizip.c sample for zipping big file

+- fix problem in month in date handling

+- fix bug in unzlocal_GetCurrentFileInfoInternal in unzip.c for

+    comment handling

+

+Change in 0.13: (6 Mar 98)

+- fix bugs in zip.c

+- add real minizip sample

+

+Change in 0.12: (4 Mar 98)

+- add zip.c and zip.h for creates .zip file

+- fix change_file_date in miniunz.c for Unix (Jean-loup Gailly)

+- fix miniunz.c for file without specific record for directory

+

+Change in 0.11: (3 Mar 98)

+- fix bug in unzGetCurrentFileInfo for get extra field and comment

+- enhance miniunz sample, remove the bad unztst.c sample

+

+Change in 0.10: (2 Mar 98)

+- fix bug in unzReadCurrentFile

+- rename unzip* to unz* function and structure

+- remove Windows-like hungary notation variable name

+- modify some structure in unzip.h

+- add somes comment in source

+- remove unzipGetcCurrentFile function

+- replace ZUNZEXPORT by ZEXPORT

+- add unzGetLocalExtrafield for get the local extrafield info

+- add a new sample, miniunz.c

+

+Change in 0.4: (25 Feb 98)

+- suppress the type unzipFileInZip.

+  Only on file in the zipfile can be open at the same time

+- fix somes typo in code

+- added tm_unz structure in unzip_file_info (date/time in readable format)

diff --git a/contrib/minizip/Makefile b/contrib/minizip/Makefile
index 84eaad2..fbba3ac 100644
--- a/contrib/minizip/Makefile
+++ b/contrib/minizip/Makefile
@@ -1,25 +1,25 @@
-CC=cc
-CFLAGS=-O -I../..
-
-UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
-ZIP_OBJS = minizip.o zip.o   ioapi.o ../../libz.a
-
-.c.o:
-	$(CC) -c $(CFLAGS) $*.c
-
-all: miniunz minizip
-
-miniunz:  $(UNZ_OBJS)
-	$(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
-
-minizip:  $(ZIP_OBJS)
-	$(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
-
-test:	miniunz minizip
-	./minizip test readme.txt
-	./miniunz -l test.zip
-	mv readme.txt readme.old
-	./miniunz test.zip
-
-clean:
-	/bin/rm -f *.o *~ minizip miniunz
+CC=cc

+CFLAGS=-O -I../..

+

+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a

+ZIP_OBJS = minizip.o zip.o   ioapi.o ../../libz.a

+

+.c.o:

+	$(CC) -c $(CFLAGS) $*.c

+

+all: miniunz minizip

+

+miniunz:  $(UNZ_OBJS)

+	$(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)

+

+minizip:  $(ZIP_OBJS)

+	$(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)

+

+test:	miniunz minizip

+	./minizip test readme.txt

+	./miniunz -l test.zip

+	mv readme.txt readme.old

+	./miniunz test.zip

+

+clean:

+	/bin/rm -f *.o *~ minizip miniunz

diff --git a/contrib/minizip/crypt.h b/contrib/minizip/crypt.h
index 7f8a634..f14a628 100644
--- a/contrib/minizip/crypt.h
+++ b/contrib/minizip/crypt.h
@@ -1,132 +1,132 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-
-   This code is a modified version of crypting code in Infozip distribution
-
-   The encryption/decryption parts of this source code (as opposed to the
-   non-echoing password parts) were originally written in Europe.  The
-   whole source package can be freely distributed, including from the USA.
-   (Prior to January 2000, re-export from the US was a violation of US law.)
-
-   This encryption code is a direct transcription of the algorithm from
-   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-   file (appnote.txt) is distributed with the PKZIP program (even in the
-   version without encryption capabilities).
-
-   If you don't need crypting in your application, just define symbols
-   NOCRYPT and NOUNCRYPT.
-
-   This code support the "Traditional PKWARE Encryption".
-
-   The new AES encryption added on Zip format by Winzip (see the page
-   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
-   Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
-{
-    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
-                     * unpredictable manner on 16-bit systems; not a problem
-                     * with any known compiler so far, though */
-
-    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
-    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
-    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
-    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
-    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
-    {
-      register int keyshift = (int)((*(pkeys+1)) >> 24);
-      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
-    }
-    return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
-    *(pkeys+0) = 305419896L;
-    *(pkeys+1) = 591751049L;
-    *(pkeys+2) = 878082192L;
-    while (*passwd != '\0') {
-        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
-        passwd++;
-    }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
-    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
-    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN  12
-   /* "last resort" source for second part of crypt seed pattern */
-#  ifndef ZCR_SEED2
-#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
-#  endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
-    const char *passwd;         /* password string */
-    unsigned char *buf;         /* where to write header */
-    int bufSize;
-    unsigned long* pkeys;
-    const unsigned long* pcrc_32_tab;
-    unsigned long crcForCrypting;
-{
-    int n;                       /* index in random header */
-    int t;                       /* temporary */
-    int c;                       /* random byte */
-    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
-    static unsigned calls = 0;   /* ensure different random header each time */
-
-    if (bufSize<RAND_HEAD_LEN)
-      return 0;
-
-    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
-     * output of rand() to get less predictability, since rand() is
-     * often poorly implemented.
-     */
-    if (++calls == 1)
-    {
-        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
-    }
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        c = (rand() >> 7) & 0xff;
-        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
-    }
-    /* Encrypt random header (last two bytes is high word of crc) */
-    init_keys(passwd, pkeys, pcrc_32_tab);
-    for (n = 0; n < RAND_HEAD_LEN-2; n++)
-    {
-        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
-    }
-    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
-    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
-    return n;
-}
-
-#endif
+/* crypt.h -- base code for crypt/uncrypt ZIPfile

+

+

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+

+   This code is a modified version of crypting code in Infozip distribution

+

+   The encryption/decryption parts of this source code (as opposed to the

+   non-echoing password parts) were originally written in Europe.  The

+   whole source package can be freely distributed, including from the USA.

+   (Prior to January 2000, re-export from the US was a violation of US law.)

+

+   This encryption code is a direct transcription of the algorithm from

+   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This

+   file (appnote.txt) is distributed with the PKZIP program (even in the

+   version without encryption capabilities).

+

+   If you don't need crypting in your application, just define symbols

+   NOCRYPT and NOUNCRYPT.

+

+   This code support the "Traditional PKWARE Encryption".

+

+   The new AES encryption added on Zip format by Winzip (see the page

+   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong

+   Encryption is not supported.

+*/

+

+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))

+

+/***********************************************************************

+ * Return the next byte in the pseudo-random sequence

+ */

+static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)

+{

+    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an

+                     * unpredictable manner on 16-bit systems; not a problem

+                     * with any known compiler so far, though */

+

+    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;

+    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);

+}

+

+/***********************************************************************

+ * Update the encryption keys with the next byte of plain text

+ */

+static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)

+{

+    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);

+    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;

+    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;

+    {

+      register int keyshift = (int)((*(pkeys+1)) >> 24);

+      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);

+    }

+    return c;

+}

+

+

+/***********************************************************************

+ * Initialize the encryption keys and the random header according to

+ * the given password.

+ */

+static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)

+{

+    *(pkeys+0) = 305419896L;

+    *(pkeys+1) = 591751049L;

+    *(pkeys+2) = 878082192L;

+    while (*passwd != '\0') {

+        update_keys(pkeys,pcrc_32_tab,(int)*passwd);

+        passwd++;

+    }

+}

+

+#define zdecode(pkeys,pcrc_32_tab,c) \

+    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))

+

+#define zencode(pkeys,pcrc_32_tab,c,t) \

+    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))

+

+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED

+

+#define RAND_HEAD_LEN  12

+   /* "last resort" source for second part of crypt seed pattern */

+#  ifndef ZCR_SEED2

+#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */

+#  endif

+

+static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)

+    const char *passwd;         /* password string */

+    unsigned char *buf;         /* where to write header */

+    int bufSize;

+    unsigned long* pkeys;

+    const unsigned long* pcrc_32_tab;

+    unsigned long crcForCrypting;

+{

+    int n;                       /* index in random header */

+    int t;                       /* temporary */

+    int c;                       /* random byte */

+    unsigned char header[RAND_HEAD_LEN-2]; /* random header */

+    static unsigned calls = 0;   /* ensure different random header each time */

+

+    if (bufSize<RAND_HEAD_LEN)

+      return 0;

+

+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the

+     * output of rand() to get less predictability, since rand() is

+     * often poorly implemented.

+     */

+    if (++calls == 1)

+    {

+        srand((unsigned)(time(NULL) ^ ZCR_SEED2));

+    }

+    init_keys(passwd, pkeys, pcrc_32_tab);

+    for (n = 0; n < RAND_HEAD_LEN-2; n++)

+    {

+        c = (rand() >> 7) & 0xff;

+        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);

+    }

+    /* Encrypt random header (last two bytes is high word of crc) */

+    init_keys(passwd, pkeys, pcrc_32_tab);

+    for (n = 0; n < RAND_HEAD_LEN-2; n++)

+    {

+        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);

+    }

+    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);

+    buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);

+    return n;

+}

+

+#endif

diff --git a/contrib/minizip/ioapi.c b/contrib/minizip/ioapi.c
index c9e69f2..7f20c18 100644
--- a/contrib/minizip/ioapi.c
+++ b/contrib/minizip/ioapi.c
@@ -1,177 +1,177 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
-   files using zlib + zip or unzip API
-
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR    1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END    2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET    0
-#endif
-
-voidpf ZCALLBACK fopen_file_func OF((
-   voidpf opaque,
-   const char* filename,
-   int mode));
-
-uLong ZCALLBACK fread_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   void* buf,
-   uLong size));
-
-uLong ZCALLBACK fwrite_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   const void* buf,
-   uLong size));
-
-long ZCALLBACK ftell_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-long ZCALLBACK fseek_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   uLong offset,
-   int origin));
-
-int ZCALLBACK fclose_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-int ZCALLBACK ferror_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-
-voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
-   voidpf opaque;
-   const char* filename;
-   int mode;
-{
-    FILE* file = NULL;
-    const char* mode_fopen = NULL;
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-        mode_fopen = "rb";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-        mode_fopen = "r+b";
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-        mode_fopen = "wb";
-
-    if ((filename!=NULL) && (mode_fopen != NULL))
-        file = fopen(filename, mode_fopen);
-    return file;
-}
-
-
-uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
-   voidpf opaque;
-   voidpf stream;
-   void* buf;
-   uLong size;
-{
-    uLong ret;
-    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-
-uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
-   voidpf opaque;
-   voidpf stream;
-   const void* buf;
-   uLong size;
-{
-    uLong ret;
-    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
-    return ret;
-}
-
-long ZCALLBACK ftell_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    long ret;
-    ret = ftell((FILE *)stream);
-    return ret;
-}
-
-long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
-   voidpf opaque;
-   voidpf stream;
-   uLong offset;
-   int origin;
-{
-    int fseek_origin=0;
-    long ret;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        fseek_origin = SEEK_CUR;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        fseek_origin = SEEK_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        fseek_origin = SEEK_SET;
-        break;
-    default: return -1;
-    }
-    ret = 0;
-    fseek((FILE *)stream, offset, fseek_origin);
-    return ret;
-}
-
-int ZCALLBACK fclose_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    int ret;
-    ret = fclose((FILE *)stream);
-    return ret;
-}
-
-int ZCALLBACK ferror_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    int ret;
-    ret = ferror((FILE *)stream);
-    return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
-  zlib_filefunc_def* pzlib_filefunc_def;
-{
-    pzlib_filefunc_def->zopen_file = fopen_file_func;
-    pzlib_filefunc_def->zread_file = fread_file_func;
-    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
-    pzlib_filefunc_def->ztell_file = ftell_file_func;
-    pzlib_filefunc_def->zseek_file = fseek_file_func;
-    pzlib_filefunc_def->zclose_file = fclose_file_func;
-    pzlib_filefunc_def->zerror_file = ferror_file_func;
-    pzlib_filefunc_def->opaque = NULL;
-}
+/* ioapi.c -- IO base function header for compress/uncompress .zip

+   files using zlib + zip or unzip API

+

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include "zlib.h"

+#include "ioapi.h"

+

+

+

+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */

+

+#ifndef SEEK_CUR

+#define SEEK_CUR    1

+#endif

+

+#ifndef SEEK_END

+#define SEEK_END    2

+#endif

+

+#ifndef SEEK_SET

+#define SEEK_SET    0

+#endif

+

+voidpf ZCALLBACK fopen_file_func OF((

+   voidpf opaque,

+   const char* filename,

+   int mode));

+

+uLong ZCALLBACK fread_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   void* buf,

+   uLong size));

+

+uLong ZCALLBACK fwrite_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   const void* buf,

+   uLong size));

+

+long ZCALLBACK ftell_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+long ZCALLBACK fseek_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   uLong offset,

+   int origin));

+

+int ZCALLBACK fclose_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+int ZCALLBACK ferror_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+

+voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)

+   voidpf opaque;

+   const char* filename;

+   int mode;

+{

+    FILE* file = NULL;

+    const char* mode_fopen = NULL;

+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)

+        mode_fopen = "rb";

+    else

+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)

+        mode_fopen = "r+b";

+    else

+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)

+        mode_fopen = "wb";

+

+    if ((filename!=NULL) && (mode_fopen != NULL))

+        file = fopen(filename, mode_fopen);

+    return file;

+}

+

+

+uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)

+   voidpf opaque;

+   voidpf stream;

+   void* buf;

+   uLong size;

+{

+    uLong ret;

+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);

+    return ret;

+}

+

+

+uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)

+   voidpf opaque;

+   voidpf stream;

+   const void* buf;

+   uLong size;

+{

+    uLong ret;

+    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);

+    return ret;

+}

+

+long ZCALLBACK ftell_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    long ret;

+    ret = ftell((FILE *)stream);

+    return ret;

+}

+

+long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)

+   voidpf opaque;

+   voidpf stream;

+   uLong offset;

+   int origin;

+{

+    int fseek_origin=0;

+    long ret;

+    switch (origin)

+    {

+    case ZLIB_FILEFUNC_SEEK_CUR :

+        fseek_origin = SEEK_CUR;

+        break;

+    case ZLIB_FILEFUNC_SEEK_END :

+        fseek_origin = SEEK_END;

+        break;

+    case ZLIB_FILEFUNC_SEEK_SET :

+        fseek_origin = SEEK_SET;

+        break;

+    default: return -1;

+    }

+    ret = 0;

+    fseek((FILE *)stream, offset, fseek_origin);

+    return ret;

+}

+

+int ZCALLBACK fclose_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    int ret;

+    ret = fclose((FILE *)stream);

+    return ret;

+}

+

+int ZCALLBACK ferror_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    int ret;

+    ret = ferror((FILE *)stream);

+    return ret;

+}

+

+void fill_fopen_filefunc (pzlib_filefunc_def)

+  zlib_filefunc_def* pzlib_filefunc_def;

+{

+    pzlib_filefunc_def->zopen_file = fopen_file_func;

+    pzlib_filefunc_def->zread_file = fread_file_func;

+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;

+    pzlib_filefunc_def->ztell_file = ftell_file_func;

+    pzlib_filefunc_def->zseek_file = fseek_file_func;

+    pzlib_filefunc_def->zclose_file = fclose_file_func;

+    pzlib_filefunc_def->zerror_file = ferror_file_func;

+    pzlib_filefunc_def->opaque = NULL;

+}

diff --git a/contrib/minizip/ioapi.h b/contrib/minizip/ioapi.h
index b761161..e73a3b2 100644
--- a/contrib/minizip/ioapi.h
+++ b/contrib/minizip/ioapi.h
@@ -1,75 +1,75 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
-   files using zlib + zip or unzip API
-
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ      (1)
-#define ZLIB_FILEFUNC_MODE_WRITE     (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE   (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong  (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong  (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long   (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long   (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int    (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int    (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
-    open_file_func      zopen_file;
-    read_file_func      zread_file;
-    write_file_func     zwrite_file;
-    tell_file_func      ztell_file;
-    seek_file_func      zseek_file;
-    close_file_func     zclose_file;
-    testerror_file_func zerror_file;
-    voidpf              opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+/* ioapi.h -- IO base function header for compress/uncompress .zip

+   files using zlib + zip or unzip API

+

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+#ifndef _ZLIBIOAPI_H

+#define _ZLIBIOAPI_H

+

+

+#define ZLIB_FILEFUNC_SEEK_CUR (1)

+#define ZLIB_FILEFUNC_SEEK_END (2)

+#define ZLIB_FILEFUNC_SEEK_SET (0)

+

+#define ZLIB_FILEFUNC_MODE_READ      (1)

+#define ZLIB_FILEFUNC_MODE_WRITE     (2)

+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)

+

+#define ZLIB_FILEFUNC_MODE_EXISTING (4)

+#define ZLIB_FILEFUNC_MODE_CREATE   (8)

+

+

+#ifndef ZCALLBACK

+

+#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)

+#define ZCALLBACK CALLBACK

+#else

+#define ZCALLBACK

+#endif

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));

+typedef uLong  (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));

+typedef uLong  (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));

+typedef long   (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));

+typedef long   (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));

+typedef int    (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));

+typedef int    (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));

+

+typedef struct zlib_filefunc_def_s

+{

+    open_file_func      zopen_file;

+    read_file_func      zread_file;

+    write_file_func     zwrite_file;

+    tell_file_func      ztell_file;

+    seek_file_func      zseek_file;

+    close_file_func     zclose_file;

+    testerror_file_func zerror_file;

+    voidpf              opaque;

+} zlib_filefunc_def;

+

+

+

+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));

+

+#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))

+#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))

+#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))

+#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))

+#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))

+#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))

+

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif

+

diff --git a/contrib/minizip/iowin32.c b/contrib/minizip/iowin32.c
index 940dc0b..694bc03 100644
--- a/contrib/minizip/iowin32.c
+++ b/contrib/minizip/iowin32.c
@@ -1,270 +1,270 @@
-/* iowin32.c -- IO base function header for compress/uncompress .zip
-   files using zlib + zip or unzip API
-   This IO API version uses the Win32 API (for Microsoft Windows)
-
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdlib.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-#include "iowin32.h"
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
-#endif
-
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-voidpf ZCALLBACK win32_open_file_func OF((
-   voidpf opaque,
-   const char* filename,
-   int mode));
-
-uLong ZCALLBACK win32_read_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   void* buf,
-   uLong size));
-
-uLong ZCALLBACK win32_write_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   const void* buf,
-   uLong size));
-
-long ZCALLBACK win32_tell_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-long ZCALLBACK win32_seek_file_func OF((
-   voidpf opaque,
-   voidpf stream,
-   uLong offset,
-   int origin));
-
-int ZCALLBACK win32_close_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-int ZCALLBACK win32_error_file_func OF((
-   voidpf opaque,
-   voidpf stream));
-
-typedef struct
-{
-    HANDLE hf;
-    int error;
-} WIN32FILE_IOWIN;
-
-voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
-   voidpf opaque;
-   const char* filename;
-   int mode;
-{
-    const char* mode_fopen = NULL;
-    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
-    HANDLE hFile = 0;
-    voidpf ret=NULL;
-
-    dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
-
-    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
-    {
-        dwDesiredAccess = GENERIC_READ;
-        dwCreationDisposition = OPEN_EXISTING;
-        dwShareMode = FILE_SHARE_READ;
-    }
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
-    {
-        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
-        dwCreationDisposition = OPEN_EXISTING;
-    }
-    else
-    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
-    {
-        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
-        dwCreationDisposition = CREATE_ALWAYS;
-    }
-
-    if ((filename!=NULL) && (dwDesiredAccess != 0))
-        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
-                      dwCreationDisposition, dwFlagsAndAttributes, NULL);
-
-    if (hFile == INVALID_HANDLE_VALUE)
-        hFile = NULL;
-
-    if (hFile != NULL)
-    {
-        WIN32FILE_IOWIN w32fiow;
-        w32fiow.hf = hFile;
-        w32fiow.error = 0;
-        ret = malloc(sizeof(WIN32FILE_IOWIN));
-        if (ret==NULL)
-            CloseHandle(hFile);
-        else *((WIN32FILE_IOWIN*)ret) = w32fiow;
-    }
-    return ret;
-}
-
-
-uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
-   voidpf opaque;
-   voidpf stream;
-   void* buf;
-   uLong size;
-{
-    uLong ret=0;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-    if (hFile != NULL)
-        if (!ReadFile(hFile, buf, size, &ret, NULL))
-        {
-            DWORD dwErr = GetLastError();
-            if (dwErr == ERROR_HANDLE_EOF)
-                dwErr = 0;
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-        }
-
-    return ret;
-}
-
-
-uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
-   voidpf opaque;
-   voidpf stream;
-   const void* buf;
-   uLong size;
-{
-    uLong ret=0;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-
-    if (hFile !=NULL)
-        if (!WriteFile(hFile, buf, size, &ret, NULL))
-        {
-            DWORD dwErr = GetLastError();
-            if (dwErr == ERROR_HANDLE_EOF)
-                dwErr = 0;
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-        }
-
-    return ret;
-}
-
-long ZCALLBACK win32_tell_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    long ret=-1;
-    HANDLE hFile = NULL;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-    if (hFile != NULL)
-    {
-        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
-        if (dwSet == INVALID_SET_FILE_POINTER)
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = -1;
-        }
-        else
-            ret=(long)dwSet;
-    }
-    return ret;
-}
-
-long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
-   voidpf opaque;
-   voidpf stream;
-   uLong offset;
-   int origin;
-{
-    DWORD dwMoveMethod=0xFFFFFFFF;
-    HANDLE hFile = NULL;
-
-    long ret=-1;
-    if (stream!=NULL)
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-    switch (origin)
-    {
-    case ZLIB_FILEFUNC_SEEK_CUR :
-        dwMoveMethod = FILE_CURRENT;
-        break;
-    case ZLIB_FILEFUNC_SEEK_END :
-        dwMoveMethod = FILE_END;
-        break;
-    case ZLIB_FILEFUNC_SEEK_SET :
-        dwMoveMethod = FILE_BEGIN;
-        break;
-    default: return -1;
-    }
-
-    if (hFile != NULL)
-    {
-        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
-        if (dwSet == INVALID_SET_FILE_POINTER)
-        {
-            DWORD dwErr = GetLastError();
-            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
-            ret = -1;
-        }
-        else
-            ret=0;
-    }
-    return ret;
-}
-
-int ZCALLBACK win32_close_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    int ret=-1;
-
-    if (stream!=NULL)
-    {
-        HANDLE hFile;
-        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-        if (hFile != NULL)
-        {
-            CloseHandle(hFile);
-            ret=0;
-        }
-        free(stream);
-    }
-    return ret;
-}
-
-int ZCALLBACK win32_error_file_func (opaque, stream)
-   voidpf opaque;
-   voidpf stream;
-{
-    int ret=-1;
-    if (stream!=NULL)
-    {
-        ret = ((WIN32FILE_IOWIN*)stream) -> error;
-    }
-    return ret;
-}
-
-void fill_win32_filefunc (pzlib_filefunc_def)
-  zlib_filefunc_def* pzlib_filefunc_def;
-{
-    pzlib_filefunc_def->zopen_file = win32_open_file_func;
-    pzlib_filefunc_def->zread_file = win32_read_file_func;
-    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
-    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
-    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
-    pzlib_filefunc_def->zclose_file = win32_close_file_func;
-    pzlib_filefunc_def->zerror_file = win32_error_file_func;
-    pzlib_filefunc_def->opaque=NULL;
-}
+/* iowin32.c -- IO base function header for compress/uncompress .zip

+   files using zlib + zip or unzip API

+   This IO API version uses the Win32 API (for Microsoft Windows)

+

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+#include <stdlib.h>

+

+#include "zlib.h"

+#include "ioapi.h"

+#include "iowin32.h"

+

+#ifndef INVALID_HANDLE_VALUE

+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)

+#endif

+

+#ifndef INVALID_SET_FILE_POINTER

+#define INVALID_SET_FILE_POINTER ((DWORD)-1)

+#endif

+

+voidpf ZCALLBACK win32_open_file_func OF((

+   voidpf opaque,

+   const char* filename,

+   int mode));

+

+uLong ZCALLBACK win32_read_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   void* buf,

+   uLong size));

+

+uLong ZCALLBACK win32_write_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   const void* buf,

+   uLong size));

+

+long ZCALLBACK win32_tell_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+long ZCALLBACK win32_seek_file_func OF((

+   voidpf opaque,

+   voidpf stream,

+   uLong offset,

+   int origin));

+

+int ZCALLBACK win32_close_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+int ZCALLBACK win32_error_file_func OF((

+   voidpf opaque,

+   voidpf stream));

+

+typedef struct

+{

+    HANDLE hf;

+    int error;

+} WIN32FILE_IOWIN;

+

+voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)

+   voidpf opaque;

+   const char* filename;

+   int mode;

+{

+    const char* mode_fopen = NULL;

+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;

+    HANDLE hFile = 0;

+    voidpf ret=NULL;

+

+    dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;

+

+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)

+    {

+        dwDesiredAccess = GENERIC_READ;

+        dwCreationDisposition = OPEN_EXISTING;

+        dwShareMode = FILE_SHARE_READ;

+    }

+    else

+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)

+    {

+        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;

+        dwCreationDisposition = OPEN_EXISTING;

+    }

+    else

+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)

+    {

+        dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;

+        dwCreationDisposition = CREATE_ALWAYS;

+    }

+

+    if ((filename!=NULL) && (dwDesiredAccess != 0))

+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,

+                      dwCreationDisposition, dwFlagsAndAttributes, NULL);

+

+    if (hFile == INVALID_HANDLE_VALUE)

+        hFile = NULL;

+

+    if (hFile != NULL)

+    {

+        WIN32FILE_IOWIN w32fiow;

+        w32fiow.hf = hFile;

+        w32fiow.error = 0;

+        ret = malloc(sizeof(WIN32FILE_IOWIN));

+        if (ret==NULL)

+            CloseHandle(hFile);

+        else *((WIN32FILE_IOWIN*)ret) = w32fiow;

+    }

+    return ret;

+}

+

+

+uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)

+   voidpf opaque;

+   voidpf stream;

+   void* buf;

+   uLong size;

+{

+    uLong ret=0;

+    HANDLE hFile = NULL;

+    if (stream!=NULL)

+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;

+    if (hFile != NULL)

+        if (!ReadFile(hFile, buf, size, &ret, NULL))

+        {

+            DWORD dwErr = GetLastError();

+            if (dwErr == ERROR_HANDLE_EOF)

+                dwErr = 0;

+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;

+        }

+

+    return ret;

+}

+

+

+uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)

+   voidpf opaque;

+   voidpf stream;

+   const void* buf;

+   uLong size;

+{

+    uLong ret=0;

+    HANDLE hFile = NULL;

+    if (stream!=NULL)

+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;

+

+    if (hFile !=NULL)

+        if (!WriteFile(hFile, buf, size, &ret, NULL))

+        {

+            DWORD dwErr = GetLastError();

+            if (dwErr == ERROR_HANDLE_EOF)

+                dwErr = 0;

+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;

+        }

+

+    return ret;

+}

+

+long ZCALLBACK win32_tell_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    long ret=-1;

+    HANDLE hFile = NULL;

+    if (stream!=NULL)

+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;

+    if (hFile != NULL)

+    {

+        DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);

+        if (dwSet == INVALID_SET_FILE_POINTER)

+        {

+            DWORD dwErr = GetLastError();

+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;

+            ret = -1;

+        }

+        else

+            ret=(long)dwSet;

+    }

+    return ret;

+}

+

+long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)

+   voidpf opaque;

+   voidpf stream;

+   uLong offset;

+   int origin;

+{

+    DWORD dwMoveMethod=0xFFFFFFFF;

+    HANDLE hFile = NULL;

+

+    long ret=-1;

+    if (stream!=NULL)

+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;

+    switch (origin)

+    {

+    case ZLIB_FILEFUNC_SEEK_CUR :

+        dwMoveMethod = FILE_CURRENT;

+        break;

+    case ZLIB_FILEFUNC_SEEK_END :

+        dwMoveMethod = FILE_END;

+        break;

+    case ZLIB_FILEFUNC_SEEK_SET :

+        dwMoveMethod = FILE_BEGIN;

+        break;

+    default: return -1;

+    }

+

+    if (hFile != NULL)

+    {

+        DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);

+        if (dwSet == INVALID_SET_FILE_POINTER)

+        {

+            DWORD dwErr = GetLastError();

+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;

+            ret = -1;

+        }

+        else

+            ret=0;

+    }

+    return ret;

+}

+

+int ZCALLBACK win32_close_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    int ret=-1;

+

+    if (stream!=NULL)

+    {

+        HANDLE hFile;

+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;

+        if (hFile != NULL)

+        {

+            CloseHandle(hFile);

+            ret=0;

+        }

+        free(stream);

+    }

+    return ret;

+}

+

+int ZCALLBACK win32_error_file_func (opaque, stream)

+   voidpf opaque;

+   voidpf stream;

+{

+    int ret=-1;

+    if (stream!=NULL)

+    {

+        ret = ((WIN32FILE_IOWIN*)stream) -> error;

+    }

+    return ret;

+}

+

+void fill_win32_filefunc (pzlib_filefunc_def)

+  zlib_filefunc_def* pzlib_filefunc_def;

+{

+    pzlib_filefunc_def->zopen_file = win32_open_file_func;

+    pzlib_filefunc_def->zread_file = win32_read_file_func;

+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;

+    pzlib_filefunc_def->ztell_file = win32_tell_file_func;

+    pzlib_filefunc_def->zseek_file = win32_seek_file_func;

+    pzlib_filefunc_def->zclose_file = win32_close_file_func;

+    pzlib_filefunc_def->zerror_file = win32_error_file_func;

+    pzlib_filefunc_def->opaque=NULL;

+}

diff --git a/contrib/minizip/iowin32.h b/contrib/minizip/iowin32.h
index 8774fe7..e9c5f8b 100644
--- a/contrib/minizip/iowin32.h
+++ b/contrib/minizip/iowin32.h
@@ -1,21 +1,21 @@
-/* iowin32.h -- IO base function header for compress/uncompress .zip
-   files using zlib + zip or unzip API
-   This IO API version uses the Win32 API (for Microsoft Windows)
-
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <windows.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#ifdef __cplusplus
-}
-#endif
+/* iowin32.h -- IO base function header for compress/uncompress .zip

+   files using zlib + zip or unzip API

+   This IO API version uses the Win32 API (for Microsoft Windows)

+

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+#include <windows.h>

+

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));

+

+#ifdef __cplusplus

+}

+#endif

diff --git a/contrib/minizip/miniunz.c b/contrib/minizip/miniunz.c
index a6b06a2..82d8702 100644
--- a/contrib/minizip/miniunz.c
+++ b/contrib/minizip/miniunz.c
@@ -1,585 +1,585 @@
-/*
-   miniunz.c
-   Version 1.01b, May 30th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "unzip.h"
-
-#define CASESENSITIVITY (0)
-#define WRITEBUFFERSIZE (8192)
-#define MAXFILENAME (256)
-
-#ifdef WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-/*
-  mini unzip, demo of unzip package
-
-  usage :
-  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
-    if it exists
-*/
-
-
-/* change_file_date : change the date/time of a file
-    filename : the filename of the file where date/time must be modified
-    dosdate : the new date at the MSDos format (4 bytes)
-    tmu_date : the SAME new date at the tm_unz format */
-void change_file_date(filename,dosdate,tmu_date)
-    const char *filename;
-    uLong dosdate;
-    tm_unz tmu_date;
-{
-#ifdef WIN32
-  HANDLE hFile;
-  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
-
-  hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
-                      0,NULL,OPEN_EXISTING,0,NULL);
-  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
-  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
-  LocalFileTimeToFileTime(&ftLocal,&ftm);
-  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
-  CloseHandle(hFile);
-#else
-#ifdef unix
-  struct utimbuf ut;
-  struct tm newdate;
-  newdate.tm_sec = tmu_date.tm_sec;
-  newdate.tm_min=tmu_date.tm_min;
-  newdate.tm_hour=tmu_date.tm_hour;
-  newdate.tm_mday=tmu_date.tm_mday;
-  newdate.tm_mon=tmu_date.tm_mon;
-  if (tmu_date.tm_year > 1900)
-      newdate.tm_year=tmu_date.tm_year - 1900;
-  else
-      newdate.tm_year=tmu_date.tm_year ;
-  newdate.tm_isdst=-1;
-
-  ut.actime=ut.modtime=mktime(&newdate);
-  utime(filename,&ut);
-#endif
-#endif
-}
-
-
-/* mymkdir and change_file_date are not 100 % portable
-   As I don't know well Unix, I wait feedback for the unix portion */
-
-int mymkdir(dirname)
-    const char* dirname;
-{
-    int ret=0;
-#ifdef WIN32
-    ret = mkdir(dirname);
-#else
-#ifdef unix
-    ret = mkdir (dirname,0775);
-#endif
-#endif
-    return ret;
-}
-
-int makedir (newdir)
-    char *newdir;
-{
-  char *buffer ;
-  char *p;
-  int  len = (int)strlen(newdir);
-
-  if (len <= 0)
-    return 0;
-
-  buffer = (char*)malloc(len+1);
-  strcpy(buffer,newdir);
-
-  if (buffer[len-1] == '/') {
-    buffer[len-1] = '\0';
-  }
-  if (mymkdir(buffer) == 0)
-    {
-      free(buffer);
-      return 1;
-    }
-
-  p = buffer+1;
-  while (1)
-    {
-      char hold;
-
-      while(*p && *p != '\\' && *p != '/')
-        p++;
-      hold = *p;
-      *p = 0;
-      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
-        {
-          printf("couldn't create directory %s\n",buffer);
-          free(buffer);
-          return 0;
-        }
-      if (hold == 0)
-        break;
-      *p++ = hold;
-    }
-  free(buffer);
-  return 1;
-}
-
-void do_banner()
-{
-    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");
-}
-
-void do_help()
-{
-    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" \
-           "  -x  Extract with pathname\n" \
-           "  -v  list files\n" \
-           "  -l  list files\n" \
-           "  -d  directory to extract into\n" \
-           "  -o  overwrite files without prompting\n" \
-           "  -p  extract crypted file using password\n\n");
-}
-
-
-int do_list(uf)
-    unzFile uf;
-{
-    uLong i;
-    unz_global_info gi;
-    int err;
-
-    err = unzGetGlobalInfo (uf,&gi);
-    if (err!=UNZ_OK)
-        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-    printf(" Length  Method   Size  Ratio   Date    Time   CRC-32     Name\n");
-    printf(" ------  ------   ----  -----   ----    ----   ------     ----\n");
-    for (i=0;i<gi.number_entry;i++)
-    {
-        char filename_inzip[256];
-        unz_file_info file_info;
-        uLong ratio=0;
-        const char *string_method;
-        char charCrypt=' ';
-        err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-        if (err!=UNZ_OK)
-        {
-            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
-            break;
-        }
-        if (file_info.uncompressed_size>0)
-            ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
-
-        /* display a '*' if the file is crypted */
-        if ((file_info.flag & 1) != 0)
-            charCrypt='*';
-
-        if (file_info.compression_method==0)
-            string_method="Stored";
-        else
-        if (file_info.compression_method==Z_DEFLATED)
-        {
-            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
-            if (iLevel==0)
-              string_method="Defl:N";
-            else if (iLevel==1)
-              string_method="Defl:X";
-            else if ((iLevel==2) || (iLevel==3))
-              string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
-        }
-        else
-            string_method="Unkn. ";
-
-        printf("%7lu  %6s%c%7lu %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
-                file_info.uncompressed_size,string_method,
-                charCrypt,
-                file_info.compressed_size,
-                ratio,
-                (uLong)file_info.tmu_date.tm_mon + 1,
-                (uLong)file_info.tmu_date.tm_mday,
-                (uLong)file_info.tmu_date.tm_year % 100,
-                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
-                (uLong)file_info.crc,filename_inzip);
-        if ((i+1)<gi.number_entry)
-        {
-            err = unzGoToNextFile(uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzGoToNextFile\n",err);
-                break;
-            }
-        }
-    }
-
-    return 0;
-}
-
-
-int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
-    unzFile uf;
-    const int* popt_extract_without_path;
-    int* popt_overwrite;
-    const char* password;
-{
-    char filename_inzip[256];
-    char* filename_withoutpath;
-    char* p;
-    int err=UNZ_OK;
-    FILE *fout=NULL;
-    void* buf;
-    uInt size_buf;
-
-    unz_file_info file_info;
-    uLong ratio=0;
-    err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
-
-    if (err!=UNZ_OK)
-    {
-        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
-        return err;
-    }
-
-    size_buf = WRITEBUFFERSIZE;
-    buf = (void*)malloc(size_buf);
-    if (buf==NULL)
-    {
-        printf("Error allocating memory\n");
-        return UNZ_INTERNALERROR;
-    }
-
-    p = filename_withoutpath = filename_inzip;
-    while ((*p) != '\0')
-    {
-        if (((*p)=='/') || ((*p)=='\\'))
-            filename_withoutpath = p+1;
-        p++;
-    }
-
-    if ((*filename_withoutpath)=='\0')
-    {
-        if ((*popt_extract_without_path)==0)
-        {
-            printf("creating directory: %s\n",filename_inzip);
-            mymkdir(filename_inzip);
-        }
-    }
-    else
-    {
-        const char* write_filename;
-        int skip=0;
-
-        if ((*popt_extract_without_path)==0)
-            write_filename = filename_inzip;
-        else
-            write_filename = filename_withoutpath;
-
-        err = unzOpenCurrentFilePassword(uf,password);
-        if (err!=UNZ_OK)
-        {
-            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
-        }
-
-        if (((*popt_overwrite)==0) && (err==UNZ_OK))
-        {
-            char rep=0;
-            FILE* ftestexist;
-            ftestexist = fopen(write_filename,"rb");
-            if (ftestexist!=NULL)
-            {
-                fclose(ftestexist);
-                do
-                {
-                    char answer[128];
-                    int ret;
-
-                    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] ;
-                    if ((rep>='a') && (rep<='z'))
-                        rep -= 0x20;
-                }
-                while ((rep!='Y') && (rep!='N') && (rep!='A'));
-            }
-
-            if (rep == 'N')
-                skip = 1;
-
-            if (rep == 'A')
-                *popt_overwrite=1;
-        }
-
-        if ((skip==0) && (err==UNZ_OK))
-        {
-            fout=fopen(write_filename,"wb");
-
-            /* some zipfile don't contain directory alone before file */
-            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
-                                (filename_withoutpath!=(char*)filename_inzip))
-            {
-                char c=*(filename_withoutpath-1);
-                *(filename_withoutpath-1)='\0';
-                makedir(write_filename);
-                *(filename_withoutpath-1)=c;
-                fout=fopen(write_filename,"wb");
-            }
-
-            if (fout==NULL)
-            {
-                printf("error opening %s\n",write_filename);
-            }
-        }
-
-        if (fout!=NULL)
-        {
-            printf(" extracting: %s\n",write_filename);
-
-            do
-            {
-                err = unzReadCurrentFile(uf,buf,size_buf);
-                if (err<0)
-                {
-                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
-                    break;
-                }
-                if (err>0)
-                    if (fwrite(buf,err,1,fout)!=1)
-                    {
-                        printf("error in writing extracted file\n");
-                        err=UNZ_ERRNO;
-                        break;
-                    }
-            }
-            while (err>0);
-            if (fout)
-                    fclose(fout);
-
-            if (err==0)
-                change_file_date(write_filename,file_info.dosDate,
-                                 file_info.tmu_date);
-        }
-
-        if (err==UNZ_OK)
-        {
-            err = unzCloseCurrentFile (uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
-            }
-        }
-        else
-            unzCloseCurrentFile(uf); /* don't lose the error */
-    }
-
-    free(buf);
-    return err;
-}
-
-
-int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
-    unzFile uf;
-    int opt_extract_without_path;
-    int opt_overwrite;
-    const char* password;
-{
-    uLong i;
-    unz_global_info gi;
-    int err;
-    FILE* fout=NULL;
-
-    err = unzGetGlobalInfo (uf,&gi);
-    if (err!=UNZ_OK)
-        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
-
-    for (i=0;i<gi.number_entry;i++)
-    {
-        if (do_extract_currentfile(uf,&opt_extract_without_path,
-                                      &opt_overwrite,
-                                      password) != UNZ_OK)
-            break;
-
-        if ((i+1)<gi.number_entry)
-        {
-            err = unzGoToNextFile(uf);
-            if (err!=UNZ_OK)
-            {
-                printf("error %d with zipfile in unzGoToNextFile\n",err);
-                break;
-            }
-        }
-    }
-
-    return 0;
-}
-
-int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
-    unzFile uf;
-    const char* filename;
-    int opt_extract_without_path;
-    int opt_overwrite;
-    const char* password;
-{
-    int err = UNZ_OK;
-    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
-    {
-        printf("file %s not found in the zipfile\n",filename);
-        return 2;
-    }
-
-    if (do_extract_currentfile(uf,&opt_extract_without_path,
-                                      &opt_overwrite,
-                                      password) == UNZ_OK)
-        return 0;
-    else
-        return 1;
-}
-
-
-int main(argc,argv)
-    int argc;
-    char *argv[];
-{
-    const char *zipfilename=NULL;
-    const char *filename_to_extract=NULL;
-    const char *password=NULL;
-    char filename_try[MAXFILENAME+16] = "";
-    int i;
-    int opt_do_list=0;
-    int opt_do_extract=1;
-    int opt_do_extract_withoutpath=0;
-    int opt_overwrite=0;
-    int opt_extractdir=0;
-    const char *dirname=NULL;
-    unzFile uf=NULL;
-
-    do_banner();
-    if (argc==1)
-    {
-        do_help();
-        return 0;
-    }
-    else
-    {
-        for (i=1;i<argc;i++)
-        {
-            if ((*argv[i])=='-')
-            {
-                const char *p=argv[i]+1;
-
-                while ((*p)!='\0')
-                {
-                    char c=*(p++);;
-                    if ((c=='l') || (c=='L'))
-                        opt_do_list = 1;
-                    if ((c=='v') || (c=='V'))
-                        opt_do_list = 1;
-                    if ((c=='x') || (c=='X'))
-                        opt_do_extract = 1;
-                    if ((c=='e') || (c=='E'))
-                        opt_do_extract = opt_do_extract_withoutpath = 1;
-                    if ((c=='o') || (c=='O'))
-                        opt_overwrite=1;
-                    if ((c=='d') || (c=='D'))
-                    {
-                        opt_extractdir=1;
-                        dirname=argv[i+1];
-                    }
-
-                    if (((c=='p') || (c=='P')) && (i+1<argc))
-                    {
-                        password=argv[i+1];
-                        i++;
-                    }
-                }
-            }
-            else
-            {
-                if (zipfilename == NULL)
-                    zipfilename = argv[i];
-                else if ((filename_to_extract==NULL) && (!opt_extractdir))
-                        filename_to_extract = argv[i] ;
-            }
-        }
-    }
-
-    if (zipfilename!=NULL)
-    {
-
-#        ifdef USEWIN32IOAPI
-        zlib_filefunc_def ffunc;
-#        endif
-
-        strncpy(filename_try, zipfilename,MAXFILENAME-1);
-        /* strncpy doesnt append the trailing NULL, of the string is too long. */
-        filename_try[ MAXFILENAME ] = '\0';
-
-#        ifdef USEWIN32IOAPI
-        fill_win32_filefunc(&ffunc);
-        uf = unzOpen2(zipfilename,&ffunc);
-#        else
-        uf = unzOpen(zipfilename);
-#        endif
-        if (uf==NULL)
-        {
-            strcat(filename_try,".zip");
-#            ifdef USEWIN32IOAPI
-            uf = unzOpen2(filename_try,&ffunc);
-#            else
-            uf = unzOpen(filename_try);
-#            endif
-        }
-    }
-
-    if (uf==NULL)
-    {
-        printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
-        return 1;
-    }
-    printf("%s opened\n",filename_try);
-
-    if (opt_do_list==1)
-        return do_list(uf);
-    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)
-            return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);
-        else
-            return do_extract_onefile(uf,filename_to_extract,
-                                      opt_do_extract_withoutpath,opt_overwrite,password);
-    }
-    unzCloseCurrentFile(uf);
-
-    return 0;
-}
+/*

+   miniunz.c

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <time.h>

+#include <errno.h>

+#include <fcntl.h>

+

+#ifdef unix

+# include <unistd.h>

+# include <utime.h>

+#else

+# include <direct.h>

+# include <io.h>

+#endif

+

+#include "unzip.h"

+

+#define CASESENSITIVITY (0)

+#define WRITEBUFFERSIZE (8192)

+#define MAXFILENAME (256)

+

+#ifdef WIN32

+#define USEWIN32IOAPI

+#include "iowin32.h"

+#endif

+/*

+  mini unzip, demo of unzip package

+

+  usage :

+  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

+    if it exists

+*/

+

+

+/* change_file_date : change the date/time of a file

+    filename : the filename of the file where date/time must be modified

+    dosdate : the new date at the MSDos format (4 bytes)

+    tmu_date : the SAME new date at the tm_unz format */

+void change_file_date(filename,dosdate,tmu_date)

+    const char *filename;

+    uLong dosdate;

+    tm_unz tmu_date;

+{

+#ifdef WIN32

+  HANDLE hFile;

+  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;

+

+  hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,

+                      0,NULL,OPEN_EXISTING,0,NULL);

+  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);

+  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);

+  LocalFileTimeToFileTime(&ftLocal,&ftm);

+  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);

+  CloseHandle(hFile);

+#else

+#ifdef unix

+  struct utimbuf ut;

+  struct tm newdate;

+  newdate.tm_sec = tmu_date.tm_sec;

+  newdate.tm_min=tmu_date.tm_min;

+  newdate.tm_hour=tmu_date.tm_hour;

+  newdate.tm_mday=tmu_date.tm_mday;

+  newdate.tm_mon=tmu_date.tm_mon;

+  if (tmu_date.tm_year > 1900)

+      newdate.tm_year=tmu_date.tm_year - 1900;

+  else

+      newdate.tm_year=tmu_date.tm_year ;

+  newdate.tm_isdst=-1;

+

+  ut.actime=ut.modtime=mktime(&newdate);

+  utime(filename,&ut);

+#endif

+#endif

+}

+

+

+/* mymkdir and change_file_date are not 100 % portable

+   As I don't know well Unix, I wait feedback for the unix portion */

+

+int mymkdir(dirname)

+    const char* dirname;

+{

+    int ret=0;

+#ifdef WIN32

+    ret = mkdir(dirname);

+#else

+#ifdef unix

+    ret = mkdir (dirname,0775);

+#endif

+#endif

+    return ret;

+}

+

+int makedir (newdir)

+    char *newdir;

+{

+  char *buffer ;

+  char *p;

+  int  len = (int)strlen(newdir);

+

+  if (len <= 0)

+    return 0;

+

+  buffer = (char*)malloc(len+1);

+  strcpy(buffer,newdir);

+

+  if (buffer[len-1] == '/') {

+    buffer[len-1] = '\0';

+  }

+  if (mymkdir(buffer) == 0)

+    {

+      free(buffer);

+      return 1;

+    }

+

+  p = buffer+1;

+  while (1)

+    {

+      char hold;

+

+      while(*p && *p != '\\' && *p != '/')

+        p++;

+      hold = *p;

+      *p = 0;

+      if ((mymkdir(buffer) == -1) && (errno == ENOENT))

+        {

+          printf("couldn't create directory %s\n",buffer);

+          free(buffer);

+          return 0;

+        }

+      if (hold == 0)

+        break;

+      *p++ = hold;

+    }

+  free(buffer);

+  return 1;

+}

+

+void do_banner()

+{

+    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");

+}

+

+void do_help()

+{

+    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" \

+           "  -x  Extract with pathname\n" \

+           "  -v  list files\n" \

+           "  -l  list files\n" \

+           "  -d  directory to extract into\n" \

+           "  -o  overwrite files without prompting\n" \

+           "  -p  extract crypted file using password\n\n");

+}

+

+

+int do_list(uf)

+    unzFile uf;

+{

+    uLong i;

+    unz_global_info gi;

+    int err;

+

+    err = unzGetGlobalInfo (uf,&gi);

+    if (err!=UNZ_OK)

+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);

+    printf(" Length  Method   Size  Ratio   Date    Time   CRC-32     Name\n");

+    printf(" ------  ------   ----  -----   ----    ----   ------     ----\n");

+    for (i=0;i<gi.number_entry;i++)

+    {

+        char filename_inzip[256];

+        unz_file_info file_info;

+        uLong ratio=0;

+        const char *string_method;

+        char charCrypt=' ';

+        err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);

+        if (err!=UNZ_OK)

+        {

+            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);

+            break;

+        }

+        if (file_info.uncompressed_size>0)

+            ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;

+

+        /* display a '*' if the file is crypted */

+        if ((file_info.flag & 1) != 0)

+            charCrypt='*';

+

+        if (file_info.compression_method==0)

+            string_method="Stored";

+        else

+        if (file_info.compression_method==Z_DEFLATED)

+        {

+            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);

+            if (iLevel==0)

+              string_method="Defl:N";

+            else if (iLevel==1)

+              string_method="Defl:X";

+            else if ((iLevel==2) || (iLevel==3))

+              string_method="Defl:F"; /* 2:fast , 3 : extra fast*/

+        }

+        else

+            string_method="Unkn. ";

+

+        printf("%7lu  %6s%c%7lu %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",

+                file_info.uncompressed_size,string_method,

+                charCrypt,

+                file_info.compressed_size,

+                ratio,

+                (uLong)file_info.tmu_date.tm_mon + 1,

+                (uLong)file_info.tmu_date.tm_mday,

+                (uLong)file_info.tmu_date.tm_year % 100,

+                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,

+                (uLong)file_info.crc,filename_inzip);

+        if ((i+1)<gi.number_entry)

+        {

+            err = unzGoToNextFile(uf);

+            if (err!=UNZ_OK)

+            {

+                printf("error %d with zipfile in unzGoToNextFile\n",err);

+                break;

+            }

+        }

+    }

+

+    return 0;

+}

+

+

+int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)

+    unzFile uf;

+    const int* popt_extract_without_path;

+    int* popt_overwrite;

+    const char* password;

+{

+    char filename_inzip[256];

+    char* filename_withoutpath;

+    char* p;

+    int err=UNZ_OK;

+    FILE *fout=NULL;

+    void* buf;

+    uInt size_buf;

+

+    unz_file_info file_info;

+    uLong ratio=0;

+    err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);

+

+    if (err!=UNZ_OK)

+    {

+        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);

+        return err;

+    }

+

+    size_buf = WRITEBUFFERSIZE;

+    buf = (void*)malloc(size_buf);

+    if (buf==NULL)

+    {

+        printf("Error allocating memory\n");

+        return UNZ_INTERNALERROR;

+    }

+

+    p = filename_withoutpath = filename_inzip;

+    while ((*p) != '\0')

+    {

+        if (((*p)=='/') || ((*p)=='\\'))

+            filename_withoutpath = p+1;

+        p++;

+    }

+

+    if ((*filename_withoutpath)=='\0')

+    {

+        if ((*popt_extract_without_path)==0)

+        {

+            printf("creating directory: %s\n",filename_inzip);

+            mymkdir(filename_inzip);

+        }

+    }

+    else

+    {

+        const char* write_filename;

+        int skip=0;

+

+        if ((*popt_extract_without_path)==0)

+            write_filename = filename_inzip;

+        else

+            write_filename = filename_withoutpath;

+

+        err = unzOpenCurrentFilePassword(uf,password);

+        if (err!=UNZ_OK)

+        {

+            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);

+        }

+

+        if (((*popt_overwrite)==0) && (err==UNZ_OK))

+        {

+            char rep=0;

+            FILE* ftestexist;

+            ftestexist = fopen(write_filename,"rb");

+            if (ftestexist!=NULL)

+            {

+                fclose(ftestexist);

+                do

+                {

+                    char answer[128];

+                    int ret;

+

+                    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] ;

+                    if ((rep>='a') && (rep<='z'))

+                        rep -= 0x20;

+                }

+                while ((rep!='Y') && (rep!='N') && (rep!='A'));

+            }

+

+            if (rep == 'N')

+                skip = 1;

+

+            if (rep == 'A')

+                *popt_overwrite=1;

+        }

+

+        if ((skip==0) && (err==UNZ_OK))

+        {

+            fout=fopen(write_filename,"wb");

+

+            /* some zipfile don't contain directory alone before file */

+            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&

+                                (filename_withoutpath!=(char*)filename_inzip))

+            {

+                char c=*(filename_withoutpath-1);

+                *(filename_withoutpath-1)='\0';

+                makedir(write_filename);

+                *(filename_withoutpath-1)=c;

+                fout=fopen(write_filename,"wb");

+            }

+

+            if (fout==NULL)

+            {

+                printf("error opening %s\n",write_filename);

+            }

+        }

+

+        if (fout!=NULL)

+        {

+            printf(" extracting: %s\n",write_filename);

+

+            do

+            {

+                err = unzReadCurrentFile(uf,buf,size_buf);

+                if (err<0)

+                {

+                    printf("error %d with zipfile in unzReadCurrentFile\n",err);

+                    break;

+                }

+                if (err>0)

+                    if (fwrite(buf,err,1,fout)!=1)

+                    {

+                        printf("error in writing extracted file\n");

+                        err=UNZ_ERRNO;

+                        break;

+                    }

+            }

+            while (err>0);

+            if (fout)

+                    fclose(fout);

+

+            if (err==0)

+                change_file_date(write_filename,file_info.dosDate,

+                                 file_info.tmu_date);

+        }

+

+        if (err==UNZ_OK)

+        {

+            err = unzCloseCurrentFile (uf);

+            if (err!=UNZ_OK)

+            {

+                printf("error %d with zipfile in unzCloseCurrentFile\n",err);

+            }

+        }

+        else

+            unzCloseCurrentFile(uf); /* don't lose the error */

+    }

+

+    free(buf);

+    return err;

+}

+

+

+int do_extract(uf,opt_extract_without_path,opt_overwrite,password)

+    unzFile uf;

+    int opt_extract_without_path;

+    int opt_overwrite;

+    const char* password;

+{

+    uLong i;

+    unz_global_info gi;

+    int err;

+    FILE* fout=NULL;

+

+    err = unzGetGlobalInfo (uf,&gi);

+    if (err!=UNZ_OK)

+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);

+

+    for (i=0;i<gi.number_entry;i++)

+    {

+        if (do_extract_currentfile(uf,&opt_extract_without_path,

+                                      &opt_overwrite,

+                                      password) != UNZ_OK)

+            break;

+

+        if ((i+1)<gi.number_entry)

+        {

+            err = unzGoToNextFile(uf);

+            if (err!=UNZ_OK)

+            {

+                printf("error %d with zipfile in unzGoToNextFile\n",err);

+                break;

+            }

+        }

+    }

+

+    return 0;

+}

+

+int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)

+    unzFile uf;

+    const char* filename;

+    int opt_extract_without_path;

+    int opt_overwrite;

+    const char* password;

+{

+    int err = UNZ_OK;

+    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)

+    {

+        printf("file %s not found in the zipfile\n",filename);

+        return 2;

+    }

+

+    if (do_extract_currentfile(uf,&opt_extract_without_path,

+                                      &opt_overwrite,

+                                      password) == UNZ_OK)

+        return 0;

+    else

+        return 1;

+}

+

+

+int main(argc,argv)

+    int argc;

+    char *argv[];

+{

+    const char *zipfilename=NULL;

+    const char *filename_to_extract=NULL;

+    const char *password=NULL;

+    char filename_try[MAXFILENAME+16] = "";

+    int i;

+    int opt_do_list=0;

+    int opt_do_extract=1;

+    int opt_do_extract_withoutpath=0;

+    int opt_overwrite=0;

+    int opt_extractdir=0;

+    const char *dirname=NULL;

+    unzFile uf=NULL;

+

+    do_banner();

+    if (argc==1)

+    {

+        do_help();

+        return 0;

+    }

+    else

+    {

+        for (i=1;i<argc;i++)

+        {

+            if ((*argv[i])=='-')

+            {

+                const char *p=argv[i]+1;

+

+                while ((*p)!='\0')

+                {

+                    char c=*(p++);;

+                    if ((c=='l') || (c=='L'))

+                        opt_do_list = 1;

+                    if ((c=='v') || (c=='V'))

+                        opt_do_list = 1;

+                    if ((c=='x') || (c=='X'))

+                        opt_do_extract = 1;

+                    if ((c=='e') || (c=='E'))

+                        opt_do_extract = opt_do_extract_withoutpath = 1;

+                    if ((c=='o') || (c=='O'))

+                        opt_overwrite=1;

+                    if ((c=='d') || (c=='D'))

+                    {

+                        opt_extractdir=1;

+                        dirname=argv[i+1];

+                    }

+

+                    if (((c=='p') || (c=='P')) && (i+1<argc))

+                    {

+                        password=argv[i+1];

+                        i++;

+                    }

+                }

+            }

+            else

+            {

+                if (zipfilename == NULL)

+                    zipfilename = argv[i];

+                else if ((filename_to_extract==NULL) && (!opt_extractdir))

+                        filename_to_extract = argv[i] ;

+            }

+        }

+    }

+

+    if (zipfilename!=NULL)

+    {

+

+#        ifdef USEWIN32IOAPI

+        zlib_filefunc_def ffunc;

+#        endif

+

+        strncpy(filename_try, zipfilename,MAXFILENAME-1);

+        /* strncpy doesnt append the trailing NULL, of the string is too long. */

+        filename_try[ MAXFILENAME ] = '\0';

+

+#        ifdef USEWIN32IOAPI

+        fill_win32_filefunc(&ffunc);

+        uf = unzOpen2(zipfilename,&ffunc);

+#        else

+        uf = unzOpen(zipfilename);

+#        endif

+        if (uf==NULL)

+        {

+            strcat(filename_try,".zip");

+#            ifdef USEWIN32IOAPI

+            uf = unzOpen2(filename_try,&ffunc);

+#            else

+            uf = unzOpen(filename_try);

+#            endif

+        }

+    }

+

+    if (uf==NULL)

+    {

+        printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);

+        return 1;

+    }

+    printf("%s opened\n",filename_try);

+

+    if (opt_do_list==1)

+        return do_list(uf);

+    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)

+            return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite,password);

+        else

+            return do_extract_onefile(uf,filename_to_extract,

+                                      opt_do_extract_withoutpath,opt_overwrite,password);

+    }

+    unzCloseCurrentFile(uf);

+

+    return 0;

+}

diff --git a/contrib/minizip/minizip.c b/contrib/minizip/minizip.c
index 918c322..70fee02 100644
--- a/contrib/minizip/minizip.c
+++ b/contrib/minizip/minizip.c
@@ -1,420 +1,420 @@
-/*
-   minizip.c
-   Version 1.01b, May 30th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#ifdef unix
-# include <unistd.h>
-# include <utime.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-#else
-# include <direct.h>
-# include <io.h>
-#endif
-
-#include "zip.h"
-
-#ifdef WIN32
-#define USEWIN32IOAPI
-#include "iowin32.h"
-#endif
-
-
-
-#define WRITEBUFFERSIZE (16384)
-#define MAXFILENAME (256)
-
-#ifdef WIN32
-uLong filetime(f, tmzip, dt)
-    char *f;                /* name of file to get info on */
-    tm_zip *tmzip;             /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-  int ret = 0;
-  {
-      FILETIME ftLocal;
-      HANDLE hFind;
-      WIN32_FIND_DATA  ff32;
-
-      hFind = FindFirstFile(f,&ff32);
-      if (hFind != INVALID_HANDLE_VALUE)
-      {
-        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
-        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
-        FindClose(hFind);
-        ret = 1;
-      }
-  }
-  return ret;
-}
-#else
-#ifdef unix
-uLong filetime(f, tmzip, dt)
-    char *f;               /* name of file to get info on */
-    tm_zip *tmzip;         /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-  int ret=0;
-  struct stat s;        /* results of stat() */
-  struct tm* filedate;
-  time_t tm_t=0;
-
-  if (strcmp(f,"-")!=0)
-  {
-    char name[MAXFILENAME+1];
-    int len = strlen(f);
-    if (len > MAXFILENAME)
-      len = MAXFILENAME;
-
-    strncpy(name, f,MAXFILENAME-1);
-    /* strncpy doesnt append the trailing NULL, of the string is too long. */
-    name[ MAXFILENAME ] = '\0';
-
-    if (name[len - 1] == '/')
-      name[len - 1] = '\0';
-    /* not all systems allow stat'ing a file with / appended */
-    if (stat(name,&s)==0)
-    {
-      tm_t = s.st_mtime;
-      ret = 1;
-    }
-  }
-  filedate = localtime(&tm_t);
-
-  tmzip->tm_sec  = filedate->tm_sec;
-  tmzip->tm_min  = filedate->tm_min;
-  tmzip->tm_hour = filedate->tm_hour;
-  tmzip->tm_mday = filedate->tm_mday;
-  tmzip->tm_mon  = filedate->tm_mon ;
-  tmzip->tm_year = filedate->tm_year;
-
-  return ret;
-}
-#else
-uLong filetime(f, tmzip, dt)
-    char *f;                /* name of file to get info on */
-    tm_zip *tmzip;             /* return value: access, modific. and creation times */
-    uLong *dt;             /* dostime */
-{
-    return 0;
-}
-#endif
-#endif
-
-
-
-
-int check_exist_file(filename)
-    const char* filename;
-{
-    FILE* ftestexist;
-    int ret = 1;
-    ftestexist = fopen(filename,"rb");
-    if (ftestexist==NULL)
-        ret = 0;
-    else
-        fclose(ftestexist);
-    return ret;
-}
-
-void do_banner()
-{
-    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");
-}
-
-void do_help()
-{
-    printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \
-           "  -o  Overwrite existing file.zip\n" \
-           "  -a  Append to existing file.zip\n" \
-           "  -0  Store only\n" \
-           "  -1  Compress faster\n" \
-           "  -9  Compress better\n\n");
-}
-
-/* calculate the CRC32 of a file,
-   because to encrypt a file, we need known the CRC32 of the file before */
-int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
-{
-   unsigned long calculate_crc=0;
-   int err=ZIP_OK;
-   FILE * fin = fopen(filenameinzip,"rb");
-   unsigned long size_read = 0;
-   unsigned long total_read = 0;
-   if (fin==NULL)
-   {
-       err = ZIP_ERRNO;
-   }
-
-    if (err == ZIP_OK)
-        do
-        {
-            err = ZIP_OK;
-            size_read = (int)fread(buf,1,size_buf,fin);
-            if (size_read < size_buf)
-                if (feof(fin)==0)
-            {
-                printf("error in reading %s\n",filenameinzip);
-                err = ZIP_ERRNO;
-            }
-
-            if (size_read>0)
-                calculate_crc = crc32(calculate_crc,buf,size_read);
-            total_read += size_read;
-
-        } while ((err == ZIP_OK) && (size_read>0));
-
-    if (fin)
-        fclose(fin);
-
-    *result_crc=calculate_crc;
-    printf("file %s crc %x\n",filenameinzip,calculate_crc);
-    return err;
-}
-
-int main(argc,argv)
-    int argc;
-    char *argv[];
-{
-    int i;
-    int opt_overwrite=0;
-    int opt_compress_level=Z_DEFAULT_COMPRESSION;
-    int zipfilenamearg = 0;
-    char filename_try[MAXFILENAME+16];
-    int zipok;
-    int err=0;
-    int size_buf=0;
-    void* buf=NULL;
-    const char* password=NULL;
-
-
-    do_banner();
-    if (argc==1)
-    {
-        do_help();
-        return 0;
-    }
-    else
-    {
-        for (i=1;i<argc;i++)
-        {
-            if ((*argv[i])=='-')
-            {
-                const char *p=argv[i]+1;
-
-                while ((*p)!='\0')
-                {
-                    char c=*(p++);;
-                    if ((c=='o') || (c=='O'))
-                        opt_overwrite = 1;
-                    if ((c=='a') || (c=='A'))
-                        opt_overwrite = 2;
-                    if ((c>='0') && (c<='9'))
-                        opt_compress_level = c-'0';
-
-                    if (((c=='p') || (c=='P')) && (i+1<argc))
-                    {
-                        password=argv[i+1];
-                        i++;
-                    }
-                }
-            }
-            else
-                if (zipfilenamearg == 0)
-                    zipfilenamearg = i ;
-        }
-    }
-
-    size_buf = WRITEBUFFERSIZE;
-    buf = (void*)malloc(size_buf);
-    if (buf==NULL)
-    {
-        printf("Error allocating memory\n");
-        return ZIP_INTERNALERROR;
-    }
-
-    if (zipfilenamearg==0)
-        zipok=0;
-    else
-    {
-        int i,len;
-        int dot_found=0;
-
-        zipok = 1 ;
-        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
-        /* strncpy doesnt append the trailing NULL, of the string is too long. */
-        filename_try[ MAXFILENAME ] = '\0';
-
-        len=(int)strlen(filename_try);
-        for (i=0;i<len;i++)
-            if (filename_try[i]=='.')
-                dot_found=1;
-
-        if (dot_found==0)
-            strcat(filename_try,".zip");
-
-        if (opt_overwrite==2)
-        {
-            /* if the file don't exist, we not append file */
-            if (check_exist_file(filename_try)==0)
-                opt_overwrite=1;
-        }
-        else
-        if (opt_overwrite==0)
-            if (check_exist_file(filename_try)!=0)
-            {
-                char rep=0;
-                do
-                {
-                    char answer[128];
-                    int ret;
-                    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] ;
-                    if ((rep>='a') && (rep<='z'))
-                        rep -= 0x20;
-                }
-                while ((rep!='Y') && (rep!='N') && (rep!='A'));
-                if (rep=='N')
-                    zipok = 0;
-                if (rep=='A')
-                    opt_overwrite = 2;
-            }
-    }
-
-    if (zipok==1)
-    {
-        zipFile zf;
-        int errclose;
-#        ifdef USEWIN32IOAPI
-        zlib_filefunc_def ffunc;
-        fill_win32_filefunc(&ffunc);
-        zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
-#        else
-        zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
-#        endif
-
-        if (zf == NULL)
-        {
-            printf("error opening %s\n",filename_try);
-            err= ZIP_ERRNO;
-        }
-        else
-            printf("creating %s\n",filename_try);
-
-        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);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;
-                int size_read;
-                const char* filenameinzip = argv[i];
-                zip_fileinfo zi;
-                unsigned long crcFile=0;
-
-                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
-                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
-                zi.dosDate = 0;
-                zi.internal_fa = 0;
-                zi.external_fa = 0;
-                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
-
-/*
-                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
-                                 NULL,0,NULL,0,NULL / * comment * /,
-                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
-                                 opt_compress_level);
-*/
-                if ((password != NULL) && (err==ZIP_OK))
-                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
-
-                err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,
-                                 NULL,0,NULL,0,NULL /* comment*/,
-                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
-                                 opt_compress_level,0,
-                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 password,crcFile);
-
-                if (err != ZIP_OK)
-                    printf("error in opening %s in zipfile\n",filenameinzip);
-                else
-                {
-                    fin = fopen(filenameinzip,"rb");
-                    if (fin==NULL)
-                    {
-                        err=ZIP_ERRNO;
-                        printf("error in opening %s for reading\n",filenameinzip);
-                    }
-                }
-
-                if (err == ZIP_OK)
-                    do
-                    {
-                        err = ZIP_OK;
-                        size_read = (int)fread(buf,1,size_buf,fin);
-                        if (size_read < size_buf)
-                            if (feof(fin)==0)
-                        {
-                            printf("error in reading %s\n",filenameinzip);
-                            err = ZIP_ERRNO;
-                        }
-
-                        if (size_read>0)
-                        {
-                            err = zipWriteInFileInZip (zf,buf,size_read);
-                            if (err<0)
-                            {
-                                printf("error in writing %s in the zipfile\n",
-                                                 filenameinzip);
-                            }
-
-                        }
-                    } while ((err == ZIP_OK) && (size_read>0));
-
-                if (fin)
-                    fclose(fin);
-
-                if (err<0)
-                    err=ZIP_ERRNO;
-                else
-                {
-                    err = zipCloseFileInZip(zf);
-                    if (err!=ZIP_OK)
-                        printf("error in closing %s in the zipfile\n",
-                                    filenameinzip);
-                }
-            }
-        }
-        errclose = zipClose(zf,NULL);
-        if (errclose != ZIP_OK)
-            printf("error in closing %s\n",filename_try);
-    }
-    else
-    {
-       do_help();
-    }
-
-    free(buf);
-    return 0;
-}
+/*

+   minizip.c

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+*/

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <time.h>

+#include <errno.h>

+#include <fcntl.h>

+

+#ifdef unix

+# include <unistd.h>

+# include <utime.h>

+# include <sys/types.h>

+# include <sys/stat.h>

+#else

+# include <direct.h>

+# include <io.h>

+#endif

+

+#include "zip.h"

+

+#ifdef WIN32

+#define USEWIN32IOAPI

+#include "iowin32.h"

+#endif

+

+

+

+#define WRITEBUFFERSIZE (16384)

+#define MAXFILENAME (256)

+

+#ifdef WIN32

+uLong filetime(f, tmzip, dt)

+    char *f;                /* name of file to get info on */

+    tm_zip *tmzip;             /* return value: access, modific. and creation times */

+    uLong *dt;             /* dostime */

+{

+  int ret = 0;

+  {

+      FILETIME ftLocal;

+      HANDLE hFind;

+      WIN32_FIND_DATA  ff32;

+

+      hFind = FindFirstFile(f,&ff32);

+      if (hFind != INVALID_HANDLE_VALUE)

+      {

+        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);

+        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);

+        FindClose(hFind);

+        ret = 1;

+      }

+  }

+  return ret;

+}

+#else

+#ifdef unix

+uLong filetime(f, tmzip, dt)

+    char *f;               /* name of file to get info on */

+    tm_zip *tmzip;         /* return value: access, modific. and creation times */

+    uLong *dt;             /* dostime */

+{

+  int ret=0;

+  struct stat s;        /* results of stat() */

+  struct tm* filedate;

+  time_t tm_t=0;

+

+  if (strcmp(f,"-")!=0)

+  {

+    char name[MAXFILENAME+1];

+    int len = strlen(f);

+    if (len > MAXFILENAME)

+      len = MAXFILENAME;

+

+    strncpy(name, f,MAXFILENAME-1);

+    /* strncpy doesnt append the trailing NULL, of the string is too long. */

+    name[ MAXFILENAME ] = '\0';

+

+    if (name[len - 1] == '/')

+      name[len - 1] = '\0';

+    /* not all systems allow stat'ing a file with / appended */

+    if (stat(name,&s)==0)

+    {

+      tm_t = s.st_mtime;

+      ret = 1;

+    }

+  }

+  filedate = localtime(&tm_t);

+

+  tmzip->tm_sec  = filedate->tm_sec;

+  tmzip->tm_min  = filedate->tm_min;

+  tmzip->tm_hour = filedate->tm_hour;

+  tmzip->tm_mday = filedate->tm_mday;

+  tmzip->tm_mon  = filedate->tm_mon ;

+  tmzip->tm_year = filedate->tm_year;

+

+  return ret;

+}

+#else

+uLong filetime(f, tmzip, dt)

+    char *f;                /* name of file to get info on */

+    tm_zip *tmzip;             /* return value: access, modific. and creation times */

+    uLong *dt;             /* dostime */

+{

+    return 0;

+}

+#endif

+#endif

+

+

+

+

+int check_exist_file(filename)

+    const char* filename;

+{

+    FILE* ftestexist;

+    int ret = 1;

+    ftestexist = fopen(filename,"rb");

+    if (ftestexist==NULL)

+        ret = 0;

+    else

+        fclose(ftestexist);

+    return ret;

+}

+

+void do_banner()

+{

+    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");

+}

+

+void do_help()

+{

+    printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] file.zip [files_to_add]\n\n" \

+           "  -o  Overwrite existing file.zip\n" \

+           "  -a  Append to existing file.zip\n" \

+           "  -0  Store only\n" \

+           "  -1  Compress faster\n" \

+           "  -9  Compress better\n\n");

+}

+

+/* calculate the CRC32 of a file,

+   because to encrypt a file, we need known the CRC32 of the file before */

+int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)

+{

+   unsigned long calculate_crc=0;

+   int err=ZIP_OK;

+   FILE * fin = fopen(filenameinzip,"rb");

+   unsigned long size_read = 0;

+   unsigned long total_read = 0;

+   if (fin==NULL)

+   {

+       err = ZIP_ERRNO;

+   }

+

+    if (err == ZIP_OK)

+        do

+        {

+            err = ZIP_OK;

+            size_read = (int)fread(buf,1,size_buf,fin);

+            if (size_read < size_buf)

+                if (feof(fin)==0)

+            {

+                printf("error in reading %s\n",filenameinzip);

+                err = ZIP_ERRNO;

+            }

+

+            if (size_read>0)

+                calculate_crc = crc32(calculate_crc,buf,size_read);

+            total_read += size_read;

+

+        } while ((err == ZIP_OK) && (size_read>0));

+

+    if (fin)

+        fclose(fin);

+

+    *result_crc=calculate_crc;

+    printf("file %s crc %x\n",filenameinzip,calculate_crc);

+    return err;

+}

+

+int main(argc,argv)

+    int argc;

+    char *argv[];

+{

+    int i;

+    int opt_overwrite=0;

+    int opt_compress_level=Z_DEFAULT_COMPRESSION;

+    int zipfilenamearg = 0;

+    char filename_try[MAXFILENAME+16];

+    int zipok;

+    int err=0;

+    int size_buf=0;

+    void* buf=NULL;

+    const char* password=NULL;

+

+

+    do_banner();

+    if (argc==1)

+    {

+        do_help();

+        return 0;

+    }

+    else

+    {

+        for (i=1;i<argc;i++)

+        {

+            if ((*argv[i])=='-')

+            {

+                const char *p=argv[i]+1;

+

+                while ((*p)!='\0')

+                {

+                    char c=*(p++);;

+                    if ((c=='o') || (c=='O'))

+                        opt_overwrite = 1;

+                    if ((c=='a') || (c=='A'))

+                        opt_overwrite = 2;

+                    if ((c>='0') && (c<='9'))

+                        opt_compress_level = c-'0';

+

+                    if (((c=='p') || (c=='P')) && (i+1<argc))

+                    {

+                        password=argv[i+1];

+                        i++;

+                    }

+                }

+            }

+            else

+                if (zipfilenamearg == 0)

+                    zipfilenamearg = i ;

+        }

+    }

+

+    size_buf = WRITEBUFFERSIZE;

+    buf = (void*)malloc(size_buf);

+    if (buf==NULL)

+    {

+        printf("Error allocating memory\n");

+        return ZIP_INTERNALERROR;

+    }

+

+    if (zipfilenamearg==0)

+        zipok=0;

+    else

+    {

+        int i,len;

+        int dot_found=0;

+

+        zipok = 1 ;

+        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);

+        /* strncpy doesnt append the trailing NULL, of the string is too long. */

+        filename_try[ MAXFILENAME ] = '\0';

+

+        len=(int)strlen(filename_try);

+        for (i=0;i<len;i++)

+            if (filename_try[i]=='.')

+                dot_found=1;

+

+        if (dot_found==0)

+            strcat(filename_try,".zip");

+

+        if (opt_overwrite==2)

+        {

+            /* if the file don't exist, we not append file */

+            if (check_exist_file(filename_try)==0)

+                opt_overwrite=1;

+        }

+        else

+        if (opt_overwrite==0)

+            if (check_exist_file(filename_try)!=0)

+            {

+                char rep=0;

+                do

+                {

+                    char answer[128];

+                    int ret;

+                    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] ;

+                    if ((rep>='a') && (rep<='z'))

+                        rep -= 0x20;

+                }

+                while ((rep!='Y') && (rep!='N') && (rep!='A'));

+                if (rep=='N')

+                    zipok = 0;

+                if (rep=='A')

+                    opt_overwrite = 2;

+            }

+    }

+

+    if (zipok==1)

+    {

+        zipFile zf;

+        int errclose;

+#        ifdef USEWIN32IOAPI

+        zlib_filefunc_def ffunc;

+        fill_win32_filefunc(&ffunc);

+        zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);

+#        else

+        zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);

+#        endif

+

+        if (zf == NULL)

+        {

+            printf("error opening %s\n",filename_try);

+            err= ZIP_ERRNO;

+        }

+        else

+            printf("creating %s\n",filename_try);

+

+        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);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;

+                int size_read;

+                const char* filenameinzip = argv[i];

+                zip_fileinfo zi;

+                unsigned long crcFile=0;

+

+                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =

+                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;

+                zi.dosDate = 0;

+                zi.internal_fa = 0;

+                zi.external_fa = 0;

+                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);

+

+/*

+                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,

+                                 NULL,0,NULL,0,NULL / * comment * /,

+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,

+                                 opt_compress_level);

+*/

+                if ((password != NULL) && (err==ZIP_OK))

+                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);

+

+                err = zipOpenNewFileInZip3(zf,filenameinzip,&zi,

+                                 NULL,0,NULL,0,NULL /* comment*/,

+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,

+                                 opt_compress_level,0,

+                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */

+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,

+                                 password,crcFile);

+

+                if (err != ZIP_OK)

+                    printf("error in opening %s in zipfile\n",filenameinzip);

+                else

+                {

+                    fin = fopen(filenameinzip,"rb");

+                    if (fin==NULL)

+                    {

+                        err=ZIP_ERRNO;

+                        printf("error in opening %s for reading\n",filenameinzip);

+                    }

+                }

+

+                if (err == ZIP_OK)

+                    do

+                    {

+                        err = ZIP_OK;

+                        size_read = (int)fread(buf,1,size_buf,fin);

+                        if (size_read < size_buf)

+                            if (feof(fin)==0)

+                        {

+                            printf("error in reading %s\n",filenameinzip);

+                            err = ZIP_ERRNO;

+                        }

+

+                        if (size_read>0)

+                        {

+                            err = zipWriteInFileInZip (zf,buf,size_read);

+                            if (err<0)

+                            {

+                                printf("error in writing %s in the zipfile\n",

+                                                 filenameinzip);

+                            }

+

+                        }

+                    } while ((err == ZIP_OK) && (size_read>0));

+

+                if (fin)

+                    fclose(fin);

+

+                if (err<0)

+                    err=ZIP_ERRNO;

+                else

+                {

+                    err = zipCloseFileInZip(zf);

+                    if (err!=ZIP_OK)

+                        printf("error in closing %s in the zipfile\n",

+                                    filenameinzip);

+                }

+            }

+        }

+        errclose = zipClose(zf,NULL);

+        if (errclose != ZIP_OK)

+            printf("error in closing %s\n",filename_try);

+    }

+    else

+    {

+       do_help();

+    }

+

+    free(buf);

+    return 0;

+}

diff --git a/contrib/minizip/mztools.c b/contrib/minizip/mztools.c
index c1266bc..bc5c798 100644
--- a/contrib/minizip/mztools.c
+++ b/contrib/minizip/mztools.c
@@ -1,281 +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;
-}
+/*

+  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 = (int)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;

+}

diff --git a/contrib/minizip/mztools.h b/contrib/minizip/mztools.h
index 88b3459..82d1597 100644
--- a/contrib/minizip/mztools.h
+++ b/contrib/minizip/mztools.h
@@ -1,31 +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
+/*

+  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

diff --git a/contrib/minizip/unzip.c b/contrib/minizip/unzip.c
index e14de9e..3a70629 100644
--- a/contrib/minizip/unzip.c
+++ b/contrib/minizip/unzip.c
@@ -1,1595 +1,1598 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
-   Version 1.01d, September 22th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-
-   Read unzip.h for more info
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
-  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
-
-  See the accompanying file LICENSE, version 2000-Apr-09 or later
-  (the contents of which are also included in zip.h) for terms of use.
-  If, for some reason, all these files are missing, the Info-ZIP license
-  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
-  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
-
-  The encryption/decryption parts of this source code (as opposed to the
-  non-echoing password parts) were originally written in Europe.  The
-  whole source package can be freely distributed, including from the USA.
-  (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
-  This encryption code is a direct transcription of the algorithm from
-  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
-  file (appnote.txt) is distributed with the PKZIP program (even in the
-  version without encryption capabilities).
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-#  include <stddef.h>
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
-
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-#    define CASESENSITIVITYDEFAULT_NO
-#  endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
-   " 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*/
-typedef struct unz_file_info_internal_s
-{
-    uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
-    when reading and decompress it */
-typedef struct
-{
-    char  *read_buffer;         /* internal buffer for compressed data */
-    z_stream stream;            /* zLib stream structure for inflate */
-
-    uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
-    uLong stream_initialised;   /* flag set if stream structure is initialised*/
-
-    uLong offset_local_extrafield;/* offset of the local extra field */
-    uInt  size_local_extrafield;/* size of the local extra field */
-    uLong pos_local_extrafield;   /* position in the local extra field in read*/
-
-    uLong crc32;                /* crc32 of all data uncompressed */
-    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
-    uLong rest_read_compressed; /* number of byte to be decompressed */
-    uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
-    zlib_filefunc_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    uLong compression_method;   /* compression method (0==store) */
-    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-    int   raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
-    zlib_filefunc_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    unz_global_info gi;       /* public global information */
-    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-    uLong num_file;             /* number of the current file in the zipfile*/
-    uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
-    uLong current_file_ok;      /* flag about the usability of the current file*/
-    uLong central_pos;          /* position of the beginning of the central dir*/
-
-    uLong size_central_dir;     /* size of the central directory  */
-    uLong offset_central_dir;   /* offset of start of central directory with
-                                   respect to the starting disk number */
-
-    unz_file_info cur_file_info; /* public info about the current file in zip*/
-    unz_file_info_internal cur_file_info_internal; /* private info about it*/
-    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
-                                        file if we are decompressing it */
-    int encrypted;
-#    ifndef NOUNCRYPT
-    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
-    const unsigned long* pcrc_32_tab;
-#    endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
-     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
-   for end of file.
-   IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    int *pi;
-{
-    unsigned char c;
-    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
-    if (err==1)
-    {
-        *pi = (int)c;
-        return UNZ_OK;
-    }
-    else
-    {
-        if (ZERROR(*pzlib_filefunc_def,filestream))
-            return UNZ_ERRNO;
-        else
-            return UNZ_EOF;
-    }
-}
-
-
-/* ===========================================================================
-   Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    uLong *pX;
-{
-    uLong x ;
-    int i;
-    int err;
-
-    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==UNZ_OK)
-        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==UNZ_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int unzlocal_getLong OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    uLong *pX;
-{
-    uLong x ;
-    int i;
-    int err;
-
-    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==UNZ_OK)
-        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==UNZ_OK)
-        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<16;
-
-    if (err==UNZ_OK)
-        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<24;
-
-    if (err==UNZ_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
-    const char* fileName1;
-    const char* fileName2;
-{
-    for (;;)
-    {
-        char c1=*(fileName1++);
-        char c2=*(fileName2++);
-        if ((c1>='a') && (c1<='z'))
-            c1 -= 0x20;
-        if ((c2>='a') && (c2<='z'))
-            c2 -= 0x20;
-        if (c1=='\0')
-            return ((c2=='\0') ? 0 : -1);
-        if (c2=='\0')
-            return 1;
-        if (c1<c2)
-            return -1;
-        if (c1>c2)
-            return 1;
-    }
-}
-
-
-#ifdef  CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
-   Compare two filename (fileName1,fileName2).
-   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
-   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
-                                                                or strcasecmp)
-   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
-        (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
-    const char* fileName1;
-    const char* fileName2;
-    int iCaseSensitivity;
-{
-    if (iCaseSensitivity==0)
-        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
-    if (iCaseSensitivity==1)
-        return strcmp(fileName1,fileName2);
-
-    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
-  Locate the Central directory of a zipfile (at the end, just before
-    the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-{
-    unsigned char* buf;
-    uLong uSizeFile;
-    uLong uBackRead;
-    uLong uMaxBack=0xffff; /* maximum size of global comment */
-    uLong uPosFound=0;
-
-    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-        return 0;
-
-
-    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
-    if (uMaxBack>uSizeFile)
-        uMaxBack = uSizeFile;
-
-    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-    if (buf==NULL)
-        return 0;
-
-    uBackRead = 4;
-    while (uBackRead<uMaxBack)
-    {
-        uLong uReadSize,uReadPos ;
-        int i;
-        if (uBackRead+BUFREADCOMMENT>uMaxBack)
-            uBackRead = uMaxBack;
-        else
-            uBackRead+=BUFREADCOMMENT;
-        uReadPos = uSizeFile-uBackRead ;
-
-        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
-        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            break;
-
-        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-            break;
-
-        for (i=(int)uReadSize-3; (i--)>0;)
-            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
-            {
-                uPosFound = uReadPos+i;
-                break;
-            }
-
-        if (uPosFound!=0)
-            break;
-    }
-    TRYFREE(buf);
-    return uPosFound;
-}
-
-/*
-  Open a Zip file. path contain the full pathname (by example,
-     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
-     "zlib/zlib114.zip".
-     If the zipfile cannot be opened (file doesn't exist or in not valid), the
-       return value is NULL.
-     Else, the return value is a unzFile Handle, usable with other function
-       of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
-    const char *path;
-    zlib_filefunc_def* pzlib_filefunc_def;
-{
-    unz_s us;
-    unz_s *s;
-    uLong central_pos,uL;
-
-    uLong number_disk;          /* number of the current dist, used for
-                                   spaning ZIP, unsupported, always 0*/
-    uLong number_disk_with_CD;  /* number the the disk with central dir, used
-                                   for spaning ZIP, unsupported, always 0*/
-    uLong number_entry_CD;      /* total number of entries in
-                                   the central dir
-                                   (same than number_entry on nospan) */
-
-    int err=UNZ_OK;
-
-    if (unz_copyright[0]!=' ')
-        return NULL;
-
-    if (pzlib_filefunc_def==NULL)
-        fill_fopen_filefunc(&us.z_filefunc);
-    else
-        us.z_filefunc = *pzlib_filefunc_def;
-
-    us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
-                                                 path,
-                                                 ZLIB_FILEFUNC_MODE_READ |
-                                                 ZLIB_FILEFUNC_MODE_EXISTING);
-    if (us.filestream==NULL)
-        return NULL;
-
-    central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
-    if (central_pos==0)
-        err=UNZ_ERRNO;
-
-    if (ZSEEK(us.z_filefunc, us.filestream,
-                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        err=UNZ_ERRNO;
-
-    /* the signature, already checked */
-    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* number of this disk */
-    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* number of the disk with the start of the central directory */
-    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* total number of entries in the central dir on this disk */
-    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* total number of entries in the central dir */
-    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if ((number_entry_CD!=us.gi.number_entry) ||
-        (number_disk_with_CD!=0) ||
-        (number_disk!=0))
-        err=UNZ_BADZIPFILE;
-
-    /* size of the central directory */
-    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* offset of start of central directory with respect to the
-          starting disk number */
-    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    /* zipfile comment length */
-    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
-        (err==UNZ_OK))
-        err=UNZ_BADZIPFILE;
-
-    if (err!=UNZ_OK)
-    {
-        ZCLOSE(us.z_filefunc, us.filestream);
-        return NULL;
-    }
-
-    us.byte_before_the_zipfile = central_pos -
-                            (us.offset_central_dir+us.size_central_dir);
-    us.central_pos = central_pos;
-    us.pfile_in_zip_read = NULL;
-    us.encrypted = 0;
-
-
-    s=(unz_s*)ALLOC(sizeof(unz_s));
-    *s=us;
-    unzGoToFirstFile((unzFile)s);
-    return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen (path)
-    const char *path;
-{
-    return unzOpen2(path, NULL);
-}
-
-/*
-  Close a ZipFile opened with unzipOpen.
-  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
-    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
-  return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
-    unzFile file;
-{
-    unz_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-
-    if (s->pfile_in_zip_read!=NULL)
-        unzCloseCurrentFile(file);
-
-    ZCLOSE(s->z_filefunc, s->filestream);
-    TRYFREE(s);
-    return UNZ_OK;
-}
-
-
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
-    unzFile file;
-    unz_global_info *pglobal_info;
-{
-    unz_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    *pglobal_info=s->gi;
-    return UNZ_OK;
-}
-
-
-/*
-   Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
-    uLong ulDosDate;
-    tm_unz* ptm;
-{
-    uLong uDate;
-    uDate = (uLong)(ulDosDate>>16);
-    ptm->tm_mday = (uInt)(uDate&0x1f) ;
-    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
-    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
-    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
-    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
-    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
-  Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
-                                                  unz_file_info *pfile_info,
-                                                  unz_file_info_internal
-                                                  *pfile_info_internal,
-                                                  char *szFileName,
-                                                  uLong fileNameBufferSize,
-                                                  void *extraField,
-                                                  uLong extraFieldBufferSize,
-                                                  char *szComment,
-                                                  uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
-                                              pfile_info,
-                                              pfile_info_internal,
-                                              szFileName, fileNameBufferSize,
-                                              extraField, extraFieldBufferSize,
-                                              szComment,  commentBufferSize)
-    unzFile file;
-    unz_file_info *pfile_info;
-    unz_file_info_internal *pfile_info_internal;
-    char *szFileName;
-    uLong fileNameBufferSize;
-    void *extraField;
-    uLong extraFieldBufferSize;
-    char *szComment;
-    uLong commentBufferSize;
-{
-    unz_s* s;
-    unz_file_info file_info;
-    unz_file_info_internal file_info_internal;
-    int err=UNZ_OK;
-    uLong uMagic;
-    long lSeek=0;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    if (ZSEEK(s->z_filefunc, s->filestream,
-              s->pos_in_central_dir+s->byte_before_the_zipfile,
-              ZLIB_FILEFUNC_SEEK_SET)!=0)
-        err=UNZ_ERRNO;
-
-
-    /* we check the magic */
-    if (err==UNZ_OK)
-        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
-            err=UNZ_ERRNO;
-        else if (uMagic!=0x02014b50)
-            err=UNZ_BADZIPFILE;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    lSeek+=file_info.size_filename;
-    if ((err==UNZ_OK) && (szFileName!=NULL))
-    {
-        uLong uSizeRead ;
-        if (file_info.size_filename<fileNameBufferSize)
-        {
-            *(szFileName+file_info.size_filename)='\0';
-            uSizeRead = file_info.size_filename;
-        }
-        else
-            uSizeRead = fileNameBufferSize;
-
-        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
-            if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek -= uSizeRead;
-    }
-
-
-    if ((err==UNZ_OK) && (extraField!=NULL))
-    {
-        uLong uSizeRead ;
-        if (file_info.size_file_extra<extraFieldBufferSize)
-            uSizeRead = file_info.size_file_extra;
-        else
-            uSizeRead = extraFieldBufferSize;
-
-        if (lSeek!=0)
-            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
-                lSeek=0;
-            else
-                err=UNZ_ERRNO;
-        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
-            if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek += file_info.size_file_extra - uSizeRead;
-    }
-    else
-        lSeek+=file_info.size_file_extra;
-
-
-    if ((err==UNZ_OK) && (szComment!=NULL))
-    {
-        uLong uSizeRead ;
-        if (file_info.size_file_comment<commentBufferSize)
-        {
-            *(szComment+file_info.size_file_comment)='\0';
-            uSizeRead = file_info.size_file_comment;
-        }
-        else
-            uSizeRead = commentBufferSize;
-
-        if (lSeek!=0)
-            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
-                lSeek=0;
-            else
-                err=UNZ_ERRNO;
-        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
-            if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
-                err=UNZ_ERRNO;
-        lSeek+=file_info.size_file_comment - uSizeRead;
-    }
-    else
-        lSeek+=file_info.size_file_comment;
-
-    if ((err==UNZ_OK) && (pfile_info!=NULL))
-        *pfile_info=file_info;
-
-    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
-        *pfile_info_internal=file_info_internal;
-
-    return err;
-}
-
-
-
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
-                                          pfile_info,
-                                          szFileName, fileNameBufferSize,
-                                          extraField, extraFieldBufferSize,
-                                          szComment,  commentBufferSize)
-    unzFile file;
-    unz_file_info *pfile_info;
-    char *szFileName;
-    uLong fileNameBufferSize;
-    void *extraField;
-    uLong extraFieldBufferSize;
-    char *szComment;
-    uLong commentBufferSize;
-{
-    return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
-                                                szFileName,fileNameBufferSize,
-                                                extraField,extraFieldBufferSize,
-                                                szComment,commentBufferSize);
-}
-
-/*
-  Set the current file of the zipfile to the first file.
-  return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
-    unzFile file;
-{
-    int err=UNZ_OK;
-    unz_s* s;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    s->pos_in_central_dir=s->offset_central_dir;
-    s->num_file=0;
-    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;
-}
-
-/*
-  Set the current file of the zipfile to the next file.
-  return UNZ_OK if there is no problem
-  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
-    unzFile file;
-{
-    unz_s* s;
-    int err;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    if (!s->current_file_ok)
-        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)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
-            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
-    s->num_file++;
-    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;
-}
-
-
-/*
-  Try locate the file szFileName in the zipfile.
-  For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
-  return value :
-  UNZ_OK if the file is found. It becomes the current file.
-  UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
-    unzFile file;
-    const char *szFileName;
-    int iCaseSensitivity;
-{
-    unz_s* s;
-    int err;
-
-    /* We remember the 'current' position in the file so that we can jump
-     * back there if we fail.
-     */
-    unz_file_info cur_file_infoSaved;
-    unz_file_info_internal cur_file_info_internalSaved;
-    uLong num_fileSaved;
-    uLong pos_in_central_dirSaved;
-
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-
-    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
-        return UNZ_PARAMERROR;
-
-    s=(unz_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    /* Save the current state */
-    num_fileSaved = s->num_file;
-    pos_in_central_dirSaved = s->pos_in_central_dir;
-    cur_file_infoSaved = s->cur_file_info;
-    cur_file_info_internalSaved = s->cur_file_info_internal;
-
-    err = unzGoToFirstFile(file);
-
-    while (err == UNZ_OK)
-    {
-        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
-        err = unzGetCurrentFileInfo(file,NULL,
-                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
-                                    NULL,0,NULL,0);
-        if (err == UNZ_OK)
-        {
-            if (unzStringFileNameCompare(szCurrentFileName,
-                                            szFileName,iCaseSensitivity)==0)
-                return UNZ_OK;
-            err = unzGoToNextFile(file);
-        }
-    }
-
-    /* We failed, so restore the state of the 'current file' to where we
-     * were.
-     */
-    s->num_file = num_fileSaved ;
-    s->pos_in_central_dir = pos_in_central_dirSaved ;
-    s->cur_file_info = cur_file_infoSaved;
-    s->cur_file_info_internal = cur_file_info_internalSaved;
-    return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
-    uLong pos_in_zip_directory;   // offset in file
-    uLong num_of_file;            // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
-    unzFile file;
-    unz_file_pos* file_pos;
-{
-    unz_s* s;
-
-    if (file==NULL || file_pos==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_END_OF_LIST_OF_FILE;
-
-    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
-    file_pos->num_of_file           = s->num_file;
-
-    return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
-    unzFile file;
-    unz_file_pos* file_pos;
-{
-    unz_s* s;
-    int err;
-
-    if (file==NULL || file_pos==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-
-    /* jump to the right spot */
-    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
-    s->num_file           = file_pos->num_of_file;
-
-    /* set the current file */
-    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
-                                               &s->cur_file_info_internal,
-                                               NULL,0,NULL,0,NULL,0);
-    /* return results */
-    s->current_file_ok = (err == UNZ_OK);
-    return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
-  Read the local header of the current zipfile
-  Check the coherency of the local header and info in the end of central
-        directory about this file
-  store in *piSizeVar the size of extra info in local header
-        (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
-                                                    poffset_local_extrafield,
-                                                    psize_local_extrafield)
-    unz_s* s;
-    uInt* piSizeVar;
-    uLong *poffset_local_extrafield;
-    uInt  *psize_local_extrafield;
-{
-    uLong uMagic,uData,uFlags;
-    uLong size_filename;
-    uLong size_extra_field;
-    int err=UNZ_OK;
-
-    *piSizeVar = 0;
-    *poffset_local_extrafield = 0;
-    *psize_local_extrafield = 0;
-
-    if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
-                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-
-    if (err==UNZ_OK)
-        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
-            err=UNZ_ERRNO;
-        else if (uMagic!=0x04034b50)
-            err=UNZ_BADZIPFILE;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
-        err=UNZ_ERRNO;
-/*
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
-        err=UNZ_BADZIPFILE;
-*/
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
-        err=UNZ_BADZIPFILE;
-
-    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
-                         (s->cur_file_info.compression_method!=Z_DEFLATED))
-        err=UNZ_BADZIPFILE;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
-        err=UNZ_ERRNO;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
-                              ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
-                              ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
-                              ((uFlags & 8)==0))
-        err=UNZ_BADZIPFILE;
-
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
-        err=UNZ_ERRNO;
-    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
-        err=UNZ_BADZIPFILE;
-
-    *piSizeVar += (uInt)size_filename;
-
-    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
-        err=UNZ_ERRNO;
-    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
-                                    SIZEZIPLOCALHEADER + size_filename;
-    *psize_local_extrafield = (uInt)size_extra_field;
-
-    *piSizeVar += (uInt)size_extra_field;
-
-    return err;
-}
-
-/*
-  Open for reading data the current file in the zipfile.
-  If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
-    unzFile file;
-    int* method;
-    int* level;
-    int raw;
-    const char* password;
-{
-    int err=UNZ_OK;
-    uInt iSizeVar;
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    uLong offset_local_extrafield;  /* offset of the local extra field */
-    uInt  size_local_extrafield;    /* size of the local extra field */
-#    ifndef NOUNCRYPT
-    char source[12];
-#    else
-    if (password != NULL)
-        return UNZ_PARAMERROR;
-#    endif
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    if (!s->current_file_ok)
-        return UNZ_PARAMERROR;
-
-    if (s->pfile_in_zip_read != NULL)
-        unzCloseCurrentFile(file);
-
-    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
-                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
-        return UNZ_BADZIPFILE;
-
-    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
-                                        ALLOC(sizeof(file_in_zip_read_info_s));
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_INTERNALERROR;
-
-    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
-    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
-    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
-    pfile_in_zip_read_info->pos_local_extrafield=0;
-    pfile_in_zip_read_info->raw=raw;
-
-    if (pfile_in_zip_read_info->read_buffer==NULL)
-    {
-        TRYFREE(pfile_in_zip_read_info);
-        return UNZ_INTERNALERROR;
-    }
-
-    pfile_in_zip_read_info->stream_initialised=0;
-
-    if (method!=NULL)
-        *method = (int)s->cur_file_info.compression_method;
-
-    if (level!=NULL)
-    {
-        *level = 6;
-        switch (s->cur_file_info.flag & 0x06)
-        {
-          case 6 : *level = 1; break;
-          case 4 : *level = 2; break;
-          case 2 : *level = 9; break;
-        }
-    }
-
-    if ((s->cur_file_info.compression_method!=0) &&
-        (s->cur_file_info.compression_method!=Z_DEFLATED))
-        err=UNZ_BADZIPFILE;
-
-    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
-    pfile_in_zip_read_info->crc32=0;
-    pfile_in_zip_read_info->compression_method =
-            s->cur_file_info.compression_method;
-    pfile_in_zip_read_info->filestream=s->filestream;
-    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
-    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
-    pfile_in_zip_read_info->stream.total_out = 0;
-
-    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
-        (!raw))
-    {
-      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
-      pfile_in_zip_read_info->stream.zfree = (free_func)0;
-      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
-      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
-      pfile_in_zip_read_info->stream.avail_in = 0;
-
-      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
-      if (err == Z_OK)
-        pfile_in_zip_read_info->stream_initialised=1;
-      else
-        return err;
-        /* windowBits is passed < 0 to tell that there is no zlib header.
-         * Note that in this case inflate *requires* an extra "dummy" byte
-         * after the compressed stream in order to complete decompression and
-         * return Z_STREAM_END.
-         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
-         * size of both compressed and uncompressed data
-         */
-    }
-    pfile_in_zip_read_info->rest_read_compressed =
-            s->cur_file_info.compressed_size ;
-    pfile_in_zip_read_info->rest_read_uncompressed =
-            s->cur_file_info.uncompressed_size ;
-
-
-    pfile_in_zip_read_info->pos_in_zipfile =
-            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
-              iSizeVar;
-
-    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
-    s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-#    ifndef NOUNCRYPT
-    if (password != NULL)
-    {
-        int i;
-        s->pcrc_32_tab = get_crc_table();
-        init_keys(password,s->keys,s->pcrc_32_tab);
-        if (ZSEEK(s->z_filefunc, s->filestream,
-                  s->pfile_in_zip_read->pos_in_zipfile +
-                     s->pfile_in_zip_read->byte_before_the_zipfile,
-                  SEEK_SET)!=0)
-            return UNZ_INTERNALERROR;
-        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
-            return UNZ_INTERNALERROR;
-
-        for (i = 0; i<12; i++)
-            zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
-        s->pfile_in_zip_read->pos_in_zipfile+=12;
-        s->encrypted=1;
-    }
-#    endif
-
-
-    return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
-    unzFile file;
-{
-    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
-    unzFile file;
-    const char* password;
-{
-    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
-    unzFile file;
-    int* method;
-    int* level;
-    int raw;
-{
-    return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
-  Read bytes from the current file.
-  buf contain buffer where data must be copied
-  len the size of buf.
-
-  return the number of byte copied if somes bytes are copied
-  return 0 if the end of file was reached
-  return <0 with error code if there is an error
-    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
-    unzFile file;
-    voidp buf;
-    unsigned len;
-{
-    int err=UNZ_OK;
-    uInt iRead = 0;
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-
-    if ((pfile_in_zip_read_info->read_buffer == NULL))
-        return UNZ_END_OF_LIST_OF_FILE;
-    if (len==0)
-        return 0;
-
-    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
-    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
-    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
-        (!(pfile_in_zip_read_info->raw)))
-        pfile_in_zip_read_info->stream.avail_out =
-            (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)
-    {
-        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
-            (pfile_in_zip_read_info->rest_read_compressed>0))
-        {
-            uInt uReadThis = UNZ_BUFSIZE;
-            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
-                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
-            if (uReadThis == 0)
-                return UNZ_EOF;
-            if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
-                      pfile_in_zip_read_info->filestream,
-                      pfile_in_zip_read_info->pos_in_zipfile +
-                         pfile_in_zip_read_info->byte_before_the_zipfile,
-                         ZLIB_FILEFUNC_SEEK_SET)!=0)
-                return UNZ_ERRNO;
-            if (ZREAD(pfile_in_zip_read_info->z_filefunc,
-                      pfile_in_zip_read_info->filestream,
-                      pfile_in_zip_read_info->read_buffer,
-                      uReadThis)!=uReadThis)
-                return UNZ_ERRNO;
-
-
-#            ifndef NOUNCRYPT
-            if(s->encrypted)
-            {
-                uInt i;
-                for(i=0;i<uReadThis;i++)
-                  pfile_in_zip_read_info->read_buffer[i] =
-                      zdecode(s->keys,s->pcrc_32_tab,
-                              pfile_in_zip_read_info->read_buffer[i]);
-            }
-#            endif
-
-
-            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
-            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
-            pfile_in_zip_read_info->stream.next_in =
-                (Bytef*)pfile_in_zip_read_info->read_buffer;
-            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
-        }
-
-        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
-        {
-            uInt uDoCopy,i ;
-
-            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
-                (pfile_in_zip_read_info->rest_read_compressed == 0))
-                return (iRead==0) ? UNZ_EOF : iRead;
-
-            if (pfile_in_zip_read_info->stream.avail_out <
-                            pfile_in_zip_read_info->stream.avail_in)
-                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
-            else
-                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
-            for (i=0;i<uDoCopy;i++)
-                *(pfile_in_zip_read_info->stream.next_out+i) =
-                        *(pfile_in_zip_read_info->stream.next_in+i);
-
-            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
-                                pfile_in_zip_read_info->stream.next_out,
-                                uDoCopy);
-            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
-            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
-            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
-            pfile_in_zip_read_info->stream.next_out += uDoCopy;
-            pfile_in_zip_read_info->stream.next_in += uDoCopy;
-            pfile_in_zip_read_info->stream.total_out += uDoCopy;
-            iRead += uDoCopy;
-        }
-        else
-        {
-            uLong uTotalOutBefore,uTotalOutAfter;
-            const Bytef *bufBefore;
-            uLong uOutThis;
-            int flush=Z_SYNC_FLUSH;
-
-            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
-            bufBefore = pfile_in_zip_read_info->stream.next_out;
-
-            /*
-            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
-                     pfile_in_zip_read_info->stream.avail_out) &&
-                (pfile_in_zip_read_info->rest_read_compressed == 0))
-                flush = Z_FINISH;
-            */
-            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;
-            uOutThis = uTotalOutAfter-uTotalOutBefore;
-
-            pfile_in_zip_read_info->crc32 =
-                crc32(pfile_in_zip_read_info->crc32,bufBefore,
-                        (uInt)(uOutThis));
-
-            pfile_in_zip_read_info->rest_read_uncompressed -=
-                uOutThis;
-
-            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
-            if (err==Z_STREAM_END)
-                return (iRead==0) ? UNZ_EOF : iRead;
-            if (err!=Z_OK)
-                break;
-        }
-    }
-
-    if (err==Z_OK)
-        return iRead;
-    return err;
-}
-
-
-/*
-  Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
-    unzFile file;
-{
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
-  return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
-    unzFile file;
-{
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
-        return 1;
-    else
-        return 0;
-}
-
-
-
-/*
-  Read extra field from the current file (opened by unzOpenCurrentFile)
-  This is the local-header version of the extra field (sometimes, there is
-    more info in the local-header version than in the central-header)
-
-  if buf==NULL, it return the size of the local extra field that can be read
-
-  if buf!=NULL, len is the size of the buffer, the extra header is copied in
-    buf.
-  the return value is the number of bytes copied in buf, or (if <0)
-    the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
-    unzFile file;
-    voidp buf;
-    unsigned len;
-{
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    uInt read_now;
-    uLong size_to_read;
-
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
-                pfile_in_zip_read_info->pos_local_extrafield);
-
-    if (buf==NULL)
-        return (int)size_to_read;
-
-    if (len>size_to_read)
-        read_now = (uInt)size_to_read;
-    else
-        read_now = (uInt)len ;
-
-    if (read_now==0)
-        return 0;
-
-    if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
-              pfile_in_zip_read_info->filestream,
-              pfile_in_zip_read_info->offset_local_extrafield +
-              pfile_in_zip_read_info->pos_local_extrafield,
-              ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-    if (ZREAD(pfile_in_zip_read_info->z_filefunc,
-              pfile_in_zip_read_info->filestream,
-              buf,read_now)!=read_now)
-        return UNZ_ERRNO;
-
-    return (int)read_now;
-}
-
-/*
-  Close the file in zip opened with unzipOpenCurrentFile
-  Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
-    unzFile file;
-{
-    int err=UNZ_OK;
-
-    unz_s* s;
-    file_in_zip_read_info_s* pfile_in_zip_read_info;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-    pfile_in_zip_read_info=s->pfile_in_zip_read;
-
-    if (pfile_in_zip_read_info==NULL)
-        return UNZ_PARAMERROR;
-
-
-    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
-        (!pfile_in_zip_read_info->raw))
-    {
-        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
-            err=UNZ_CRCERROR;
-    }
-
-
-    TRYFREE(pfile_in_zip_read_info->read_buffer);
-    pfile_in_zip_read_info->read_buffer = NULL;
-    if (pfile_in_zip_read_info->stream_initialised)
-        inflateEnd(&pfile_in_zip_read_info->stream);
-
-    pfile_in_zip_read_info->stream_initialised = 0;
-    TRYFREE(pfile_in_zip_read_info);
-
-    s->pfile_in_zip_read=NULL;
-
-    return err;
-}
-
-
-/*
-  Get the global comment string of the ZipFile, in the szComment buffer.
-  uSizeBuf is the size of the szComment buffer.
-  return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
-    unzFile file;
-    char *szComment;
-    uLong uSizeBuf;
-{
-    int err=UNZ_OK;
-    unz_s* s;
-    uLong uReadThis ;
-    if (file==NULL)
-        return UNZ_PARAMERROR;
-    s=(unz_s*)file;
-
-    uReadThis = uSizeBuf;
-    if (uReadThis>s->gi.size_comment)
-        uReadThis = s->gi.size_comment;
-
-    if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
-        return UNZ_ERRNO;
-
-    if (uReadThis>0)
-    {
-      *szComment='\0';
-      if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
-        return UNZ_ERRNO;
-    }
-
-    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
-        *(szComment+s->gi.size_comment)='\0';
-    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;
-}
+/* unzip.c -- IO for uncompress .zip files using zlib

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+

+   Read unzip.h for more info

+*/

+

+/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of

+compatibility with older software. The following is from the original crypt.c. Code

+woven in by Terry Thorsen 1/2003.

+*/

+/*

+  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.

+

+  See the accompanying file LICENSE, version 2000-Apr-09 or later

+  (the contents of which are also included in zip.h) for terms of use.

+  If, for some reason, all these files are missing, the Info-ZIP license

+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html

+*/

+/*

+  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]

+

+  The encryption/decryption parts of this source code (as opposed to the

+  non-echoing password parts) were originally written in Europe.  The

+  whole source package can be freely distributed, including from the USA.

+  (Prior to January 2000, re-export from the US was a violation of US law.)

+ */

+

+/*

+  This encryption code is a direct transcription of the algorithm from

+  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This

+  file (appnote.txt) is distributed with the PKZIP program (even in the

+  version without encryption capabilities).

+ */

+

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include "zlib.h"

+#include "unzip.h"

+

+#ifdef STDC

+#  include <stddef.h>

+#  include <string.h>

+#  include <stdlib.h>

+#endif

+#ifdef NO_ERRNO_H

+    extern int errno;

+#else

+#   include <errno.h>

+#endif

+

+

+#ifndef local

+#  define local static

+#endif

+/* compile with -Dlocal if your debugger can't find static symbols */

+

+

+#ifndef CASESENSITIVITYDEFAULT_NO

+#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)

+#    define CASESENSITIVITYDEFAULT_NO

+#  endif

+#endif

+

+

+#ifndef UNZ_BUFSIZE

+#define UNZ_BUFSIZE (16384)

+#endif

+

+#ifndef UNZ_MAXFILENAMEINZIP

+#define UNZ_MAXFILENAMEINZIP (256)

+#endif

+

+#ifndef ALLOC

+# define ALLOC(size) (malloc(size))

+#endif

+#ifndef TRYFREE

+# define TRYFREE(p) {if (p) free(p);}

+#endif

+

+#define SIZECENTRALDIRITEM (0x2e)

+#define SIZEZIPLOCALHEADER (0x1e)

+

+

+

+

+const char unz_copyright[] =

+   " 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*/

+typedef struct unz_file_info_internal_s

+{

+    uLong offset_curfile;/* relative offset of local header 4 bytes */

+} unz_file_info_internal;

+

+

+/* file_in_zip_read_info_s contain internal information about a file in zipfile,

+    when reading and decompress it */

+typedef struct

+{

+    char  *read_buffer;         /* internal buffer for compressed data */

+    z_stream stream;            /* zLib stream structure for inflate */

+

+    uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/

+    uLong stream_initialised;   /* flag set if stream structure is initialised*/

+

+    uLong offset_local_extrafield;/* offset of the local extra field */

+    uInt  size_local_extrafield;/* size of the local extra field */

+    uLong pos_local_extrafield;   /* position in the local extra field in read*/

+

+    uLong crc32;                /* crc32 of all data uncompressed */

+    uLong crc32_wait;           /* crc32 we must obtain after decompress all */

+    uLong rest_read_compressed; /* number of byte to be decompressed */

+    uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/

+    zlib_filefunc_def z_filefunc;

+    voidpf filestream;        /* io structore of the zipfile */

+    uLong compression_method;   /* compression method (0==store) */

+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/

+    int   raw;

+} file_in_zip_read_info_s;

+

+

+/* unz_s contain internal information about the zipfile

+*/

+typedef struct

+{

+    zlib_filefunc_def z_filefunc;

+    voidpf filestream;        /* io structore of the zipfile */

+    unz_global_info gi;       /* public global information */

+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/

+    uLong num_file;             /* number of the current file in the zipfile*/

+    uLong pos_in_central_dir;   /* pos of the current file in the central dir*/

+    uLong current_file_ok;      /* flag about the usability of the current file*/

+    uLong central_pos;          /* position of the beginning of the central dir*/

+

+    uLong size_central_dir;     /* size of the central directory  */

+    uLong offset_central_dir;   /* offset of start of central directory with

+                                   respect to the starting disk number */

+

+    unz_file_info cur_file_info; /* public info about the current file in zip*/

+    unz_file_info_internal cur_file_info_internal; /* private info about it*/

+    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current

+                                        file if we are decompressing it */

+    int encrypted;

+#    ifndef NOUNCRYPT

+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */

+    const unsigned long* pcrc_32_tab;

+#    endif

+} unz_s;

+

+

+#ifndef NOUNCRYPT

+#include "crypt.h"

+#endif

+

+/* ===========================================================================

+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF

+   for end of file.

+   IN assertion: the stream s has been sucessfully opened for reading.

+*/

+

+

+local int unzlocal_getByte OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    int *pi));

+

+local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    int *pi;

+{

+    unsigned char c;

+    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);

+    if (err==1)

+    {

+        *pi = (int)c;

+        return UNZ_OK;

+    }

+    else

+    {

+        if (ZERROR(*pzlib_filefunc_def,filestream))

+            return UNZ_ERRNO;

+        else

+            return UNZ_EOF;

+    }

+}

+

+

+/* ===========================================================================

+   Reads a long in LSB order from the given gz_stream. Sets

+*/

+local int unzlocal_getShort OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    uLong *pX));

+

+local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    uLong *pX;

+{

+    uLong x ;

+    int i;

+    int err;

+

+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x = (uLong)i;

+

+    if (err==UNZ_OK)

+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<8;

+

+    if (err==UNZ_OK)

+        *pX = x;

+    else

+        *pX = 0;

+    return err;

+}

+

+local int unzlocal_getLong OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    uLong *pX));

+

+local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    uLong *pX;

+{

+    uLong x ;

+    int i;

+    int err;

+

+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x = (uLong)i;

+

+    if (err==UNZ_OK)

+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<8;

+

+    if (err==UNZ_OK)

+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<16;

+

+    if (err==UNZ_OK)

+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<24;

+

+    if (err==UNZ_OK)

+        *pX = x;

+    else

+        *pX = 0;

+    return err;

+}

+

+

+/* My own strcmpi / strcasecmp */

+local int strcmpcasenosensitive_internal (fileName1,fileName2)

+    const char* fileName1;

+    const char* fileName2;

+{

+    for (;;)

+    {

+        char c1=*(fileName1++);

+        char c2=*(fileName2++);

+        if ((c1>='a') && (c1<='z'))

+            c1 -= 0x20;

+        if ((c2>='a') && (c2<='z'))

+            c2 -= 0x20;

+        if (c1=='\0')

+            return ((c2=='\0') ? 0 : -1);

+        if (c2=='\0')

+            return 1;

+        if (c1<c2)

+            return -1;

+        if (c1>c2)

+            return 1;

+    }

+}

+

+

+#ifdef  CASESENSITIVITYDEFAULT_NO

+#define CASESENSITIVITYDEFAULTVALUE 2

+#else

+#define CASESENSITIVITYDEFAULTVALUE 1

+#endif

+

+#ifndef STRCMPCASENOSENTIVEFUNCTION

+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal

+#endif

+

+/*

+   Compare two filename (fileName1,fileName2).

+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)

+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi

+                                                                or strcasecmp)

+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system

+        (like 1 on Unix, 2 on Windows)

+

+*/

+extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)

+    const char* fileName1;

+    const char* fileName2;

+    int iCaseSensitivity;

+{

+    if (iCaseSensitivity==0)

+        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;

+

+    if (iCaseSensitivity==1)

+        return strcmp(fileName1,fileName2);

+

+    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);

+}

+

+#ifndef BUFREADCOMMENT

+#define BUFREADCOMMENT (0x400)

+#endif

+

+/*

+  Locate the Central directory of a zipfile (at the end, just before

+    the global comment)

+*/

+local uLong unzlocal_SearchCentralDir OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream));

+

+local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+{

+    unsigned char* buf;

+    uLong uSizeFile;

+    uLong uBackRead;

+    uLong uMaxBack=0xffff; /* maximum size of global comment */

+    uLong uPosFound=0;

+

+    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)

+        return 0;

+

+

+    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);

+

+    if (uMaxBack>uSizeFile)

+        uMaxBack = uSizeFile;

+

+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);

+    if (buf==NULL)

+        return 0;

+

+    uBackRead = 4;

+    while (uBackRead<uMaxBack)

+    {

+        uLong uReadSize,uReadPos ;

+        int i;

+        if (uBackRead+BUFREADCOMMENT>uMaxBack)

+            uBackRead = uMaxBack;

+        else

+            uBackRead+=BUFREADCOMMENT;

+        uReadPos = uSizeFile-uBackRead ;

+

+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?

+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);

+        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            break;

+

+        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)

+            break;

+

+        for (i=(int)uReadSize-3; (i--)>0;)

+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&

+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))

+            {

+                uPosFound = uReadPos+i;

+                break;

+            }

+

+        if (uPosFound!=0)

+            break;

+    }

+    TRYFREE(buf);

+    return uPosFound;

+}

+

+/*

+  Open a Zip file. path contain the full pathname (by example,

+     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer

+     "zlib/zlib114.zip".

+     If the zipfile cannot be opened (file doesn't exist or in not valid), the

+       return value is NULL.

+     Else, the return value is a unzFile Handle, usable with other function

+       of this unzip package.

+*/

+extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)

+    const char *path;

+    zlib_filefunc_def* pzlib_filefunc_def;

+{

+    unz_s us;

+    unz_s *s;

+    uLong central_pos,uL;

+

+    uLong number_disk;          /* number of the current dist, used for

+                                   spaning ZIP, unsupported, always 0*/

+    uLong number_disk_with_CD;  /* number the the disk with central dir, used

+                                   for spaning ZIP, unsupported, always 0*/

+    uLong number_entry_CD;      /* total number of entries in

+                                   the central dir

+                                   (same than number_entry on nospan) */

+

+    int err=UNZ_OK;

+

+    if (unz_copyright[0]!=' ')

+        return NULL;

+

+    if (pzlib_filefunc_def==NULL)

+        fill_fopen_filefunc(&us.z_filefunc);

+    else

+        us.z_filefunc = *pzlib_filefunc_def;

+

+    us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,

+                                                 path,

+                                                 ZLIB_FILEFUNC_MODE_READ |

+                                                 ZLIB_FILEFUNC_MODE_EXISTING);

+    if (us.filestream==NULL)

+        return NULL;

+

+    central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);

+    if (central_pos==0)

+        err=UNZ_ERRNO;

+

+    if (ZSEEK(us.z_filefunc, us.filestream,

+                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)

+        err=UNZ_ERRNO;

+

+    /* the signature, already checked */

+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* number of this disk */

+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* number of the disk with the start of the central directory */

+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* total number of entries in the central dir on this disk */

+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* total number of entries in the central dir */

+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if ((number_entry_CD!=us.gi.number_entry) ||

+        (number_disk_with_CD!=0) ||

+        (number_disk!=0))

+        err=UNZ_BADZIPFILE;

+

+    /* size of the central directory */

+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* offset of start of central directory with respect to the

+          starting disk number */

+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    /* zipfile comment length */

+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&

+        (err==UNZ_OK))

+        err=UNZ_BADZIPFILE;

+

+    if (err!=UNZ_OK)

+    {

+        ZCLOSE(us.z_filefunc, us.filestream);

+        return NULL;

+    }

+

+    us.byte_before_the_zipfile = central_pos -

+                            (us.offset_central_dir+us.size_central_dir);

+    us.central_pos = central_pos;

+    us.pfile_in_zip_read = NULL;

+    us.encrypted = 0;

+

+

+    s=(unz_s*)ALLOC(sizeof(unz_s));

+    *s=us;

+    unzGoToFirstFile((unzFile)s);

+    return (unzFile)s;

+}

+

+

+extern unzFile ZEXPORT unzOpen (path)

+    const char *path;

+{

+    return unzOpen2(path, NULL);

+}

+

+/*

+  Close a ZipFile opened with unzipOpen.

+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),

+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.

+  return UNZ_OK if there is no problem. */

+extern int ZEXPORT unzClose (file)

+    unzFile file;

+{

+    unz_s* s;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+

+    if (s->pfile_in_zip_read!=NULL)

+        unzCloseCurrentFile(file);

+

+    ZCLOSE(s->z_filefunc, s->filestream);

+    TRYFREE(s);

+    return UNZ_OK;

+}

+

+

+/*

+  Write info about the ZipFile in the *pglobal_info structure.

+  No preparation of the structure is needed

+  return UNZ_OK if there is no problem. */

+extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)

+    unzFile file;

+    unz_global_info *pglobal_info;

+{

+    unz_s* s;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    *pglobal_info=s->gi;

+    return UNZ_OK;

+}

+

+

+/*

+   Translate date/time from Dos format to tm_unz (readable more easilty)

+*/

+local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)

+    uLong ulDosDate;

+    tm_unz* ptm;

+{

+    uLong uDate;

+    uDate = (uLong)(ulDosDate>>16);

+    ptm->tm_mday = (uInt)(uDate&0x1f) ;

+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;

+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;

+

+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);

+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;

+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;

+}

+

+/*

+  Get Info about the current file in the zipfile, with internal only info

+*/

+local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,

+                                                  unz_file_info *pfile_info,

+                                                  unz_file_info_internal

+                                                  *pfile_info_internal,

+                                                  char *szFileName,

+                                                  uLong fileNameBufferSize,

+                                                  void *extraField,

+                                                  uLong extraFieldBufferSize,

+                                                  char *szComment,

+                                                  uLong commentBufferSize));

+

+local int unzlocal_GetCurrentFileInfoInternal (file,

+                                              pfile_info,

+                                              pfile_info_internal,

+                                              szFileName, fileNameBufferSize,

+                                              extraField, extraFieldBufferSize,

+                                              szComment,  commentBufferSize)

+    unzFile file;

+    unz_file_info *pfile_info;

+    unz_file_info_internal *pfile_info_internal;

+    char *szFileName;

+    uLong fileNameBufferSize;

+    void *extraField;

+    uLong extraFieldBufferSize;

+    char *szComment;

+    uLong commentBufferSize;

+{

+    unz_s* s;

+    unz_file_info file_info;

+    unz_file_info_internal file_info_internal;

+    int err=UNZ_OK;

+    uLong uMagic;

+    long lSeek=0;

+

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    if (ZSEEK(s->z_filefunc, s->filestream,

+              s->pos_in_central_dir+s->byte_before_the_zipfile,

+              ZLIB_FILEFUNC_SEEK_SET)!=0)

+        err=UNZ_ERRNO;

+

+

+    /* we check the magic */

+    if (err==UNZ_OK)

+        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)

+            err=UNZ_ERRNO;

+        else if (uMagic!=0x02014b50)

+            err=UNZ_BADZIPFILE;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    lSeek+=file_info.size_filename;

+    if ((err==UNZ_OK) && (szFileName!=NULL))

+    {

+        uLong uSizeRead ;

+        if (file_info.size_filename<fileNameBufferSize)

+        {

+            *(szFileName+file_info.size_filename)='\0';

+            uSizeRead = file_info.size_filename;

+        }

+        else

+            uSizeRead = fileNameBufferSize;

+

+        if ((file_info.size_filename>0) && (fileNameBufferSize>0))

+            if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)

+                err=UNZ_ERRNO;

+        lSeek -= uSizeRead;

+    }

+

+

+    if ((err==UNZ_OK) && (extraField!=NULL))

+    {

+        uLong uSizeRead ;

+        if (file_info.size_file_extra<extraFieldBufferSize)

+            uSizeRead = file_info.size_file_extra;

+        else

+            uSizeRead = extraFieldBufferSize;

+

+        if (lSeek!=0)

+            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)

+                lSeek=0;

+            else

+                err=UNZ_ERRNO;

+        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))

+            if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)

+                err=UNZ_ERRNO;

+        lSeek += file_info.size_file_extra - uSizeRead;

+    }

+    else

+        lSeek+=file_info.size_file_extra;

+

+

+    if ((err==UNZ_OK) && (szComment!=NULL))

+    {

+        uLong uSizeRead ;

+        if (file_info.size_file_comment<commentBufferSize)

+        {

+            *(szComment+file_info.size_file_comment)='\0';

+            uSizeRead = file_info.size_file_comment;

+        }

+        else

+            uSizeRead = commentBufferSize;

+

+        if (lSeek!=0)

+            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)

+                lSeek=0;

+            else

+                err=UNZ_ERRNO;

+        if ((file_info.size_file_comment>0) && (commentBufferSize>0))

+            if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)

+                err=UNZ_ERRNO;

+        lSeek+=file_info.size_file_comment - uSizeRead;

+    }

+    else

+        lSeek+=file_info.size_file_comment;

+

+    if ((err==UNZ_OK) && (pfile_info!=NULL))

+        *pfile_info=file_info;

+

+    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))

+        *pfile_info_internal=file_info_internal;

+

+    return err;

+}

+

+

+

+/*

+  Write info about the ZipFile in the *pglobal_info structure.

+  No preparation of the structure is needed

+  return UNZ_OK if there is no problem.

+*/

+extern int ZEXPORT unzGetCurrentFileInfo (file,

+                                          pfile_info,

+                                          szFileName, fileNameBufferSize,

+                                          extraField, extraFieldBufferSize,

+                                          szComment,  commentBufferSize)

+    unzFile file;

+    unz_file_info *pfile_info;

+    char *szFileName;

+    uLong fileNameBufferSize;

+    void *extraField;

+    uLong extraFieldBufferSize;

+    char *szComment;

+    uLong commentBufferSize;

+{

+    return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,

+                                                szFileName,fileNameBufferSize,

+                                                extraField,extraFieldBufferSize,

+                                                szComment,commentBufferSize);

+}

+

+/*

+  Set the current file of the zipfile to the first file.

+  return UNZ_OK if there is no problem

+*/

+extern int ZEXPORT unzGoToFirstFile (file)

+    unzFile file;

+{

+    int err=UNZ_OK;

+    unz_s* s;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    s->pos_in_central_dir=s->offset_central_dir;

+    s->num_file=0;

+    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;

+}

+

+/*

+  Set the current file of the zipfile to the next file.

+  return UNZ_OK if there is no problem

+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.

+*/

+extern int ZEXPORT unzGoToNextFile (file)

+    unzFile file;

+{

+    unz_s* s;

+    int err;

+

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    if (!s->current_file_ok)

+        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)

+        return UNZ_END_OF_LIST_OF_FILE;

+

+    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +

+            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;

+    s->num_file++;

+    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;

+}

+

+

+/*

+  Try locate the file szFileName in the zipfile.

+  For the iCaseSensitivity signification, see unzipStringFileNameCompare

+

+  return value :

+  UNZ_OK if the file is found. It becomes the current file.

+  UNZ_END_OF_LIST_OF_FILE if the file is not found

+*/

+extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)

+    unzFile file;

+    const char *szFileName;

+    int iCaseSensitivity;

+{

+    unz_s* s;

+    int err;

+

+    /* We remember the 'current' position in the file so that we can jump

+     * back there if we fail.

+     */

+    unz_file_info cur_file_infoSaved;

+    unz_file_info_internal cur_file_info_internalSaved;

+    uLong num_fileSaved;

+    uLong pos_in_central_dirSaved;

+

+

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+

+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)

+        return UNZ_PARAMERROR;

+

+    s=(unz_s*)file;

+    if (!s->current_file_ok)

+        return UNZ_END_OF_LIST_OF_FILE;

+

+    /* Save the current state */

+    num_fileSaved = s->num_file;

+    pos_in_central_dirSaved = s->pos_in_central_dir;

+    cur_file_infoSaved = s->cur_file_info;

+    cur_file_info_internalSaved = s->cur_file_info_internal;

+

+    err = unzGoToFirstFile(file);

+

+    while (err == UNZ_OK)

+    {

+        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];

+        err = unzGetCurrentFileInfo(file,NULL,

+                                    szCurrentFileName,sizeof(szCurrentFileName)-1,

+                                    NULL,0,NULL,0);

+        if (err == UNZ_OK)

+        {

+            if (unzStringFileNameCompare(szCurrentFileName,

+                                            szFileName,iCaseSensitivity)==0)

+                return UNZ_OK;

+            err = unzGoToNextFile(file);

+        }

+    }

+

+    /* We failed, so restore the state of the 'current file' to where we

+     * were.

+     */

+    s->num_file = num_fileSaved ;

+    s->pos_in_central_dir = pos_in_central_dirSaved ;

+    s->cur_file_info = cur_file_infoSaved;

+    s->cur_file_info_internal = cur_file_info_internalSaved;

+    return err;

+}

+

+

+/*

+///////////////////////////////////////////

+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)

+// I need random access

+//

+// Further optimization could be realized by adding an ability

+// to cache the directory in memory. The goal being a single

+// comprehensive file read to put the file I need in a memory.

+*/

+

+/*

+typedef struct unz_file_pos_s

+{

+    uLong pos_in_zip_directory;   // offset in file

+    uLong num_of_file;            // # of file

+} unz_file_pos;

+*/

+

+extern int ZEXPORT unzGetFilePos(file, file_pos)

+    unzFile file;

+    unz_file_pos* file_pos;

+{

+    unz_s* s;

+

+    if (file==NULL || file_pos==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    if (!s->current_file_ok)

+        return UNZ_END_OF_LIST_OF_FILE;

+

+    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;

+    file_pos->num_of_file           = s->num_file;

+

+    return UNZ_OK;

+}

+

+extern int ZEXPORT unzGoToFilePos(file, file_pos)

+    unzFile file;

+    unz_file_pos* file_pos;

+{

+    unz_s* s;

+    int err;

+

+    if (file==NULL || file_pos==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+

+    /* jump to the right spot */

+    s->pos_in_central_dir = file_pos->pos_in_zip_directory;

+    s->num_file           = file_pos->num_of_file;

+

+    /* set the current file */

+    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,

+                                               &s->cur_file_info_internal,

+                                               NULL,0,NULL,0,NULL,0);

+    /* return results */

+    s->current_file_ok = (err == UNZ_OK);

+    return err;

+}

+

+/*

+// Unzip Helper Functions - should be here?

+///////////////////////////////////////////

+*/

+

+/*

+  Read the local header of the current zipfile

+  Check the coherency of the local header and info in the end of central

+        directory about this file

+  store in *piSizeVar the size of extra info in local header

+        (filename and size of extra field data)

+*/

+local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,

+                                                    poffset_local_extrafield,

+                                                    psize_local_extrafield)

+    unz_s* s;

+    uInt* piSizeVar;

+    uLong *poffset_local_extrafield;

+    uInt  *psize_local_extrafield;

+{

+    uLong uMagic,uData,uFlags;

+    uLong size_filename;

+    uLong size_extra_field;

+    int err=UNZ_OK;

+

+    *piSizeVar = 0;

+    *poffset_local_extrafield = 0;

+    *psize_local_extrafield = 0;

+

+    if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +

+                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)

+        return UNZ_ERRNO;

+

+

+    if (err==UNZ_OK)

+        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)

+            err=UNZ_ERRNO;

+        else if (uMagic!=0x04034b50)

+            err=UNZ_BADZIPFILE;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)

+        err=UNZ_ERRNO;

+/*

+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))

+        err=UNZ_BADZIPFILE;

+*/

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)

+        err=UNZ_ERRNO;

+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))

+        err=UNZ_BADZIPFILE;

+

+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&

+                         (s->cur_file_info.compression_method!=Z_DEFLATED))

+        err=UNZ_BADZIPFILE;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */

+        err=UNZ_ERRNO;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */

+        err=UNZ_ERRNO;

+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&

+                              ((uFlags & 8)==0))

+        err=UNZ_BADZIPFILE;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */

+        err=UNZ_ERRNO;

+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&

+                              ((uFlags & 8)==0))

+        err=UNZ_BADZIPFILE;

+

+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */

+        err=UNZ_ERRNO;

+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&

+                              ((uFlags & 8)==0))

+        err=UNZ_BADZIPFILE;

+

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)

+        err=UNZ_ERRNO;

+    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))

+        err=UNZ_BADZIPFILE;

+

+    *piSizeVar += (uInt)size_filename;

+

+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)

+        err=UNZ_ERRNO;

+    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +

+                                    SIZEZIPLOCALHEADER + size_filename;

+    *psize_local_extrafield = (uInt)size_extra_field;

+

+    *piSizeVar += (uInt)size_extra_field;

+

+    return err;

+}

+

+/*

+  Open for reading data the current file in the zipfile.

+  If there is no error and the file is opened, the return value is UNZ_OK.

+*/

+extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)

+    unzFile file;

+    int* method;

+    int* level;

+    int raw;

+    const char* password;

+{

+    int err=UNZ_OK;

+    uInt iSizeVar;

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    uLong offset_local_extrafield;  /* offset of the local extra field */

+    uInt  size_local_extrafield;    /* size of the local extra field */

+#    ifndef NOUNCRYPT

+    char source[12];

+#    else

+    if (password != NULL)

+        return UNZ_PARAMERROR;

+#    endif

+

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    if (!s->current_file_ok)

+        return UNZ_PARAMERROR;

+

+    if (s->pfile_in_zip_read != NULL)

+        unzCloseCurrentFile(file);

+

+    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,

+                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)

+        return UNZ_BADZIPFILE;

+

+    pfile_in_zip_read_info = (file_in_zip_read_info_s*)

+                                        ALLOC(sizeof(file_in_zip_read_info_s));

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_INTERNALERROR;

+

+    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);

+    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;

+    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;

+    pfile_in_zip_read_info->pos_local_extrafield=0;

+    pfile_in_zip_read_info->raw=raw;

+

+    if (pfile_in_zip_read_info->read_buffer==NULL)

+    {

+        TRYFREE(pfile_in_zip_read_info);

+        return UNZ_INTERNALERROR;

+    }

+

+    pfile_in_zip_read_info->stream_initialised=0;

+

+    if (method!=NULL)

+        *method = (int)s->cur_file_info.compression_method;

+

+    if (level!=NULL)

+    {

+        *level = 6;

+        switch (s->cur_file_info.flag & 0x06)

+        {

+          case 6 : *level = 1; break;

+          case 4 : *level = 2; break;

+          case 2 : *level = 9; break;

+        }

+    }

+

+    if ((s->cur_file_info.compression_method!=0) &&

+        (s->cur_file_info.compression_method!=Z_DEFLATED))

+        err=UNZ_BADZIPFILE;

+

+    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;

+    pfile_in_zip_read_info->crc32=0;

+    pfile_in_zip_read_info->compression_method =

+            s->cur_file_info.compression_method;

+    pfile_in_zip_read_info->filestream=s->filestream;

+    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;

+    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;

+

+    pfile_in_zip_read_info->stream.total_out = 0;

+

+    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&

+        (!raw))

+    {

+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;

+      pfile_in_zip_read_info->stream.zfree = (free_func)0;

+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;

+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;

+      pfile_in_zip_read_info->stream.avail_in = 0;

+

+      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);

+      if (err == Z_OK)

+        pfile_in_zip_read_info->stream_initialised=1;

+      else

+      {

+        TRYFREE(pfile_in_zip_read_info);

+        return err;

+      }

+        /* windowBits is passed < 0 to tell that there is no zlib header.

+         * Note that in this case inflate *requires* an extra "dummy" byte

+         * after the compressed stream in order to complete decompression and

+         * return Z_STREAM_END.

+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the

+         * size of both compressed and uncompressed data

+         */

+    }

+    pfile_in_zip_read_info->rest_read_compressed =

+            s->cur_file_info.compressed_size ;

+    pfile_in_zip_read_info->rest_read_uncompressed =

+            s->cur_file_info.uncompressed_size ;

+

+

+    pfile_in_zip_read_info->pos_in_zipfile =

+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +

+              iSizeVar;

+

+    pfile_in_zip_read_info->stream.avail_in = (uInt)0;

+

+    s->pfile_in_zip_read = pfile_in_zip_read_info;

+

+#    ifndef NOUNCRYPT

+    if (password != NULL)

+    {

+        int i;

+        s->pcrc_32_tab = get_crc_table();

+        init_keys(password,s->keys,s->pcrc_32_tab);

+        if (ZSEEK(s->z_filefunc, s->filestream,

+                  s->pfile_in_zip_read->pos_in_zipfile +

+                     s->pfile_in_zip_read->byte_before_the_zipfile,

+                  SEEK_SET)!=0)

+            return UNZ_INTERNALERROR;

+        if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)

+            return UNZ_INTERNALERROR;

+

+        for (i = 0; i<12; i++)

+            zdecode(s->keys,s->pcrc_32_tab,source[i]);

+

+        s->pfile_in_zip_read->pos_in_zipfile+=12;

+        s->encrypted=1;

+    }

+#    endif

+

+

+    return UNZ_OK;

+}

+

+extern int ZEXPORT unzOpenCurrentFile (file)

+    unzFile file;

+{

+    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);

+}

+

+extern int ZEXPORT unzOpenCurrentFilePassword (file, password)

+    unzFile file;

+    const char* password;

+{

+    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);

+}

+

+extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)

+    unzFile file;

+    int* method;

+    int* level;

+    int raw;

+{

+    return unzOpenCurrentFile3(file, method, level, raw, NULL);

+}

+

+/*

+  Read bytes from the current file.

+  buf contain buffer where data must be copied

+  len the size of buf.

+

+  return the number of byte copied if somes bytes are copied

+  return 0 if the end of file was reached

+  return <0 with error code if there is an error

+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)

+*/

+extern int ZEXPORT unzReadCurrentFile  (file, buf, len)

+    unzFile file;

+    voidp buf;

+    unsigned len;

+{

+    int err=UNZ_OK;

+    uInt iRead = 0;

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    pfile_in_zip_read_info=s->pfile_in_zip_read;

+

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_PARAMERROR;

+

+

+    if ((pfile_in_zip_read_info->read_buffer == NULL))

+        return UNZ_END_OF_LIST_OF_FILE;

+    if (len==0)

+        return 0;

+

+    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;

+

+    pfile_in_zip_read_info->stream.avail_out = (uInt)len;

+

+    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&

+        (!(pfile_in_zip_read_info->raw)))

+        pfile_in_zip_read_info->stream.avail_out =

+            (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)

+    {

+        if ((pfile_in_zip_read_info->stream.avail_in==0) &&

+            (pfile_in_zip_read_info->rest_read_compressed>0))

+        {

+            uInt uReadThis = UNZ_BUFSIZE;

+            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)

+                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;

+            if (uReadThis == 0)

+                return UNZ_EOF;

+            if (ZSEEK(pfile_in_zip_read_info->z_filefunc,

+                      pfile_in_zip_read_info->filestream,

+                      pfile_in_zip_read_info->pos_in_zipfile +

+                         pfile_in_zip_read_info->byte_before_the_zipfile,

+                         ZLIB_FILEFUNC_SEEK_SET)!=0)

+                return UNZ_ERRNO;

+            if (ZREAD(pfile_in_zip_read_info->z_filefunc,

+                      pfile_in_zip_read_info->filestream,

+                      pfile_in_zip_read_info->read_buffer,

+                      uReadThis)!=uReadThis)

+                return UNZ_ERRNO;

+

+

+#            ifndef NOUNCRYPT

+            if(s->encrypted)

+            {

+                uInt i;

+                for(i=0;i<uReadThis;i++)

+                  pfile_in_zip_read_info->read_buffer[i] =

+                      zdecode(s->keys,s->pcrc_32_tab,

+                              pfile_in_zip_read_info->read_buffer[i]);

+            }

+#            endif

+

+

+            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

+

+            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;

+

+            pfile_in_zip_read_info->stream.next_in =

+                (Bytef*)pfile_in_zip_read_info->read_buffer;

+            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;

+        }

+

+        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))

+        {

+            uInt uDoCopy,i ;

+

+            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&

+                (pfile_in_zip_read_info->rest_read_compressed == 0))

+                return (iRead==0) ? UNZ_EOF : iRead;

+

+            if (pfile_in_zip_read_info->stream.avail_out <

+                            pfile_in_zip_read_info->stream.avail_in)

+                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;

+            else

+                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;

+

+            for (i=0;i<uDoCopy;i++)

+                *(pfile_in_zip_read_info->stream.next_out+i) =

+                        *(pfile_in_zip_read_info->stream.next_in+i);

+

+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,

+                                pfile_in_zip_read_info->stream.next_out,

+                                uDoCopy);

+            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;

+            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;

+            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;

+            pfile_in_zip_read_info->stream.next_out += uDoCopy;

+            pfile_in_zip_read_info->stream.next_in += uDoCopy;

+            pfile_in_zip_read_info->stream.total_out += uDoCopy;

+            iRead += uDoCopy;

+        }

+        else

+        {

+            uLong uTotalOutBefore,uTotalOutAfter;

+            const Bytef *bufBefore;

+            uLong uOutThis;

+            int flush=Z_SYNC_FLUSH;

+

+            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;

+            bufBefore = pfile_in_zip_read_info->stream.next_out;

+

+            /*

+            if ((pfile_in_zip_read_info->rest_read_uncompressed ==

+                     pfile_in_zip_read_info->stream.avail_out) &&

+                (pfile_in_zip_read_info->rest_read_compressed == 0))

+                flush = Z_FINISH;

+            */

+            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;

+            uOutThis = uTotalOutAfter-uTotalOutBefore;

+

+            pfile_in_zip_read_info->crc32 =

+                crc32(pfile_in_zip_read_info->crc32,bufBefore,

+                        (uInt)(uOutThis));

+

+            pfile_in_zip_read_info->rest_read_uncompressed -=

+                uOutThis;

+

+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);

+

+            if (err==Z_STREAM_END)

+                return (iRead==0) ? UNZ_EOF : iRead;

+            if (err!=Z_OK)

+                break;

+        }

+    }

+

+    if (err==Z_OK)

+        return iRead;

+    return err;

+}

+

+

+/*

+  Give the current position in uncompressed data

+*/

+extern z_off_t ZEXPORT unztell (file)

+    unzFile file;

+{

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    pfile_in_zip_read_info=s->pfile_in_zip_read;

+

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_PARAMERROR;

+

+    return (z_off_t)pfile_in_zip_read_info->stream.total_out;

+}

+

+

+/*

+  return 1 if the end of file was reached, 0 elsewhere

+*/

+extern int ZEXPORT unzeof (file)

+    unzFile file;

+{

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    pfile_in_zip_read_info=s->pfile_in_zip_read;

+

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_PARAMERROR;

+

+    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)

+        return 1;

+    else

+        return 0;

+}

+

+

+

+/*

+  Read extra field from the current file (opened by unzOpenCurrentFile)

+  This is the local-header version of the extra field (sometimes, there is

+    more info in the local-header version than in the central-header)

+

+  if buf==NULL, it return the size of the local extra field that can be read

+

+  if buf!=NULL, len is the size of the buffer, the extra header is copied in

+    buf.

+  the return value is the number of bytes copied in buf, or (if <0)

+    the error code

+*/

+extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)

+    unzFile file;

+    voidp buf;

+    unsigned len;

+{

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    uInt read_now;

+    uLong size_to_read;

+

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    pfile_in_zip_read_info=s->pfile_in_zip_read;

+

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_PARAMERROR;

+

+    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -

+                pfile_in_zip_read_info->pos_local_extrafield);

+

+    if (buf==NULL)

+        return (int)size_to_read;

+

+    if (len>size_to_read)

+        read_now = (uInt)size_to_read;

+    else

+        read_now = (uInt)len ;

+

+    if (read_now==0)

+        return 0;

+

+    if (ZSEEK(pfile_in_zip_read_info->z_filefunc,

+              pfile_in_zip_read_info->filestream,

+              pfile_in_zip_read_info->offset_local_extrafield +

+              pfile_in_zip_read_info->pos_local_extrafield,

+              ZLIB_FILEFUNC_SEEK_SET)!=0)

+        return UNZ_ERRNO;

+

+    if (ZREAD(pfile_in_zip_read_info->z_filefunc,

+              pfile_in_zip_read_info->filestream,

+              buf,read_now)!=read_now)

+        return UNZ_ERRNO;

+

+    return (int)read_now;

+}

+

+/*

+  Close the file in zip opened with unzipOpenCurrentFile

+  Return UNZ_CRCERROR if all the file was read but the CRC is not good

+*/

+extern int ZEXPORT unzCloseCurrentFile (file)

+    unzFile file;

+{

+    int err=UNZ_OK;

+

+    unz_s* s;

+    file_in_zip_read_info_s* pfile_in_zip_read_info;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+    pfile_in_zip_read_info=s->pfile_in_zip_read;

+

+    if (pfile_in_zip_read_info==NULL)

+        return UNZ_PARAMERROR;

+

+

+    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&

+        (!pfile_in_zip_read_info->raw))

+    {

+        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)

+            err=UNZ_CRCERROR;

+    }

+

+

+    TRYFREE(pfile_in_zip_read_info->read_buffer);

+    pfile_in_zip_read_info->read_buffer = NULL;

+    if (pfile_in_zip_read_info->stream_initialised)

+        inflateEnd(&pfile_in_zip_read_info->stream);

+

+    pfile_in_zip_read_info->stream_initialised = 0;

+    TRYFREE(pfile_in_zip_read_info);

+

+    s->pfile_in_zip_read=NULL;

+

+    return err;

+}

+

+

+/*

+  Get the global comment string of the ZipFile, in the szComment buffer.

+  uSizeBuf is the size of the szComment buffer.

+  return the number of byte copied or an error code <0

+*/

+extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)

+    unzFile file;

+    char *szComment;

+    uLong uSizeBuf;

+{

+    int err=UNZ_OK;

+    unz_s* s;

+    uLong uReadThis ;

+    if (file==NULL)

+        return UNZ_PARAMERROR;

+    s=(unz_s*)file;

+

+    uReadThis = uSizeBuf;

+    if (uReadThis>s->gi.size_comment)

+        uReadThis = s->gi.size_comment;

+

+    if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)

+        return UNZ_ERRNO;

+

+    if (uReadThis>0)

+    {

+      *szComment='\0';

+      if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)

+        return UNZ_ERRNO;

+    }

+

+    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))

+        *(szComment+s->gi.size_comment)='\0';

+    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;

+}

diff --git a/contrib/minizip/unzip.h b/contrib/minizip/unzip.h
index 0c7c6f1..c3206a0 100644
--- a/contrib/minizip/unzip.h
+++ b/contrib/minizip/unzip.h
@@ -1,352 +1,354 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-
-   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
-     WinZip, InfoZip tools and compatible.
-   Encryption and multi volume ZipFile (span) are not supported.
-   Old compressions used by old PKZip 1.x are not supported
-
-
-   I WAIT FEEDBACK at mail info@winimage.com
-   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
-      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
-      http://www.info-zip.org/pub/infozip/doc/
-   PkWare has also a specification at :
-      ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK                          (0)
-#define UNZ_END_OF_LIST_OF_FILE         (-100)
-#define UNZ_ERRNO                       (Z_ERRNO)
-#define UNZ_EOF                         (0)
-#define UNZ_PARAMERROR                  (-102)
-#define UNZ_BADZIPFILE                  (-103)
-#define UNZ_INTERNALERROR               (-104)
-#define UNZ_CRCERROR                    (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
-   These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
-    uLong number_entry;         /* total number of entries in
-                       the central dir on this disk */
-    uLong size_comment;         /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
-    uLong version;              /* version made by                 2 bytes */
-    uLong version_needed;       /* version needed to extract       2 bytes */
-    uLong flag;                 /* general purpose bit flag        2 bytes */
-    uLong compression_method;   /* compression method              2 bytes */
-    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
-    uLong crc;                  /* crc-32                          4 bytes */
-    uLong compressed_size;      /* compressed size                 4 bytes */
-    uLong uncompressed_size;    /* uncompressed size               4 bytes */
-    uLong size_filename;        /* filename length                 2 bytes */
-    uLong size_file_extra;      /* extra field length              2 bytes */
-    uLong size_file_comment;    /* file comment length             2 bytes */
-
-    uLong disk_num_start;       /* disk number start               2 bytes */
-    uLong internal_fa;          /* internal file attributes        2 bytes */
-    uLong external_fa;          /* external file attributes        4 bytes */
-
-    tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
-                                                 const char* fileName2,
-                                                 int iCaseSensitivity));
-/*
-   Compare two filename (fileName1,fileName2).
-   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
-   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
-                                or strcasecmp)
-   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
-    (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
-  Open a Zip file. path contain the full pathname (by example,
-     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
-     "zlib/zlib113.zip".
-     If the zipfile cannot be opened (file don't exist or in not valid), the
-       return value is NULL.
-     Else, the return value is a unzFile Handle, usable with other function
-       of this unzip package.
-*/
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
-                                    zlib_filefunc_def* pzlib_filefunc_def));
-/*
-   Open a Zip file, like unzOpen, but provide a set of file low level API
-      for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
-  Close a ZipFile opened with unzipOpen.
-  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
-    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
-  return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
-                                        unz_global_info *pglobal_info));
-/*
-  Write info about the ZipFile in the *pglobal_info structure.
-  No preparation of the structure is needed
-  return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
-                                           char *szComment,
-                                           uLong uSizeBuf));
-/*
-  Get the global comment string of the ZipFile, in the szComment buffer.
-  uSizeBuf is the size of the szComment buffer.
-  return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the first file.
-  return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
-  Set the current file of the zipfile to the next file.
-  return UNZ_OK if there is no problem
-  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
-                     const char *szFileName,
-                     int iCaseSensitivity));
-/*
-  Try locate the file szFileName in the zipfile.
-  For the iCaseSensitivity signification, see unzStringFileNameCompare
-
-  return value :
-  UNZ_OK if the file is found. It becomes the current file.
-  UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
-    uLong pos_in_zip_directory;   /* offset in zip file directory */
-    uLong num_of_file;            /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
-    unzFile file,
-    unz_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
-                         unz_file_info *pfile_info,
-                         char *szFileName,
-                         uLong fileNameBufferSize,
-                         void *extraField,
-                         uLong extraFieldBufferSize,
-                         char *szComment,
-                         uLong commentBufferSize));
-/*
-  Get Info about the current file
-  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
-        the current file
-  if szFileName!=NULL, the filemane string will be copied in szFileName
-            (fileNameBufferSize is the size of the buffer)
-  if extraField!=NULL, the extra field information will be copied in extraField
-            (extraFieldBufferSize is the size of the buffer).
-            This is the Central-header version of the extra field
-  if szComment!=NULL, the comment string of the file will be copied in szComment
-            (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
-   from it, and close it (you can close it before reading all the file)
-   */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
-  Open for reading data the current file in the zipfile.
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
-                                                  const char* password));
-/*
-  Open for reading data the current file in the zipfile.
-  password is a crypting password
-  If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
-                                           int* method,
-                                           int* level,
-                                           int raw,
-                                           const char* password));
-/*
-  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
-    if raw==1
-  *method will receive method of compression, *level will receive level of
-     compression
-  note : you can set level parameter as NULL (if you did not want known level,
-         but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
-  Close the file in zip opened with unzOpenCurrentFile
-  Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
-                      voidp buf,
-                      unsigned len));
-/*
-  Read bytes from the current file (opened by unzOpenCurrentFile)
-  buf contain buffer where data must be copied
-  len the size of buf.
-
-  return the number of byte copied if somes bytes are copied
-  return 0 if the end of file was reached
-  return <0 with error code if there is an error
-    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
-  Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
-  return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
-                                             voidp buf,
-                                             unsigned len));
-/*
-  Read extra field from the current file (opened by unzOpenCurrentFile)
-  This is the local-header version of the extra field (sometimes, there is
-    more info in the local-header version than in the central-header)
-
-  if buf==NULL, it return the size of the local extra field
-
-  if buf!=NULL, len is the size of the buffer, the extra header is copied in
-    buf.
-  the return value is the number of bytes copied in buf, or (if <0)
-    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
-}
-#endif
-
-#endif /* _unz_H */
+/* unzip.h -- IO for uncompress .zip files using zlib

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+

+   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g

+     WinZip, InfoZip tools and compatible.

+

+   Multi volume ZipFile (span) are not supported.

+   Encryption compatible with pkzip 2.04g only supported

+   Old compressions used by old PKZip 1.x are not supported

+

+

+   I WAIT FEEDBACK at mail info@winimage.com

+   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution

+

+   Condition of use and distribution are the same than zlib :

+

+  This software is provided 'as-is', without any express or implied

+  warranty.  In no event will the authors be held liable for any damages

+  arising from the use of this software.

+

+  Permission is granted to anyone to use this software for any purpose,

+  including commercial applications, and to alter it and redistribute it

+  freely, subject to the following restrictions:

+

+  1. The origin of this software must not be misrepresented; you must not

+     claim that you wrote the original software. If you use this software

+     in a product, an acknowledgment in the product documentation would be

+     appreciated but is not required.

+  2. Altered source versions must be plainly marked as such, and must not be

+     misrepresented as being the original software.

+  3. This notice may not be removed or altered from any source distribution.

+

+

+*/

+

+/* for more info about .ZIP format, see

+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip

+      http://www.info-zip.org/pub/infozip/doc/

+   PkWare has also a specification at :

+      ftp://ftp.pkware.com/probdesc.zip

+*/

+

+#ifndef _unz_H

+#define _unz_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#ifndef _ZLIB_H

+#include "zlib.h"

+#endif

+

+#ifndef _ZLIBIOAPI_H

+#include "ioapi.h"

+#endif

+

+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)

+/* like the STRICT of WIN32, we define a pointer that cannot be converted

+    from (void*) without cast */

+typedef struct TagunzFile__ { int unused; } unzFile__;

+typedef unzFile__ *unzFile;

+#else

+typedef voidp unzFile;

+#endif

+

+

+#define UNZ_OK                          (0)

+#define UNZ_END_OF_LIST_OF_FILE         (-100)

+#define UNZ_ERRNO                       (Z_ERRNO)

+#define UNZ_EOF                         (0)

+#define UNZ_PARAMERROR                  (-102)

+#define UNZ_BADZIPFILE                  (-103)

+#define UNZ_INTERNALERROR               (-104)

+#define UNZ_CRCERROR                    (-105)

+

+/* tm_unz contain date/time info */

+typedef struct tm_unz_s

+{

+    uInt tm_sec;            /* seconds after the minute - [0,59] */

+    uInt tm_min;            /* minutes after the hour - [0,59] */

+    uInt tm_hour;           /* hours since midnight - [0,23] */

+    uInt tm_mday;           /* day of the month - [1,31] */

+    uInt tm_mon;            /* months since January - [0,11] */

+    uInt tm_year;           /* years - [1980..2044] */

+} tm_unz;

+

+/* unz_global_info structure contain global data about the ZIPfile

+   These data comes from the end of central dir */

+typedef struct unz_global_info_s

+{

+    uLong number_entry;         /* total number of entries in

+                       the central dir on this disk */

+    uLong size_comment;         /* size of the global comment of the zipfile */

+} unz_global_info;

+

+

+/* unz_file_info contain information about a file in the zipfile */

+typedef struct unz_file_info_s

+{

+    uLong version;              /* version made by                 2 bytes */

+    uLong version_needed;       /* version needed to extract       2 bytes */

+    uLong flag;                 /* general purpose bit flag        2 bytes */

+    uLong compression_method;   /* compression method              2 bytes */

+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */

+    uLong crc;                  /* crc-32                          4 bytes */

+    uLong compressed_size;      /* compressed size                 4 bytes */

+    uLong uncompressed_size;    /* uncompressed size               4 bytes */

+    uLong size_filename;        /* filename length                 2 bytes */

+    uLong size_file_extra;      /* extra field length              2 bytes */

+    uLong size_file_comment;    /* file comment length             2 bytes */

+

+    uLong disk_num_start;       /* disk number start               2 bytes */

+    uLong internal_fa;          /* internal file attributes        2 bytes */

+    uLong external_fa;          /* external file attributes        4 bytes */

+

+    tm_unz tmu_date;

+} unz_file_info;

+

+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,

+                                                 const char* fileName2,

+                                                 int iCaseSensitivity));

+/*

+   Compare two filename (fileName1,fileName2).

+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)

+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi

+                                or strcasecmp)

+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system

+    (like 1 on Unix, 2 on Windows)

+*/

+

+

+extern unzFile ZEXPORT unzOpen OF((const char *path));

+/*

+  Open a Zip file. path contain the full pathname (by example,

+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer

+     "zlib/zlib113.zip".

+     If the zipfile cannot be opened (file don't exist or in not valid), the

+       return value is NULL.

+     Else, the return value is a unzFile Handle, usable with other function

+       of this unzip package.

+*/

+

+extern unzFile ZEXPORT unzOpen2 OF((const char *path,

+                                    zlib_filefunc_def* pzlib_filefunc_def));

+/*

+   Open a Zip file, like unzOpen, but provide a set of file low level API

+      for read/write the zip file (see ioapi.h)

+*/

+

+extern int ZEXPORT unzClose OF((unzFile file));

+/*

+  Close a ZipFile opened with unzipOpen.

+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),

+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.

+  return UNZ_OK if there is no problem. */

+

+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,

+                                        unz_global_info *pglobal_info));

+/*

+  Write info about the ZipFile in the *pglobal_info structure.

+  No preparation of the structure is needed

+  return UNZ_OK if there is no problem. */

+

+

+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,

+                                           char *szComment,

+                                           uLong uSizeBuf));

+/*

+  Get the global comment string of the ZipFile, in the szComment buffer.

+  uSizeBuf is the size of the szComment buffer.

+  return the number of byte copied or an error code <0

+*/

+

+

+/***************************************************************************/

+/* Unzip package allow you browse the directory of the zipfile */

+

+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));

+/*

+  Set the current file of the zipfile to the first file.

+  return UNZ_OK if there is no problem

+*/

+

+extern int ZEXPORT unzGoToNextFile OF((unzFile file));

+/*

+  Set the current file of the zipfile to the next file.

+  return UNZ_OK if there is no problem

+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.

+*/

+

+extern int ZEXPORT unzLocateFile OF((unzFile file,

+                     const char *szFileName,

+                     int iCaseSensitivity));

+/*

+  Try locate the file szFileName in the zipfile.

+  For the iCaseSensitivity signification, see unzStringFileNameCompare

+

+  return value :

+  UNZ_OK if the file is found. It becomes the current file.

+  UNZ_END_OF_LIST_OF_FILE if the file is not found

+*/

+

+

+/* ****************************************** */

+/* Ryan supplied functions */

+/* unz_file_info contain information about a file in the zipfile */

+typedef struct unz_file_pos_s

+{

+    uLong pos_in_zip_directory;   /* offset in zip file directory */

+    uLong num_of_file;            /* # of file */

+} unz_file_pos;

+

+extern int ZEXPORT unzGetFilePos(

+    unzFile file,

+    unz_file_pos* file_pos);

+

+extern int ZEXPORT unzGoToFilePos(

+    unzFile file,

+    unz_file_pos* file_pos);

+

+/* ****************************************** */

+

+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,

+                         unz_file_info *pfile_info,

+                         char *szFileName,

+                         uLong fileNameBufferSize,

+                         void *extraField,

+                         uLong extraFieldBufferSize,

+                         char *szComment,

+                         uLong commentBufferSize));

+/*

+  Get Info about the current file

+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about

+        the current file

+  if szFileName!=NULL, the filemane string will be copied in szFileName

+            (fileNameBufferSize is the size of the buffer)

+  if extraField!=NULL, the extra field information will be copied in extraField

+            (extraFieldBufferSize is the size of the buffer).

+            This is the Central-header version of the extra field

+  if szComment!=NULL, the comment string of the file will be copied in szComment

+            (commentBufferSize is the size of the buffer)

+*/

+

+/***************************************************************************/

+/* for reading the content of the current zipfile, you can open it, read data

+   from it, and close it (you can close it before reading all the file)

+   */

+

+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));

+/*

+  Open for reading data the current file in the zipfile.

+  If there is no error, the return value is UNZ_OK.

+*/

+

+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,

+                                                  const char* password));

+/*

+  Open for reading data the current file in the zipfile.

+  password is a crypting password

+  If there is no error, the return value is UNZ_OK.

+*/

+

+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,

+                                           int* method,

+                                           int* level,

+                                           int raw));

+/*

+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)

+    if raw==1

+  *method will receive method of compression, *level will receive level of

+     compression

+  note : you can set level parameter as NULL (if you did not want known level,

+         but you CANNOT set method parameter as NULL

+*/

+

+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,

+                                           int* method,

+                                           int* level,

+                                           int raw,

+                                           const char* password));

+/*

+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)

+    if raw==1

+  *method will receive method of compression, *level will receive level of

+     compression

+  note : you can set level parameter as NULL (if you did not want known level,

+         but you CANNOT set method parameter as NULL

+*/

+

+

+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));

+/*

+  Close the file in zip opened with unzOpenCurrentFile

+  Return UNZ_CRCERROR if all the file was read but the CRC is not good

+*/

+

+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,

+                      voidp buf,

+                      unsigned len));

+/*

+  Read bytes from the current file (opened by unzOpenCurrentFile)

+  buf contain buffer where data must be copied

+  len the size of buf.

+

+  return the number of byte copied if somes bytes are copied

+  return 0 if the end of file was reached

+  return <0 with error code if there is an error

+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)

+*/

+

+extern z_off_t ZEXPORT unztell OF((unzFile file));

+/*

+  Give the current position in uncompressed data

+*/

+

+extern int ZEXPORT unzeof OF((unzFile file));

+/*

+  return 1 if the end of file was reached, 0 elsewhere

+*/

+

+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,

+                                             voidp buf,

+                                             unsigned len));

+/*

+  Read extra field from the current file (opened by unzOpenCurrentFile)

+  This is the local-header version of the extra field (sometimes, there is

+    more info in the local-header version than in the central-header)

+

+  if buf==NULL, it return the size of the local extra field

+

+  if buf!=NULL, len is the size of the buffer, the extra header is copied in

+    buf.

+  the return value is the number of bytes copied in buf, or (if <0)

+    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

+}

+#endif

+

+#endif /* _unz_H */

diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c
index 2ccd7fd..400e2ba 100644
--- a/contrib/minizip/zip.c
+++ b/contrib/minizip/zip.c
@@ -1,1188 +1,1219 @@
-/* zip.c -- IO on .zip files using zlib
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-
-   Read zip.h for more info
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-#  include <stddef.h>
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
-    extern int errno;
-#else
-#   include <errno.h>
-#endif
-
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY   (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR    1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END    2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET    0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =
-   " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC    (0x04034b50)
-#define CENTRALHEADERMAGIC  (0x02014b50)
-#define ENDHEADERMAGIC      (0x06054b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET  (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
-  struct linkedlist_datablock_internal_s* next_datablock;
-  uLong  avail_in_this_block;
-  uLong  filled_in_this_block;
-  uLong  unused; /* for future use and alignement */
-  unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
-    linkedlist_datablock_internal* first_block;
-    linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
-    z_stream stream;            /* zLib stream structure for inflate */
-    int  stream_initialised;    /* 1 is stream is initialised */
-    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
-
-    uLong pos_local_header;     /* offset of the local header of the file
-                                     currenty writing */
-    char* central_header;       /* central header data for the current file */
-    uLong size_centralheader;   /* size of the central header for cur file */
-    uLong flag;                 /* flag of the file currently writing */
-
-    int  method;                /* compression method of file currenty wr.*/
-    int  raw;                   /* 1 for directly writing raw data */
-    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
-    uLong dosDate;
-    uLong crc32;
-    int  encrypt;
-#ifndef NOCRYPT
-    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
-    const unsigned long* pcrc_32_tab;
-    int crypt_header_size;
-#endif
-} curfile_info;
-
-typedef struct
-{
-    zlib_filefunc_def z_filefunc;
-    voidpf filestream;        /* io structore of the zipfile */
-    linkedlist_data central_dir;/* datablock with central dir in construction*/
-    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
-    curfile_info ci;            /* info on the file curretly writing */
-
-    uLong begin_pos;            /* position of the beginning of the zipfile */
-    uLong add_position_when_writting_offset;
-    uLong number_entry;
-} zip_internal;
-
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
-    linkedlist_datablock_internal* ldi;
-    ldi = (linkedlist_datablock_internal*)
-                 ALLOC(sizeof(linkedlist_datablock_internal));
-    if (ldi!=NULL)
-    {
-        ldi->next_datablock = NULL ;
-        ldi->filled_in_this_block = 0 ;
-        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
-    }
-    return ldi;
-}
-
-local void free_datablock(ldi)
-    linkedlist_datablock_internal* ldi;
-{
-    while (ldi!=NULL)
-    {
-        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
-        TRYFREE(ldi);
-        ldi = ldinext;
-    }
-}
-
-local void init_linkedlist(ll)
-    linkedlist_data* ll;
-{
-    ll->first_block = ll->last_block = NULL;
-}
-
-local void free_linkedlist(ll)
-    linkedlist_data* ll;
-{
-    free_datablock(ll->first_block);
-    ll->first_block = ll->last_block = NULL;
-}
-
-
-local int add_data_in_datablock(ll,buf,len)
-    linkedlist_data* ll;
-    const void* buf;
-    uLong len;
-{
-    linkedlist_datablock_internal* ldi;
-    const unsigned char* from_copy;
-
-    if (ll==NULL)
-        return ZIP_INTERNALERROR;
-
-    if (ll->last_block == NULL)
-    {
-        ll->first_block = ll->last_block = allocate_new_datablock();
-        if (ll->first_block == NULL)
-            return ZIP_INTERNALERROR;
-    }
-
-    ldi = ll->last_block;
-    from_copy = (unsigned char*)buf;
-
-    while (len>0)
-    {
-        uInt copy_this;
-        uInt i;
-        unsigned char* to_copy;
-
-        if (ldi->avail_in_this_block==0)
-        {
-            ldi->next_datablock = allocate_new_datablock();
-            if (ldi->next_datablock == NULL)
-                return ZIP_INTERNALERROR;
-            ldi = ldi->next_datablock ;
-            ll->last_block = ldi;
-        }
-
-        if (ldi->avail_in_this_block < len)
-            copy_this = (uInt)ldi->avail_in_this_block;
-        else
-            copy_this = (uInt)len;
-
-        to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
-        for (i=0;i<copy_this;i++)
-            *(to_copy+i)=*(from_copy+i);
-
-        ldi->filled_in_this_block += copy_this;
-        ldi->avail_in_this_block -= copy_this;
-        from_copy += copy_this ;
-        len -= copy_this;
-    }
-    return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
-   Inputs a long in LSB order to the given file
-   nbByte == 1, 2 or 4 (byte, short or long)
-*/
-
-local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
-                                voidpf filestream, uLong x, int nbByte));
-local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    uLong x;
-    int nbByte;
-{
-    unsigned char buf[4];
-    int n;
-    for (n = 0; n < nbByte; n++)
-    {
-        buf[n] = (unsigned char)(x & 0xff);
-        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)
-        return ZIP_ERRNO;
-    else
-        return ZIP_OK;
-}
-
-local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
-local void ziplocal_putValue_inmemory (dest, x, nbByte)
-    void* dest;
-    uLong x;
-    int nbByte;
-{
-    unsigned char* buf=(unsigned char*)dest;
-    int n;
-    for (n = 0; n < nbByte; n++) {
-        buf[n] = (unsigned char)(x & 0xff);
-        x >>= 8;
-    }
-
-    if (x != 0)
-    {     /* data overflow - hack for ZIP64 */
-       for (n = 0; n < nbByte; n++)
-       {
-          buf[n] = 0xff;
-       }
-    }
-}
-
-/****************************************************************************/
-
-
-local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
-    const tm_zip* ptm;
-    uLong dosDate;
-{
-    uLong year = (uLong)ptm->tm_year;
-    if (year>1980)
-        year-=1980;
-    else if (year>80)
-        year-=80;
-    return
-      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
-        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int ziplocal_getByte OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    int *pi));
-
-local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    int *pi;
-{
-    unsigned char c;
-    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
-    if (err==1)
-    {
-        *pi = (int)c;
-        return ZIP_OK;
-    }
-    else
-    {
-        if (ZERROR(*pzlib_filefunc_def,filestream))
-            return ZIP_ERRNO;
-        else
-            return ZIP_EOF;
-    }
-}
-
-
-/* ===========================================================================
-   Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int ziplocal_getShort OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    uLong *pX;
-{
-    uLong x ;
-    int i;
-    int err;
-
-    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-local int ziplocal_getLong OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream,
-    uLong *pX));
-
-local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-    uLong *pX;
-{
-    uLong x ;
-    int i;
-    int err;
-
-    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x = (uLong)i;
-
-    if (err==ZIP_OK)
-        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<8;
-
-    if (err==ZIP_OK)
-        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<16;
-
-    if (err==ZIP_OK)
-        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
-    x += ((uLong)i)<<24;
-
-    if (err==ZIP_OK)
-        *pX = x;
-    else
-        *pX = 0;
-    return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
-  Locate the Central directory of a zipfile (at the end, just before
-    the global comment)
-*/
-local uLong ziplocal_SearchCentralDir OF((
-    const zlib_filefunc_def* pzlib_filefunc_def,
-    voidpf filestream));
-
-local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
-    const zlib_filefunc_def* pzlib_filefunc_def;
-    voidpf filestream;
-{
-    unsigned char* buf;
-    uLong uSizeFile;
-    uLong uBackRead;
-    uLong uMaxBack=0xffff; /* maximum size of global comment */
-    uLong uPosFound=0;
-
-    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
-        return 0;
-
-
-    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
-    if (uMaxBack>uSizeFile)
-        uMaxBack = uSizeFile;
-
-    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
-    if (buf==NULL)
-        return 0;
-
-    uBackRead = 4;
-    while (uBackRead<uMaxBack)
-    {
-        uLong uReadSize,uReadPos ;
-        int i;
-        if (uBackRead+BUFREADCOMMENT>uMaxBack)
-            uBackRead = uMaxBack;
-        else
-            uBackRead+=BUFREADCOMMENT;
-        uReadPos = uSizeFile-uBackRead ;
-
-        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
-                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
-        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            break;
-
-        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
-            break;
-
-        for (i=(int)uReadSize-3; (i--)>0;)
-            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
-                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
-            {
-                uPosFound = uReadPos+i;
-                break;
-            }
-
-        if (uPosFound!=0)
-            break;
-    }
-    TRYFREE(buf);
-    return uPosFound;
-}
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
-    const char *pathname;
-    int append;
-    zipcharpc* globalcomment;
-    zlib_filefunc_def* pzlib_filefunc_def;
-{
-    zip_internal ziinit;
-    zip_internal* zi;
-    int err=ZIP_OK;
-
-
-    if (pzlib_filefunc_def==NULL)
-        fill_fopen_filefunc(&ziinit.z_filefunc);
-    else
-        ziinit.z_filefunc = *pzlib_filefunc_def;
-
-    ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
-                 (ziinit.z_filefunc.opaque,
-                  pathname,
-                  (append == APPEND_STATUS_CREATE) ?
-                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
-                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
-    if (ziinit.filestream == NULL)
-        return NULL;
-    ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
-    ziinit.in_opened_file_inzip = 0;
-    ziinit.ci.stream_initialised = 0;
-    ziinit.number_entry = 0;
-    ziinit.add_position_when_writting_offset = 0;
-    init_linkedlist(&(ziinit.central_dir));
-
-
-    zi = (zip_internal*)ALLOC(sizeof(zip_internal));
-    if (zi==NULL)
-    {
-        ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
-        return NULL;
-    }
-
-    /* now we add file in a zipfile */
-#    ifndef NO_ADDFILEINEXISTINGZIP
-    if (append == APPEND_STATUS_ADDINZIP)
-    {
-        uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
-        uLong size_central_dir;     /* size of the central directory  */
-        uLong offset_central_dir;   /* offset of start of central directory */
-        uLong central_pos,uL;
-
-        uLong number_disk;          /* number of the current dist, used for
-                                    spaning ZIP, unsupported, always 0*/
-        uLong number_disk_with_CD;  /* number the the disk with central dir, used
-                                    for spaning ZIP, unsupported, always 0*/
-        uLong number_entry;
-        uLong number_entry_CD;      /* total number of entries in
-                                    the central dir
-                                    (same than number_entry on nospan) */
-        uLong size_comment;
-
-        central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
-        if (central_pos==0)
-            err=ZIP_ERRNO;
-
-        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
-                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err=ZIP_ERRNO;
-
-        /* the signature, already checked */
-        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* number of this disk */
-        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* number of the disk with the start of the central directory */
-        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* total number of entries in the central dir on this disk */
-        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* total number of entries in the central dir */
-        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        if ((number_entry_CD!=number_entry) ||
-            (number_disk_with_CD!=0) ||
-            (number_disk!=0))
-            err=ZIP_BADZIPFILE;
-
-        /* size of the central directory */
-        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* offset of start of central directory with respect to the
-            starting disk number */
-        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        /* zipfile comment length */
-        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
-            err=ZIP_ERRNO;
-
-        if ((central_pos<offset_central_dir+size_central_dir) &&
-            (err==ZIP_OK))
-            err=ZIP_BADZIPFILE;
-
-        if (err!=ZIP_OK)
-        {
-            ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
-            return NULL;
-        }
-
-        byte_before_the_zipfile = central_pos -
-                                (offset_central_dir+size_central_dir);
-        ziinit.add_position_when_writting_offset = byte_before_the_zipfile ;
-
-        {
-            uLong size_central_dir_to_read = size_central_dir;
-            size_t buf_size = SIZEDATA_INDATABLOCK;
-            void* buf_read = (void*)ALLOC(buf_size);
-            if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
-                  offset_central_dir + byte_before_the_zipfile,
-                  ZLIB_FILEFUNC_SEEK_SET) != 0)
-                  err=ZIP_ERRNO;
-
-            while ((size_central_dir_to_read>0) && (err==ZIP_OK))
-            {
-                uLong read_this = SIZEDATA_INDATABLOCK;
-                if (read_this > size_central_dir_to_read)
-                    read_this = size_central_dir_to_read;
-                if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
-                    err=ZIP_ERRNO;
-
-                if (err==ZIP_OK)
-                    err = add_data_in_datablock(&ziinit.central_dir,buf_read,
-                                                (uLong)read_this);
-                size_central_dir_to_read-=read_this;
-            }
-            TRYFREE(buf_read);
-        }
-        ziinit.begin_pos = byte_before_the_zipfile;
-        ziinit.number_entry = number_entry_CD;
-
-        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
-                  offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err=ZIP_ERRNO;
-    }
-#    endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-    if (err != ZIP_OK)
-    {
-        TRYFREE(zi);
-        return NULL;
-    }
-    else
-    {
-        *zi = ziinit;
-        return (zipFile)zi;
-    }
-}
-
-extern zipFile ZEXPORT zipOpen (pathname, append)
-    const char *pathname;
-    int append;
-{
-    return zipOpen2(pathname,append,NULL,NULL);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
-                                         extrafield_local, size_extrafield_local,
-                                         extrafield_global, size_extrafield_global,
-                                         comment, method, level, raw,
-                                         windowBits, memLevel, strategy,
-                                         password, crcForCrypting)
-    zipFile file;
-    const char* filename;
-    const zip_fileinfo* zipfi;
-    const void* extrafield_local;
-    uInt size_extrafield_local;
-    const void* extrafield_global;
-    uInt size_extrafield_global;
-    const char* comment;
-    int method;
-    int level;
-    int raw;
-    int windowBits;
-    int memLevel;
-    int strategy;
-    const char* password;
-    uLong crcForCrypting;
-{
-    zip_internal* zi;
-    uInt size_filename;
-    uInt size_comment;
-    uInt i;
-    int err = ZIP_OK;
-
-#    ifdef NOCRYPT
-    if (password != NULL)
-        return ZIP_PARAMERROR;
-#    endif
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    if ((method!=0) && (method!=Z_DEFLATED))
-        return ZIP_PARAMERROR;
-
-    zi = (zip_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-        if (err != ZIP_OK)
-            return err;
-    }
-
-
-    if (filename==NULL)
-        filename="-";
-
-    if (comment==NULL)
-        size_comment = 0;
-    else
-        size_comment = (uInt)strlen(comment);
-
-    size_filename = (uInt)strlen(filename);
-
-    if (zipfi == NULL)
-        zi->ci.dosDate = 0;
-    else
-    {
-        if (zipfi->dosDate != 0)
-            zi->ci.dosDate = zipfi->dosDate;
-        else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
-    }
-
-    zi->ci.flag = 0;
-    if ((level==8) || (level==9))
-      zi->ci.flag |= 2;
-    if ((level==2))
-      zi->ci.flag |= 4;
-    if ((level==1))
-      zi->ci.flag |= 6;
-    if (password != NULL)
-      zi->ci.flag |= 1;
-
-    zi->ci.crc32 = 0;
-    zi->ci.method = method;
-    zi->ci.encrypt = 0;
-    zi->ci.stream_initialised = 0;
-    zi->ci.pos_in_buffered_data = 0;
-    zi->ci.raw = raw;
-    zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
-    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
-                                      size_extrafield_global + size_comment;
-    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
-
-    ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
-    /* version info */
-    ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
-    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
-    ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
-    ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
-    ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
-    if (zipfi==NULL)
-        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
-    else
-        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
-    if (zipfi==NULL)
-        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
-    else
-        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
-    ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
-
-    for (i=0;i<size_filename;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
-    for (i=0;i<size_extrafield_global;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
-              *(((const char*)extrafield_global)+i);
-
-    for (i=0;i<size_comment;i++)
-        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
-              size_extrafield_global+i) = *(comment+i);
-    if (zi->ci.central_header == NULL)
-        return ZIP_INTERNALERROR;
-
-    /* write the local header */
-    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
-    if (err==ZIP_OK)
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
-
-    if ((err==ZIP_OK) && (size_filename>0))
-        if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
-                err = ZIP_ERRNO;
-
-    if ((err==ZIP_OK) && (size_extrafield_local>0))
-        if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
-                                                                           !=size_extrafield_local)
-                err = ZIP_ERRNO;
-
-    zi->ci.stream.avail_in = (uInt)0;
-    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-    zi->ci.stream.next_out = zi->ci.buffered_data;
-    zi->ci.stream.total_in = 0;
-    zi->ci.stream.total_out = 0;
-
-    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-    {
-        zi->ci.stream.zalloc = (alloc_func)0;
-        zi->ci.stream.zfree = (free_func)0;
-        zi->ci.stream.opaque = (voidpf)0;
-
-        if (windowBits>0)
-            windowBits = -windowBits;
-
-        err = deflateInit2(&zi->ci.stream, level,
-               Z_DEFLATED, windowBits, memLevel, strategy);
-
-        if (err==Z_OK)
-            zi->ci.stream_initialised = 1;
-    }
-#    ifndef NOCRYPT
-    zi->ci.crypt_header_size = 0;
-    if ((err==Z_OK) && (password != NULL))
-    {
-        unsigned char bufHead[RAND_HEAD_LEN];
-        unsigned int sizeHead;
-        zi->ci.encrypt = 1;
-        zi->ci.pcrc_32_tab = get_crc_table();
-        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
-        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
-        zi->ci.crypt_header_size = sizeHead;
-
-        if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
-                err = ZIP_ERRNO;
-    }
-#    endif
-
-    if (err==Z_OK)
-        zi->in_opened_file_inzip = 1;
-    return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
-                                        extrafield_local, size_extrafield_local,
-                                        extrafield_global, size_extrafield_global,
-                                        comment, method, level, raw)
-    zipFile file;
-    const char* filename;
-    const zip_fileinfo* zipfi;
-    const void* extrafield_local;
-    uInt size_extrafield_local;
-    const void* extrafield_global;
-    uInt size_extrafield_global;
-    const char* comment;
-    int method;
-    int level;
-    int raw;
-{
-    return zipOpenNewFileInZip3 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, raw,
-                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
-                                 NULL, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
-                                        extrafield_local, size_extrafield_local,
-                                        extrafield_global, size_extrafield_global,
-                                        comment, method, level)
-    zipFile file;
-    const char* filename;
-    const zip_fileinfo* zipfi;
-    const void* extrafield_local;
-    uInt size_extrafield_local;
-    const void* extrafield_global;
-    uInt size_extrafield_global;
-    const char* comment;
-    int method;
-    int level;
-{
-    return zipOpenNewFileInZip2 (file, filename, zipfi,
-                                 extrafield_local, size_extrafield_local,
-                                 extrafield_global, size_extrafield_global,
-                                 comment, method, level, 0);
-}
-
-local int zipFlushWriteBuffer(zi)
-  zip_internal* zi;
-{
-    int err=ZIP_OK;
-
-    if (zi->ci.encrypt != 0)
-    {
-#ifndef NOCRYPT
-        uInt i;
-        int t;
-        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
-            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
-                                       zi->ci.buffered_data[i],t);
-#endif
-    }
-    if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
-                                                                    !=zi->ci.pos_in_buffered_data)
-      err = ZIP_ERRNO;
-    zi->ci.pos_in_buffered_data = 0;
-    return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
-    zipFile file;
-    const void* buf;
-    unsigned len;
-{
-    zip_internal* zi;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-
-    zi->ci.stream.next_in = (void*)buf;
-    zi->ci.stream.avail_in = len;
-    zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
-
-    while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
-    {
-        if (zi->ci.stream.avail_out == 0)
-        {
-            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
-                err = ZIP_ERRNO;
-            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-            zi->ci.stream.next_out = zi->ci.buffered_data;
-        }
-
-
-        if(err != ZIP_OK)
-            break;
-
-        if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-        {
-            uLong uTotalOutBefore = zi->ci.stream.total_out;
-            err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
-            zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-
-        }
-        else
-        {
-            uInt copy_this,i;
-            if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
-                copy_this = zi->ci.stream.avail_in;
-            else
-                copy_this = zi->ci.stream.avail_out;
-            for (i=0;i<copy_this;i++)
-                *(((char*)zi->ci.stream.next_out)+i) =
-                    *(((const char*)zi->ci.stream.next_in)+i);
-            {
-                zi->ci.stream.avail_in -= copy_this;
-                zi->ci.stream.avail_out-= copy_this;
-                zi->ci.stream.next_in+= copy_this;
-                zi->ci.stream.next_out+= copy_this;
-                zi->ci.stream.total_in+= copy_this;
-                zi->ci.stream.total_out+= copy_this;
-                zi->ci.pos_in_buffered_data += copy_this;
-            }
-        }
-    }
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
-    zipFile file;
-    uLong uncompressed_size;
-    uLong crc32;
-{
-    zip_internal* zi;
-    uLong compressed_size;
-    int err=ZIP_OK;
-
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip_internal*)file;
-
-    if (zi->in_opened_file_inzip == 0)
-        return ZIP_PARAMERROR;
-    zi->ci.stream.avail_in = 0;
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-        while (err==ZIP_OK)
-    {
-        uLong uTotalOutBefore;
-        if (zi->ci.stream.avail_out == 0)
-        {
-            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
-                err = ZIP_ERRNO;
-            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
-            zi->ci.stream.next_out = zi->ci.buffered_data;
-        }
-        uTotalOutBefore = zi->ci.stream.total_out;
-        err=deflate(&zi->ci.stream,  Z_FINISH);
-        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-    }
-
-    if (err==Z_STREAM_END)
-        err=ZIP_OK; /* this is normal */
-
-    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
-        if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
-            err = ZIP_ERRNO;
-
-    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
-    {
-        err=deflateEnd(&zi->ci.stream);
-        zi->ci.stream_initialised = 0;
-    }
-
-    if (!zi->ci.raw)
-    {
-        crc32 = (uLong)zi->ci.crc32;
-        uncompressed_size = (uLong)zi->ci.stream.total_in;
-    }
-    compressed_size = (uLong)zi->ci.stream.total_out;
-#    ifndef NOCRYPT
-    compressed_size += zi->ci.crypt_header_size;
-#    endif
-
-    ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
-    ziplocal_putValue_inmemory(zi->ci.central_header+20,
-                                compressed_size,4); /*compr size*/
-    if (zi->ci.stream.data_type == Z_ASCII)
-        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
-    ziplocal_putValue_inmemory(zi->ci.central_header+24,
-                                uncompressed_size,4); /*uncompr size*/
-
-    if (err==ZIP_OK)
-        err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
-                                       (uLong)zi->ci.size_centralheader);
-    free(zi->ci.central_header);
-
-    if (err==ZIP_OK)
-    {
-        long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
-        if (ZSEEK(zi->z_filefunc,zi->filestream,
-                  zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-
-        if (err==ZIP_OK)
-            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
-        if (err==ZIP_OK) /* compressed size, unknown */
-            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
-        if (err==ZIP_OK) /* uncompressed size, unknown */
-            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-
-        if (ZSEEK(zi->z_filefunc,zi->filestream,
-                  cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
-            err = ZIP_ERRNO;
-    }
-
-    zi->number_entry ++;
-    zi->in_opened_file_inzip = 0;
-
-    return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (file)
-    zipFile file;
-{
-    return zipCloseFileInZipRaw (file,0,0);
-}
-
-extern int ZEXPORT zipClose (file, global_comment)
-    zipFile file;
-    const char* global_comment;
-{
-    zip_internal* zi;
-    int err = 0;
-    uLong size_centraldir = 0;
-    uLong centraldir_pos_inzip ;
-    uInt size_global_comment;
-    if (file == NULL)
-        return ZIP_PARAMERROR;
-    zi = (zip_internal*)file;
-
-    if (zi->in_opened_file_inzip == 1)
-    {
-        err = zipCloseFileInZip (file);
-    }
-
-    if (global_comment==NULL)
-        size_global_comment = 0;
-    else
-        size_global_comment = (uInt)strlen(global_comment);
-
-
-    centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
-    if (err==ZIP_OK)
-    {
-        linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
-        while (ldi!=NULL)
-        {
-            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
-                if (ZWRITE(zi->z_filefunc,zi->filestream,
-                           ldi->data,ldi->filled_in_this_block)
-                              !=ldi->filled_in_this_block )
-                    err = ZIP_ERRNO;
-
-            size_centraldir += ldi->filled_in_this_block;
-            ldi = ldi->next_datablock;
-        }
-    }
-    free_datablock(zi->central_dir.first_block);
-
-    if (err==ZIP_OK) /* Magic End */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
-    if (err==ZIP_OK) /* number of this disk */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
-    if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
-    if (err==ZIP_OK) /* total number of entries in the central dir */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
-    if (err==ZIP_OK) /* size of the central directory */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
-    if (err==ZIP_OK) /* offset of start of central directory with respect to the
-                            starting disk number */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
-                                (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-
-    if (err==ZIP_OK) /* zipfile comment length */
-        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
-    if ((err==ZIP_OK) && (size_global_comment>0))
-        if (ZWRITE(zi->z_filefunc,zi->filestream,
-                   global_comment,size_global_comment) != size_global_comment)
-                err = ZIP_ERRNO;
-
-    if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
-        if (err == ZIP_OK)
-            err = ZIP_ERRNO;
-
-    TRYFREE(zi);
-
-    return err;
-}
+/* zip.c -- IO on .zip files using zlib

+   Version 1.01e, February 12th, 2005

+

+   27 Dec 2004 Rolf Kalbermatter

+   Modification to zipOpen2 to support globalComment retrieval.

+

+   Copyright (C) 1998-2005 Gilles Vollant

+

+   Read zip.h for more info

+*/

+

+

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <time.h>

+#include "zlib.h"

+#include "zip.h"

+

+#ifdef STDC

+#  include <stddef.h>

+#  include <string.h>

+#  include <stdlib.h>

+#endif

+#ifdef NO_ERRNO_H

+    extern int errno;

+#else

+#   include <errno.h>

+#endif

+

+

+#ifndef local

+#  define local static

+#endif

+/* compile with -Dlocal if your debugger can't find static symbols */

+

+#ifndef VERSIONMADEBY

+# define VERSIONMADEBY   (0x0) /* platform depedent */

+#endif

+

+#ifndef Z_BUFSIZE

+#define Z_BUFSIZE (16384)

+#endif

+

+#ifndef Z_MAXFILENAMEINZIP

+#define Z_MAXFILENAMEINZIP (256)

+#endif

+

+#ifndef ALLOC

+# define ALLOC(size) (malloc(size))

+#endif

+#ifndef TRYFREE

+# define TRYFREE(p) {if (p) free(p);}

+#endif

+

+/*

+#define SIZECENTRALDIRITEM (0x2e)

+#define SIZEZIPLOCALHEADER (0x1e)

+*/

+

+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */

+

+#ifndef SEEK_CUR

+#define SEEK_CUR    1

+#endif

+

+#ifndef SEEK_END

+#define SEEK_END    2

+#endif

+

+#ifndef SEEK_SET

+#define SEEK_SET    0

+#endif

+

+#ifndef DEF_MEM_LEVEL

+#if MAX_MEM_LEVEL >= 8

+#  define DEF_MEM_LEVEL 8

+#else

+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL

+#endif

+#endif

+const char zip_copyright[] =

+   " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";

+

+

+#define SIZEDATA_INDATABLOCK (4096-(4*4))

+

+#define LOCALHEADERMAGIC    (0x04034b50)

+#define CENTRALHEADERMAGIC  (0x02014b50)

+#define ENDHEADERMAGIC      (0x06054b50)

+

+#define FLAG_LOCALHEADER_OFFSET (0x06)

+#define CRC_LOCALHEADER_OFFSET  (0x0e)

+

+#define SIZECENTRALHEADER (0x2e) /* 46 */

+

+typedef struct linkedlist_datablock_internal_s

+{

+  struct linkedlist_datablock_internal_s* next_datablock;

+  uLong  avail_in_this_block;

+  uLong  filled_in_this_block;

+  uLong  unused; /* for future use and alignement */

+  unsigned char data[SIZEDATA_INDATABLOCK];

+} linkedlist_datablock_internal;

+

+typedef struct linkedlist_data_s

+{

+    linkedlist_datablock_internal* first_block;

+    linkedlist_datablock_internal* last_block;

+} linkedlist_data;

+

+

+typedef struct

+{

+    z_stream stream;            /* zLib stream structure for inflate */

+    int  stream_initialised;    /* 1 is stream is initialised */

+    uInt pos_in_buffered_data;  /* last written byte in buffered_data */

+

+    uLong pos_local_header;     /* offset of the local header of the file

+                                     currenty writing */

+    char* central_header;       /* central header data for the current file */

+    uLong size_centralheader;   /* size of the central header for cur file */

+    uLong flag;                 /* flag of the file currently writing */

+

+    int  method;                /* compression method of file currenty wr.*/

+    int  raw;                   /* 1 for directly writing raw data */

+    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/

+    uLong dosDate;

+    uLong crc32;

+    int  encrypt;

+#ifndef NOCRYPT

+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */

+    const unsigned long* pcrc_32_tab;

+    int crypt_header_size;

+#endif

+} curfile_info;

+

+typedef struct

+{

+    zlib_filefunc_def z_filefunc;

+    voidpf filestream;        /* io structore of the zipfile */

+    linkedlist_data central_dir;/* datablock with central dir in construction*/

+    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/

+    curfile_info ci;            /* info on the file curretly writing */

+

+    uLong begin_pos;            /* position of the beginning of the zipfile */

+    uLong add_position_when_writting_offset;

+    uLong number_entry;

+#ifndef NO_ADDFILEINEXISTINGZIP

+    char *globalcomment;

+#endif

+} zip_internal;

+

+

+

+#ifndef NOCRYPT

+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED

+#include "crypt.h"

+#endif

+

+local linkedlist_datablock_internal* allocate_new_datablock()

+{

+    linkedlist_datablock_internal* ldi;

+    ldi = (linkedlist_datablock_internal*)

+                 ALLOC(sizeof(linkedlist_datablock_internal));

+    if (ldi!=NULL)

+    {

+        ldi->next_datablock = NULL ;

+        ldi->filled_in_this_block = 0 ;

+        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;

+    }

+    return ldi;

+}

+

+local void free_datablock(ldi)

+    linkedlist_datablock_internal* ldi;

+{

+    while (ldi!=NULL)

+    {

+        linkedlist_datablock_internal* ldinext = ldi->next_datablock;

+        TRYFREE(ldi);

+        ldi = ldinext;

+    }

+}

+

+local void init_linkedlist(ll)

+    linkedlist_data* ll;

+{

+    ll->first_block = ll->last_block = NULL;

+}

+

+local void free_linkedlist(ll)

+    linkedlist_data* ll;

+{

+    free_datablock(ll->first_block);

+    ll->first_block = ll->last_block = NULL;

+}

+

+

+local int add_data_in_datablock(ll,buf,len)

+    linkedlist_data* ll;

+    const void* buf;

+    uLong len;

+{

+    linkedlist_datablock_internal* ldi;

+    const unsigned char* from_copy;

+

+    if (ll==NULL)

+        return ZIP_INTERNALERROR;

+

+    if (ll->last_block == NULL)

+    {

+        ll->first_block = ll->last_block = allocate_new_datablock();

+        if (ll->first_block == NULL)

+            return ZIP_INTERNALERROR;

+    }

+

+    ldi = ll->last_block;

+    from_copy = (unsigned char*)buf;

+

+    while (len>0)

+    {

+        uInt copy_this;

+        uInt i;

+        unsigned char* to_copy;

+

+        if (ldi->avail_in_this_block==0)

+        {

+            ldi->next_datablock = allocate_new_datablock();

+            if (ldi->next_datablock == NULL)

+                return ZIP_INTERNALERROR;

+            ldi = ldi->next_datablock ;

+            ll->last_block = ldi;

+        }

+

+        if (ldi->avail_in_this_block < len)

+            copy_this = (uInt)ldi->avail_in_this_block;

+        else

+            copy_this = (uInt)len;

+

+        to_copy = &(ldi->data[ldi->filled_in_this_block]);

+

+        for (i=0;i<copy_this;i++)

+            *(to_copy+i)=*(from_copy+i);

+

+        ldi->filled_in_this_block += copy_this;

+        ldi->avail_in_this_block -= copy_this;

+        from_copy += copy_this ;

+        len -= copy_this;

+    }

+    return ZIP_OK;

+}

+

+

+

+/****************************************************************************/

+

+#ifndef NO_ADDFILEINEXISTINGZIP

+/* ===========================================================================

+   Inputs a long in LSB order to the given file

+   nbByte == 1, 2 or 4 (byte, short or long)

+*/

+

+local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,

+                                voidpf filestream, uLong x, int nbByte));

+local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    uLong x;

+    int nbByte;

+{

+    unsigned char buf[4];

+    int n;

+    for (n = 0; n < nbByte; n++)

+    {

+        buf[n] = (unsigned char)(x & 0xff);

+        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)

+        return ZIP_ERRNO;

+    else

+        return ZIP_OK;

+}

+

+local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));

+local void ziplocal_putValue_inmemory (dest, x, nbByte)

+    void* dest;

+    uLong x;

+    int nbByte;

+{

+    unsigned char* buf=(unsigned char*)dest;

+    int n;

+    for (n = 0; n < nbByte; n++) {

+        buf[n] = (unsigned char)(x & 0xff);

+        x >>= 8;

+    }

+

+    if (x != 0)

+    {     /* data overflow - hack for ZIP64 */

+       for (n = 0; n < nbByte; n++)

+       {

+          buf[n] = 0xff;

+       }

+    }

+}

+

+/****************************************************************************/

+

+

+local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)

+    const tm_zip* ptm;

+    uLong dosDate;

+{

+    uLong year = (uLong)ptm->tm_year;

+    if (year>1980)

+        year-=1980;

+    else if (year>80)

+        year-=80;

+    return

+      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |

+        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));

+}

+

+

+/****************************************************************************/

+

+local int ziplocal_getByte OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    int *pi));

+

+local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    int *pi;

+{

+    unsigned char c;

+    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);

+    if (err==1)

+    {

+        *pi = (int)c;

+        return ZIP_OK;

+    }

+    else

+    {

+        if (ZERROR(*pzlib_filefunc_def,filestream))

+            return ZIP_ERRNO;

+        else

+            return ZIP_EOF;

+    }

+}

+

+

+/* ===========================================================================

+   Reads a long in LSB order from the given gz_stream. Sets

+*/

+local int ziplocal_getShort OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    uLong *pX));

+

+local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    uLong *pX;

+{

+    uLong x ;

+    int i;

+    int err;

+

+    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x = (uLong)i;

+

+    if (err==ZIP_OK)

+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<8;

+

+    if (err==ZIP_OK)

+        *pX = x;

+    else

+        *pX = 0;

+    return err;

+}

+

+local int ziplocal_getLong OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream,

+    uLong *pX));

+

+local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+    uLong *pX;

+{

+    uLong x ;

+    int i;

+    int err;

+

+    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x = (uLong)i;

+

+    if (err==ZIP_OK)

+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<8;

+

+    if (err==ZIP_OK)

+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<16;

+

+    if (err==ZIP_OK)

+        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);

+    x += ((uLong)i)<<24;

+

+    if (err==ZIP_OK)

+        *pX = x;

+    else

+        *pX = 0;

+    return err;

+}

+

+#ifndef BUFREADCOMMENT

+#define BUFREADCOMMENT (0x400)

+#endif

+/*

+  Locate the Central directory of a zipfile (at the end, just before

+    the global comment)

+*/

+local uLong ziplocal_SearchCentralDir OF((

+    const zlib_filefunc_def* pzlib_filefunc_def,

+    voidpf filestream));

+

+local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)

+    const zlib_filefunc_def* pzlib_filefunc_def;

+    voidpf filestream;

+{

+    unsigned char* buf;

+    uLong uSizeFile;

+    uLong uBackRead;

+    uLong uMaxBack=0xffff; /* maximum size of global comment */

+    uLong uPosFound=0;

+

+    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)

+        return 0;

+

+

+    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);

+

+    if (uMaxBack>uSizeFile)

+        uMaxBack = uSizeFile;

+

+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);

+    if (buf==NULL)

+        return 0;

+

+    uBackRead = 4;

+    while (uBackRead<uMaxBack)

+    {

+        uLong uReadSize,uReadPos ;

+        int i;

+        if (uBackRead+BUFREADCOMMENT>uMaxBack)

+            uBackRead = uMaxBack;

+        else

+            uBackRead+=BUFREADCOMMENT;

+        uReadPos = uSizeFile-uBackRead ;

+

+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?

+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);

+        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            break;

+

+        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)

+            break;

+

+        for (i=(int)uReadSize-3; (i--)>0;)

+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&

+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))

+            {

+                uPosFound = uReadPos+i;

+                break;

+            }

+

+        if (uPosFound!=0)

+            break;

+    }

+    TRYFREE(buf);

+    return uPosFound;

+}

+#endif /* !NO_ADDFILEINEXISTINGZIP*/

+

+/************************************************************/

+extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)

+    const char *pathname;

+    int append;

+    zipcharpc* globalcomment;

+    zlib_filefunc_def* pzlib_filefunc_def;

+{

+    zip_internal ziinit;

+    zip_internal* zi;

+    int err=ZIP_OK;

+

+

+    if (pzlib_filefunc_def==NULL)

+        fill_fopen_filefunc(&ziinit.z_filefunc);

+    else

+        ziinit.z_filefunc = *pzlib_filefunc_def;

+

+    ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))

+                 (ziinit.z_filefunc.opaque,

+                  pathname,

+                  (append == APPEND_STATUS_CREATE) ?

+                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :

+                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));

+

+    if (ziinit.filestream == NULL)

+        return NULL;

+    ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);

+    ziinit.in_opened_file_inzip = 0;

+    ziinit.ci.stream_initialised = 0;

+    ziinit.number_entry = 0;

+    ziinit.add_position_when_writting_offset = 0;

+    init_linkedlist(&(ziinit.central_dir));

+

+

+    zi = (zip_internal*)ALLOC(sizeof(zip_internal));

+    if (zi==NULL)

+    {

+        ZCLOSE(ziinit.z_filefunc,ziinit.filestream);

+        return NULL;

+    }

+

+    /* now we add file in a zipfile */

+#    ifndef NO_ADDFILEINEXISTINGZIP

+    ziinit.globalcomment = NULL;

+    if (append == APPEND_STATUS_ADDINZIP)

+    {

+        uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/

+

+        uLong size_central_dir;     /* size of the central directory  */

+        uLong offset_central_dir;   /* offset of start of central directory */

+        uLong central_pos,uL;

+

+        uLong number_disk;          /* number of the current dist, used for

+                                    spaning ZIP, unsupported, always 0*/

+        uLong number_disk_with_CD;  /* number the the disk with central dir, used

+                                    for spaning ZIP, unsupported, always 0*/

+        uLong number_entry;

+        uLong number_entry_CD;      /* total number of entries in

+                                    the central dir

+                                    (same than number_entry on nospan) */

+        uLong size_comment;

+

+        central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);

+        if (central_pos==0)

+            err=ZIP_ERRNO;

+

+        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,

+                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            err=ZIP_ERRNO;

+

+        /* the signature, already checked */

+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* number of this disk */

+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* number of the disk with the start of the central directory */

+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* total number of entries in the central dir on this disk */

+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* total number of entries in the central dir */

+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        if ((number_entry_CD!=number_entry) ||

+            (number_disk_with_CD!=0) ||

+            (number_disk!=0))

+            err=ZIP_BADZIPFILE;

+

+        /* size of the central directory */

+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* offset of start of central directory with respect to the

+            starting disk number */

+        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        /* zipfile global comment length */

+        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)

+            err=ZIP_ERRNO;

+

+        if ((central_pos<offset_central_dir+size_central_dir) &&

+            (err==ZIP_OK))

+            err=ZIP_BADZIPFILE;

+

+        if (err!=ZIP_OK)

+        {

+            ZCLOSE(ziinit.z_filefunc, ziinit.filestream);

+            return NULL;

+        }

+

+        if (size_comment>0)

+        {

+            ziinit.globalcomment = ALLOC(size_comment+1);

+            if (ziinit.globalcomment)

+            {

+               size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);

+               ziinit.globalcomment[size_comment]=0;

+            }

+        }

+

+        byte_before_the_zipfile = central_pos -

+                                (offset_central_dir+size_central_dir);

+        ziinit.add_position_when_writting_offset = byte_before_the_zipfile;

+

+        {

+            uLong size_central_dir_to_read = size_central_dir;

+            size_t buf_size = SIZEDATA_INDATABLOCK;

+            void* buf_read = (void*)ALLOC(buf_size);

+            if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,

+                  offset_central_dir + byte_before_the_zipfile,

+                  ZLIB_FILEFUNC_SEEK_SET) != 0)

+                  err=ZIP_ERRNO;

+

+            while ((size_central_dir_to_read>0) && (err==ZIP_OK))

+            {

+                uLong read_this = SIZEDATA_INDATABLOCK;

+                if (read_this > size_central_dir_to_read)

+                    read_this = size_central_dir_to_read;

+                if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)

+                    err=ZIP_ERRNO;

+

+                if (err==ZIP_OK)

+                    err = add_data_in_datablock(&ziinit.central_dir,buf_read,

+                                                (uLong)read_this);

+                size_central_dir_to_read-=read_this;

+            }

+            TRYFREE(buf_read);

+        }

+        ziinit.begin_pos = byte_before_the_zipfile;

+        ziinit.number_entry = number_entry_CD;

+

+        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,

+                  offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            err=ZIP_ERRNO;

+    }

+

+    if (globalcomment)

+    {

+      *globalcomment = ziinit.globalcomment;

+    }

+#    endif /* !NO_ADDFILEINEXISTINGZIP*/

+

+    if (err != ZIP_OK)

+    {

+#    ifndef NO_ADDFILEINEXISTINGZIP

+        TRYFREE(ziinit.globalcomment);

+#    endif /* !NO_ADDFILEINEXISTINGZIP*/

+        TRYFREE(zi);

+        return NULL;

+    }

+    else

+    {

+        *zi = ziinit;

+        return (zipFile)zi;

+    }

+}

+

+extern zipFile ZEXPORT zipOpen (pathname, append)

+    const char *pathname;

+    int append;

+{

+    return zipOpen2(pathname,append,NULL,NULL);

+}

+

+extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,

+                                         extrafield_local, size_extrafield_local,

+                                         extrafield_global, size_extrafield_global,

+                                         comment, method, level, raw,

+                                         windowBits, memLevel, strategy,

+                                         password, crcForCrypting)

+    zipFile file;

+    const char* filename;

+    const zip_fileinfo* zipfi;

+    const void* extrafield_local;

+    uInt size_extrafield_local;

+    const void* extrafield_global;

+    uInt size_extrafield_global;

+    const char* comment;

+    int method;

+    int level;

+    int raw;

+    int windowBits;

+    int memLevel;

+    int strategy;

+    const char* password;

+    uLong crcForCrypting;

+{

+    zip_internal* zi;

+    uInt size_filename;

+    uInt size_comment;

+    uInt i;

+    int err = ZIP_OK;

+

+#    ifdef NOCRYPT

+    if (password != NULL)

+        return ZIP_PARAMERROR;

+#    endif

+

+    if (file == NULL)

+        return ZIP_PARAMERROR;

+    if ((method!=0) && (method!=Z_DEFLATED))

+        return ZIP_PARAMERROR;

+

+    zi = (zip_internal*)file;

+

+    if (zi->in_opened_file_inzip == 1)

+    {

+        err = zipCloseFileInZip (file);

+        if (err != ZIP_OK)

+            return err;

+    }

+

+

+    if (filename==NULL)

+        filename="-";

+

+    if (comment==NULL)

+        size_comment = 0;

+    else

+        size_comment = (uInt)strlen(comment);

+

+    size_filename = (uInt)strlen(filename);

+

+    if (zipfi == NULL)

+        zi->ci.dosDate = 0;

+    else

+    {

+        if (zipfi->dosDate != 0)

+            zi->ci.dosDate = zipfi->dosDate;

+        else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);

+    }

+

+    zi->ci.flag = 0;

+    if ((level==8) || (level==9))

+      zi->ci.flag |= 2;

+    if ((level==2))

+      zi->ci.flag |= 4;

+    if ((level==1))

+      zi->ci.flag |= 6;

+    if (password != NULL)

+      zi->ci.flag |= 1;

+

+    zi->ci.crc32 = 0;

+    zi->ci.method = method;

+    zi->ci.encrypt = 0;

+    zi->ci.stream_initialised = 0;

+    zi->ci.pos_in_buffered_data = 0;

+    zi->ci.raw = raw;

+    zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;

+    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +

+                                      size_extrafield_global + size_comment;

+    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);

+

+    ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);

+    /* version info */

+    ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);

+    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/

+    ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/

+    ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/

+    ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/

+

+    if (zipfi==NULL)

+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);

+    else

+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);

+

+    if (zipfi==NULL)

+        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);

+    else

+        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);

+

+    ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);

+

+    for (i=0;i<size_filename;i++)

+        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);

+

+    for (i=0;i<size_extrafield_global;i++)

+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =

+              *(((const char*)extrafield_global)+i);

+

+    for (i=0;i<size_comment;i++)

+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+

+              size_extrafield_global+i) = *(comment+i);

+    if (zi->ci.central_header == NULL)

+        return ZIP_INTERNALERROR;

+

+    /* write the local header */

+    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);

+

+    if (err==ZIP_OK)

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);

+

+    if ((err==ZIP_OK) && (size_filename>0))

+        if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)

+                err = ZIP_ERRNO;

+

+    if ((err==ZIP_OK) && (size_extrafield_local>0))

+        if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)

+                                                                           !=size_extrafield_local)

+                err = ZIP_ERRNO;

+

+    zi->ci.stream.avail_in = (uInt)0;

+    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;

+    zi->ci.stream.next_out = zi->ci.buffered_data;

+    zi->ci.stream.total_in = 0;

+    zi->ci.stream.total_out = 0;

+

+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))

+    {

+        zi->ci.stream.zalloc = (alloc_func)0;

+        zi->ci.stream.zfree = (free_func)0;

+        zi->ci.stream.opaque = (voidpf)0;

+

+        if (windowBits>0)

+            windowBits = -windowBits;

+

+        err = deflateInit2(&zi->ci.stream, level,

+               Z_DEFLATED, windowBits, memLevel, strategy);

+

+        if (err==Z_OK)

+            zi->ci.stream_initialised = 1;

+    }

+#    ifndef NOCRYPT

+    zi->ci.crypt_header_size = 0;

+    if ((err==Z_OK) && (password != NULL))

+    {

+        unsigned char bufHead[RAND_HEAD_LEN];

+        unsigned int sizeHead;

+        zi->ci.encrypt = 1;

+        zi->ci.pcrc_32_tab = get_crc_table();

+        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/

+

+        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);

+        zi->ci.crypt_header_size = sizeHead;

+

+        if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)

+                err = ZIP_ERRNO;

+    }

+#    endif

+

+    if (err==Z_OK)

+        zi->in_opened_file_inzip = 1;

+    return err;

+}

+

+extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,

+                                        extrafield_local, size_extrafield_local,

+                                        extrafield_global, size_extrafield_global,

+                                        comment, method, level, raw)

+    zipFile file;

+    const char* filename;

+    const zip_fileinfo* zipfi;

+    const void* extrafield_local;

+    uInt size_extrafield_local;

+    const void* extrafield_global;

+    uInt size_extrafield_global;

+    const char* comment;

+    int method;

+    int level;

+    int raw;

+{

+    return zipOpenNewFileInZip3 (file, filename, zipfi,

+                                 extrafield_local, size_extrafield_local,

+                                 extrafield_global, size_extrafield_global,

+                                 comment, method, level, raw,

+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,

+                                 NULL, 0);

+}

+

+extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,

+                                        extrafield_local, size_extrafield_local,

+                                        extrafield_global, size_extrafield_global,

+                                        comment, method, level)

+    zipFile file;

+    const char* filename;

+    const zip_fileinfo* zipfi;

+    const void* extrafield_local;

+    uInt size_extrafield_local;

+    const void* extrafield_global;

+    uInt size_extrafield_global;

+    const char* comment;

+    int method;

+    int level;

+{

+    return zipOpenNewFileInZip2 (file, filename, zipfi,

+                                 extrafield_local, size_extrafield_local,

+                                 extrafield_global, size_extrafield_global,

+                                 comment, method, level, 0);

+}

+

+local int zipFlushWriteBuffer(zi)

+  zip_internal* zi;

+{

+    int err=ZIP_OK;

+

+    if (zi->ci.encrypt != 0)

+    {

+#ifndef NOCRYPT

+        uInt i;

+        int t;

+        for (i=0;i<zi->ci.pos_in_buffered_data;i++)

+            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,

+                                       zi->ci.buffered_data[i],t);

+#endif

+    }

+    if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)

+                                                                    !=zi->ci.pos_in_buffered_data)

+      err = ZIP_ERRNO;

+    zi->ci.pos_in_buffered_data = 0;

+    return err;

+}

+

+extern int ZEXPORT zipWriteInFileInZip (file, buf, len)

+    zipFile file;

+    const void* buf;

+    unsigned len;

+{

+    zip_internal* zi;

+    int err=ZIP_OK;

+

+    if (file == NULL)

+        return ZIP_PARAMERROR;

+    zi = (zip_internal*)file;

+

+    if (zi->in_opened_file_inzip == 0)

+        return ZIP_PARAMERROR;

+

+    zi->ci.stream.next_in = (void*)buf;

+    zi->ci.stream.avail_in = len;

+    zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);

+

+    while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))

+    {

+        if (zi->ci.stream.avail_out == 0)

+        {

+            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)

+                err = ZIP_ERRNO;

+            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;

+            zi->ci.stream.next_out = zi->ci.buffered_data;

+        }

+

+

+        if(err != ZIP_OK)

+            break;

+

+        if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))

+        {

+            uLong uTotalOutBefore = zi->ci.stream.total_out;

+            err=deflate(&zi->ci.stream,  Z_NO_FLUSH);

+            zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;

+

+        }

+        else

+        {

+            uInt copy_this,i;

+            if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)

+                copy_this = zi->ci.stream.avail_in;

+            else

+                copy_this = zi->ci.stream.avail_out;

+            for (i=0;i<copy_this;i++)

+                *(((char*)zi->ci.stream.next_out)+i) =

+                    *(((const char*)zi->ci.stream.next_in)+i);

+            {

+                zi->ci.stream.avail_in -= copy_this;

+                zi->ci.stream.avail_out-= copy_this;

+                zi->ci.stream.next_in+= copy_this;

+                zi->ci.stream.next_out+= copy_this;

+                zi->ci.stream.total_in+= copy_this;

+                zi->ci.stream.total_out+= copy_this;

+                zi->ci.pos_in_buffered_data += copy_this;

+            }

+        }

+    }

+

+    return err;

+}

+

+extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)

+    zipFile file;

+    uLong uncompressed_size;

+    uLong crc32;

+{

+    zip_internal* zi;

+    uLong compressed_size;

+    int err=ZIP_OK;

+

+    if (file == NULL)

+        return ZIP_PARAMERROR;

+    zi = (zip_internal*)file;

+

+    if (zi->in_opened_file_inzip == 0)

+        return ZIP_PARAMERROR;

+    zi->ci.stream.avail_in = 0;

+

+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))

+        while (err==ZIP_OK)

+    {

+        uLong uTotalOutBefore;

+        if (zi->ci.stream.avail_out == 0)

+        {

+            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)

+                err = ZIP_ERRNO;

+            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;

+            zi->ci.stream.next_out = zi->ci.buffered_data;

+        }

+        uTotalOutBefore = zi->ci.stream.total_out;

+        err=deflate(&zi->ci.stream,  Z_FINISH);

+        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;

+    }

+

+    if (err==Z_STREAM_END)

+        err=ZIP_OK; /* this is normal */

+

+    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))

+        if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)

+            err = ZIP_ERRNO;

+

+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))

+    {

+        err=deflateEnd(&zi->ci.stream);

+        zi->ci.stream_initialised = 0;

+    }

+

+    if (!zi->ci.raw)

+    {

+        crc32 = (uLong)zi->ci.crc32;

+        uncompressed_size = (uLong)zi->ci.stream.total_in;

+    }

+    compressed_size = (uLong)zi->ci.stream.total_out;

+#    ifndef NOCRYPT

+    compressed_size += zi->ci.crypt_header_size;

+#    endif

+

+    ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/

+    ziplocal_putValue_inmemory(zi->ci.central_header+20,

+                                compressed_size,4); /*compr size*/

+    if (zi->ci.stream.data_type == Z_ASCII)

+        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);

+    ziplocal_putValue_inmemory(zi->ci.central_header+24,

+                                uncompressed_size,4); /*uncompr size*/

+

+    if (err==ZIP_OK)

+        err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,

+                                       (uLong)zi->ci.size_centralheader);

+    free(zi->ci.central_header);

+

+    if (err==ZIP_OK)

+    {

+        long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);

+        if (ZSEEK(zi->z_filefunc,zi->filestream,

+                  zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            err = ZIP_ERRNO;

+

+        if (err==ZIP_OK)

+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */

+

+        if (err==ZIP_OK) /* compressed size, unknown */

+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);

+

+        if (err==ZIP_OK) /* uncompressed size, unknown */

+            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);

+

+        if (ZSEEK(zi->z_filefunc,zi->filestream,

+                  cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)

+            err = ZIP_ERRNO;

+    }

+

+    zi->number_entry ++;

+    zi->in_opened_file_inzip = 0;

+

+    return err;

+}

+

+extern int ZEXPORT zipCloseFileInZip (file)

+    zipFile file;

+{

+    return zipCloseFileInZipRaw (file,0,0);

+}

+

+extern int ZEXPORT zipClose (file, global_comment)

+    zipFile file;

+    const char* global_comment;

+{

+    zip_internal* zi;

+    int err = 0;

+    uLong size_centraldir = 0;

+    uLong centraldir_pos_inzip;

+    uInt size_global_comment;

+    if (file == NULL)

+        return ZIP_PARAMERROR;

+    zi = (zip_internal*)file;

+

+    if (zi->in_opened_file_inzip == 1)

+    {

+        err = zipCloseFileInZip (file);

+    }

+

+#ifndef NO_ADDFILEINEXISTINGZIP

+    if (global_comment==NULL)

+        global_comment = zi->globalcomment;

+#endif

+    if (global_comment==NULL)

+        size_global_comment = 0;

+    else

+        size_global_comment = (uInt)strlen(global_comment);

+

+    centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);

+    if (err==ZIP_OK)

+    {

+        linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;

+        while (ldi!=NULL)

+        {

+            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))

+                if (ZWRITE(zi->z_filefunc,zi->filestream,

+                           ldi->data,ldi->filled_in_this_block)

+                              !=ldi->filled_in_this_block )

+                    err = ZIP_ERRNO;

+

+            size_centraldir += ldi->filled_in_this_block;

+            ldi = ldi->next_datablock;

+        }

+    }

+    free_datablock(zi->central_dir.first_block);

+

+    if (err==ZIP_OK) /* Magic End */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);

+

+    if (err==ZIP_OK) /* number of this disk */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);

+

+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);

+

+    if (err==ZIP_OK) /* total number of entries in the central dir on this disk */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);

+

+    if (err==ZIP_OK) /* total number of entries in the central dir */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);

+

+    if (err==ZIP_OK) /* size of the central directory */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);

+

+    if (err==ZIP_OK) /* offset of start of central directory with respect to the

+                            starting disk number */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,

+                                (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);

+

+    if (err==ZIP_OK) /* zipfile comment length */

+        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);

+

+    if ((err==ZIP_OK) && (size_global_comment>0))

+        if (ZWRITE(zi->z_filefunc,zi->filestream,

+                   global_comment,size_global_comment) != size_global_comment)

+                err = ZIP_ERRNO;

+

+    if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)

+        if (err == ZIP_OK)

+            err = ZIP_ERRNO;

+

+#ifndef NO_ADDFILEINEXISTINGZIP

+    TRYFREE(zi->globalcomment);

+#endif

+    TRYFREE(zi);

+

+    return err;

+}

diff --git a/contrib/minizip/zip.h b/contrib/minizip/zip.h
index d5112c4..cd38b67 100644
--- a/contrib/minizip/zip.h
+++ b/contrib/minizip/zip.h
@@ -1,234 +1,235 @@
-/* zip.h -- IO for compress .zip files using zlib
-   Version 1.01, May 8th, 2004
-
-   Copyright (C) 1998-2004 Gilles Vollant
-
-   This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
-     WinZip, InfoZip tools and compatible.
-   Encryption and multi volume ZipFile (span) are not supported.
-   Old compressions used by old PKZip 1.x are not supported
-
-  For uncompress .zip file, look at unzip.h
-
-
-   I WAIT FEEDBACK at mail info@winimage.com
-   Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
-
-   Condition of use and distribution are the same than zlib :
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
-      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
-      http://www.info-zip.org/pub/infozip/doc/
-   PkWare has also a specification at :
-      ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _zip_H
-#define _zip_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
-    from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK                          (0)
-#define ZIP_EOF                         (0)
-#define ZIP_ERRNO                       (Z_ERRNO)
-#define ZIP_PARAMERROR                  (-102)
-#define ZIP_BADZIPFILE                  (-103)
-#define ZIP_INTERNALERROR               (-104)
-
-#ifndef DEF_MEM_LEVEL
-#  if MAX_MEM_LEVEL >= 8
-#    define DEF_MEM_LEVEL 8
-#  else
-#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#  endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
-    uInt tm_sec;            /* seconds after the minute - [0,59] */
-    uInt tm_min;            /* minutes after the hour - [0,59] */
-    uInt tm_hour;           /* hours since midnight - [0,23] */
-    uInt tm_mday;           /* day of the month - [1,31] */
-    uInt tm_mon;            /* months since January - [0,11] */
-    uInt tm_year;           /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
-    tm_zip      tmz_date;       /* date in understandable format           */
-    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
-/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
-
-    uLong       internal_fa;    /* internal file attributes        2 bytes */
-    uLong       external_fa;    /* external file attributes        4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE        (0)
-#define APPEND_STATUS_CREATEAFTER   (1)
-#define APPEND_STATUS_ADDINZIP      (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-/*
-  Create a zipfile.
-     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
-       an Unix computer "zlib/zlib113.zip".
-     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
-       will be created at the end of the file.
-         (useful if the file contain a self extractor code)
-     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
-       add files in existing zip (be sure you don't add file that doesn't exist)
-     If the zipfile cannot be opened, the return value is NULL.
-     Else, the return value is a zipFile Handle, usable with other function
-       of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
-   If you want delete file into a zipfile, you must open a zipfile, and create another
-   Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
-                                   int append,
-                                   zipcharpc* globalcomment,
-                                   zlib_filefunc_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
-                       const char* filename,
-                       const zip_fileinfo* zipfi,
-                       const void* extrafield_local,
-                       uInt size_extrafield_local,
-                       const void* extrafield_global,
-                       uInt size_extrafield_global,
-                       const char* comment,
-                       int method,
-                       int level));
-/*
-  Open a file in the ZIP for writing.
-  filename : the filename in zip (if NULL, '-' without quote will be used
-  *zipfi contain supplemental information
-  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
-    contains the extrafield data the the local header
-  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
-    contains the extrafield data the the local header
-  if comment != NULL, comment contain the comment string
-  method contain the compression method (0 for store, Z_DEFLATED for deflate)
-  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw));
-
-/*
-  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
-                                            const char* filename,
-                                            const zip_fileinfo* zipfi,
-                                            const void* extrafield_local,
-                                            uInt size_extrafield_local,
-                                            const void* extrafield_global,
-                                            uInt size_extrafield_global,
-                                            const char* comment,
-                                            int method,
-                                            int level,
-                                            int raw,
-                                            int windowBits,
-                                            int memLevel,
-                                            int strategy,
-                                            const char* password,
-                                            uLong crcForCtypting));
-
-/*
-  Same than zipOpenNewFileInZip2, except
-    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
-    password : crypting password (NULL for no crypting)
-    crcForCtypting : crc of file to compress (needed for crypting)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
-                       const void* buf,
-                       unsigned len));
-/*
-  Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
-  Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
-                                            uLong uncompressed_size,
-                                            uLong crc32));
-/*
-  Close the current file in the zipfile, for fiel opened with
-    parameter raw=1 in zipOpenNewFileInZip2
-  uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
-                const char* global_comment));
-/*
-  Close the zipfile
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip_H */
+/* zip.h -- IO for compress .zip files using zlib

+   Version 1.01e, February 12th, 2005

+

+   Copyright (C) 1998-2005 Gilles Vollant

+

+   This unzip package allow creates .ZIP file, compatible with PKZip 2.04g

+     WinZip, InfoZip tools and compatible.

+   Multi volume ZipFile (span) are not supported.

+   Encryption compatible with pkzip 2.04g only supported

+   Old compressions used by old PKZip 1.x are not supported

+

+  For uncompress .zip file, look at unzip.h

+

+

+   I WAIT FEEDBACK at mail info@winimage.com

+   Visit also http://www.winimage.com/zLibDll/unzip.html for evolution

+

+   Condition of use and distribution are the same than zlib :

+

+  This software is provided 'as-is', without any express or implied

+  warranty.  In no event will the authors be held liable for any damages

+  arising from the use of this software.

+

+  Permission is granted to anyone to use this software for any purpose,

+  including commercial applications, and to alter it and redistribute it

+  freely, subject to the following restrictions:

+

+  1. The origin of this software must not be misrepresented; you must not

+     claim that you wrote the original software. If you use this software

+     in a product, an acknowledgment in the product documentation would be

+     appreciated but is not required.

+  2. Altered source versions must be plainly marked as such, and must not be

+     misrepresented as being the original software.

+  3. This notice may not be removed or altered from any source distribution.

+

+

+*/

+

+/* for more info about .ZIP format, see

+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip

+      http://www.info-zip.org/pub/infozip/doc/

+   PkWare has also a specification at :

+      ftp://ftp.pkware.com/probdesc.zip

+*/

+

+#ifndef _zip_H

+#define _zip_H

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#ifndef _ZLIB_H

+#include "zlib.h"

+#endif

+

+#ifndef _ZLIBIOAPI_H

+#include "ioapi.h"

+#endif

+

+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)

+/* like the STRICT of WIN32, we define a pointer that cannot be converted

+    from (void*) without cast */

+typedef struct TagzipFile__ { int unused; } zipFile__;

+typedef zipFile__ *zipFile;

+#else

+typedef voidp zipFile;

+#endif

+

+#define ZIP_OK                          (0)

+#define ZIP_EOF                         (0)

+#define ZIP_ERRNO                       (Z_ERRNO)

+#define ZIP_PARAMERROR                  (-102)

+#define ZIP_BADZIPFILE                  (-103)

+#define ZIP_INTERNALERROR               (-104)

+

+#ifndef DEF_MEM_LEVEL

+#  if MAX_MEM_LEVEL >= 8

+#    define DEF_MEM_LEVEL 8

+#  else

+#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL

+#  endif

+#endif

+/* default memLevel */

+

+/* tm_zip contain date/time info */

+typedef struct tm_zip_s

+{

+    uInt tm_sec;            /* seconds after the minute - [0,59] */

+    uInt tm_min;            /* minutes after the hour - [0,59] */

+    uInt tm_hour;           /* hours since midnight - [0,23] */

+    uInt tm_mday;           /* day of the month - [1,31] */

+    uInt tm_mon;            /* months since January - [0,11] */

+    uInt tm_year;           /* years - [1980..2044] */

+} tm_zip;

+

+typedef struct

+{

+    tm_zip      tmz_date;       /* date in understandable format           */

+    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */

+/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */

+

+    uLong       internal_fa;    /* internal file attributes        2 bytes */

+    uLong       external_fa;    /* external file attributes        4 bytes */

+} zip_fileinfo;

+

+typedef const char* zipcharpc;

+

+

+#define APPEND_STATUS_CREATE        (0)

+#define APPEND_STATUS_CREATEAFTER   (1)

+#define APPEND_STATUS_ADDINZIP      (2)

+

+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));

+/*

+  Create a zipfile.

+     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on

+       an Unix computer "zlib/zlib113.zip".

+     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip

+       will be created at the end of the file.

+         (useful if the file contain a self extractor code)

+     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will

+       add files in existing zip (be sure you don't add file that doesn't exist)

+     If the zipfile cannot be opened, the return value is NULL.

+     Else, the return value is a zipFile Handle, usable with other function

+       of this zip package.

+*/

+

+/* Note : there is no delete function into a zipfile.

+   If you want delete file into a zipfile, you must open a zipfile, and create another

+   Of couse, you can use RAW reading and writing to copy the file you did not want delte

+*/

+

+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,

+                                   int append,

+                                   zipcharpc* globalcomment,

+                                   zlib_filefunc_def* pzlib_filefunc_def));

+

+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,

+                       const char* filename,

+                       const zip_fileinfo* zipfi,

+                       const void* extrafield_local,

+                       uInt size_extrafield_local,

+                       const void* extrafield_global,

+                       uInt size_extrafield_global,

+                       const char* comment,

+                       int method,

+                       int level));

+/*

+  Open a file in the ZIP for writing.

+  filename : the filename in zip (if NULL, '-' without quote will be used

+  *zipfi contain supplemental information

+  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local

+    contains the extrafield data the the local header

+  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global

+    contains the extrafield data the the local header

+  if comment != NULL, comment contain the comment string

+  method contain the compression method (0 for store, Z_DEFLATED for deflate)

+  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)

+*/

+

+

+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,

+                                            const char* filename,

+                                            const zip_fileinfo* zipfi,

+                                            const void* extrafield_local,

+                                            uInt size_extrafield_local,

+                                            const void* extrafield_global,

+                                            uInt size_extrafield_global,

+                                            const char* comment,

+                                            int method,

+                                            int level,

+                                            int raw));

+

+/*

+  Same than zipOpenNewFileInZip, except if raw=1, we write raw file

+ */

+

+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,

+                                            const char* filename,

+                                            const zip_fileinfo* zipfi,

+                                            const void* extrafield_local,

+                                            uInt size_extrafield_local,

+                                            const void* extrafield_global,

+                                            uInt size_extrafield_global,

+                                            const char* comment,

+                                            int method,

+                                            int level,

+                                            int raw,

+                                            int windowBits,

+                                            int memLevel,

+                                            int strategy,

+                                            const char* password,

+                                            uLong crcForCtypting));

+

+/*

+  Same than zipOpenNewFileInZip2, except

+    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2

+    password : crypting password (NULL for no crypting)

+    crcForCtypting : crc of file to compress (needed for crypting)

+ */

+

+

+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,

+                       const void* buf,

+                       unsigned len));

+/*

+  Write data in the zipfile

+*/

+

+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));

+/*

+  Close the current file in the zipfile

+*/

+

+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,

+                                            uLong uncompressed_size,

+                                            uLong crc32));

+/*

+  Close the current file in the zipfile, for fiel opened with

+    parameter raw=1 in zipOpenNewFileInZip2

+  uncompressed_size and crc32 are value for the uncompressed size

+*/

+

+extern int ZEXPORT zipClose OF((zipFile file,

+                const char* global_comment));

+/*

+  Close the zipfile

+*/

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* _zip_H */

diff --git a/contrib/testzlib/rdtsc64.asm b/contrib/testzlib/rdtsc64.asm
new file mode 100644
index 0000000..6b78a8b
--- /dev/null
+++ b/contrib/testzlib/rdtsc64.asm
@@ -0,0 +1,18 @@
+; rdtsc64.asm

+;

+; unsigned _int64 myrdtsc();

+;

+; return the performance rdtsc value, on AMD64/Intel EM64T

+;

+; compile with :

+;    ml64.exe" /Flrdtsc64   /c /Zi rdtsc64.asm

+;

+.code

+myrdtsc PROC

+          rdtsc

+          shl rdx,32

+          or rax,rdx

+          ret

+myrdtsc ENDP

+

+END

diff --git a/contrib/testzlib/rdtsc64.obj b/contrib/testzlib/rdtsc64.obj
new file mode 100644
index 0000000..7905142
--- /dev/null
+++ b/contrib/testzlib/rdtsc64.obj
Binary files differ
diff --git a/contrib/testzlib/testzlib.c b/contrib/testzlib/testzlib.c
index fdabc5c..6c3ff9f 100644
--- a/contrib/testzlib/testzlib.c
+++ b/contrib/testzlib/testzlib.c
@@ -1,149 +1,258 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-#include "zlib.h"
-
-int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
-{
-    FILE* stream;
-    void* ptr;
-    int retVal=1;
-    stream=fopen(filename, "rb");
-    if (stream==NULL)
-        return 0;
-
-    fseek(stream,0,SEEK_END);
-
-    *plFileSize=ftell(stream);
-    fseek(stream,0,SEEK_SET);
-    ptr=malloc((*plFileSize)+1);
-    if (ptr==NULL)
-        retVal=0;
-    else
-    {
-        if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
-            retVal=0;
-    }
-    fclose(stream);
-    *pFilePtr=ptr;
-    return retVal;
-}
-
-int main(int argc, char *argv[])
-{
-    int BlockSizeCompress=0x8000;
-    int BlockSizeUncompress=0x8000;
-    int cprLevel=Z_DEFAULT_COMPRESSION ;
-    long lFileSize;
-    unsigned char* FilePtr;
-    long lBufferSizeCpr;
-    long lBufferSizeUncpr;
-    long lCompressedSize=0;
-    unsigned char* CprPtr;
-    unsigned char* UncprPtr;
-    long lSizeCpr,lSizeUncpr;
-    DWORD dwGetTick;
-
-    if (argc<=1)
-    {
-        printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
-        return 0;
-    }
-
-    if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
-    {
-        printf("error reading %s\n",argv[1]);
-        return 1;
-    }
-    else printf("file %s read, %u bytes\n",argv[1],lFileSize);
-
-    if (argc>=3)
-        BlockSizeCompress=atol(argv[2]);
-
-    if (argc>=4)
-        BlockSizeUncompress=atol(argv[3]);
-
-    if (argc>=5)
-        cprLevel=(int)atol(argv[4]);
-
-    lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
-    lBufferSizeUncpr = lBufferSizeCpr;
-
-    CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
-    UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
-
-    dwGetTick=GetTickCount();
-    {
-        z_stream zcpr;
-        int ret=Z_OK;
-        long lOrigToDo = lFileSize;
-        long lOrigDone = 0;
-        int step=0;
-        memset(&zcpr,0,sizeof(z_stream));
-        deflateInit(&zcpr,cprLevel);
-
-        zcpr.next_in = FilePtr;
-        zcpr.next_out = CprPtr;
-
-
-        do
-        {
-            long all_read_before = zcpr.total_in;
-            zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
-            zcpr.avail_out = BlockSizeCompress;
-            ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
-            lOrigDone += (zcpr.total_in-all_read_before);
-            lOrigToDo -= (zcpr.total_in-all_read_before);
-            step++;
-        } while (ret==Z_OK);
-
-        lSizeCpr=zcpr.total_out;
-        deflateEnd(&zcpr);
-        dwGetTick=GetTickCount()-dwGetTick;
-        printf("total compress size = %u, in %u step\n",lSizeCpr,step);
-        printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
-    }
-
-    dwGetTick=GetTickCount();
-    {
-        z_stream zcpr;
-        int ret=Z_OK;
-        long lOrigToDo = lSizeCpr;
-        long lOrigDone = 0;
-        int step=0;
-        memset(&zcpr,0,sizeof(z_stream));
-        inflateInit(&zcpr);
-
-        zcpr.next_in = CprPtr;
-        zcpr.next_out = UncprPtr;
-
-
-        do
-        {
-            long all_read_before = zcpr.total_in;
-            zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
-            zcpr.avail_out = BlockSizeUncompress;
-            ret=inflate(&zcpr,Z_SYNC_FLUSH);
-            lOrigDone += (zcpr.total_in-all_read_before);
-            lOrigToDo -= (zcpr.total_in-all_read_before);
-            step++;
-        } while (ret==Z_OK);
-
-        lSizeUncpr=zcpr.total_out;
-        inflateEnd(&zcpr);
-        dwGetTick=GetTickCount()-dwGetTick;
-        printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
-        printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
-    }
-
-    if (lSizeUncpr==lFileSize)
-    {
-        if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
-            printf("compare ok\n");
-
-    }
-
-    return 0;
-
-}
+

+#include <stdio.h>

+#include <stdlib.h>

+#include <windows.h>

+#include "zlib.h"

+

+

+void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)

+{

+    R->HighPart = A.HighPart - B.HighPart;

+    if (A.LowPart >= B.LowPart)

+        R->LowPart = A.LowPart - B.LowPart;

+    else

+    {

+        R->LowPart = A.LowPart - B.LowPart;

+        R->HighPart --;

+    }

+}

+

+#ifdef _AMD64_

+unsigned _int64 myrdtsc();

+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)

+{

+ //   printf("rdtsc = %I64x\n",myrdtsc());

+   pbeginTime64->QuadPart=myrdtsc();

+}

+

+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)

+{

+    LARGE_INTEGER LIres;

+    unsigned _int64 res=myrdtsc()-((unsigned _int64)(beginTime64.QuadPart));

+    LIres.QuadPart=res;

+   // printf("rdtsc = %I64x\n",myrdtsc());

+    return LIres;

+}

+#else

+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)

+{

+    DWORD dwEdx,dwEax;

+    _asm

+    {

+        rdtsc

+        mov dwEax,eax

+        mov dwEdx,edx

+    }

+    pbeginTime64->LowPart=dwEax;

+    pbeginTime64->HighPart=dwEdx;

+}

+

+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)

+{

+    myGetRDTSC32(pbeginTime64);

+}

+

+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)

+{

+    LARGE_INTEGER LIres,endTime64;

+    myGetRDTSC32(&endTime64);

+

+    LIres.LowPart=LIres.HighPart=0;

+    MyDoMinus64(&LIres,endTime64,beginTime64);

+    return LIres;

+}

+#endif

+

+

+void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)

+{

+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))

+    {

+        pbeginTime64->LowPart = GetTickCount();

+        pbeginTime64->HighPart = 0;

+    }

+}

+

+DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)

+{

+    LARGE_INTEGER endTime64,ticksPerSecond,ticks;

+    DWORDLONG ticksShifted,tickSecShifted;

+    DWORD dwLog=16+0;

+    DWORD dwRet;

+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))

+        dwRet = (GetTickCount() - beginTime64.LowPart)*1;

+    else

+    {

+        MyDoMinus64(&ticks,endTime64,beginTime64);

+        QueryPerformanceFrequency(&ticksPerSecond);

+

+    

+        {

+            ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);

+            tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);

+        

+        } 

+

+        dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));

+        dwRet *=1;

+    }

+    return dwRet;

+}

+

+int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)

+{

+    FILE* stream;

+    void* ptr;

+    int retVal=1;

+    stream=fopen(filename, "rb");

+    if (stream==NULL)

+        return 0;

+

+    fseek(stream,0,SEEK_END);

+

+    *plFileSize=ftell(stream);

+    fseek(stream,0,SEEK_SET);

+    ptr=malloc((*plFileSize)+1);

+    if (ptr==NULL)

+        retVal=0;

+    else

+    {

+        if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))

+            retVal=0;

+    }

+    fclose(stream);

+    *pFilePtr=ptr;

+    return retVal;

+}

+

+int main(int argc, char *argv[])

+{

+    int BlockSizeCompress=0x8000;

+    int BlockSizeUncompress=0x8000;

+    int cprLevel=Z_DEFAULT_COMPRESSION ;

+    long lFileSize;

+    unsigned char* FilePtr;

+    long lBufferSizeCpr;

+    long lBufferSizeUncpr;

+    long lCompressedSize=0;

+    unsigned char* CprPtr;

+    unsigned char* UncprPtr;

+    long lSizeCpr,lSizeUncpr;

+    DWORD dwGetTick,dwMsecQP;

+    LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;

+

+    if (argc<=1)

+    {

+        printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");

+        return 0;

+    }

+

+    if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)

+    {

+        printf("error reading %s\n",argv[1]);

+        return 1;

+    }

+    else printf("file %s read, %u bytes\n",argv[1],lFileSize);

+

+    if (argc>=3)

+        BlockSizeCompress=atol(argv[2]);

+

+    if (argc>=4)

+        BlockSizeUncompress=atol(argv[3]);

+

+    if (argc>=5)

+        cprLevel=(int)atol(argv[4]);

+

+    lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;

+    lBufferSizeUncpr = lBufferSizeCpr;

+

+    CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);

+

+    BeginCountPerfCounter(&li_qp,TRUE);

+    dwGetTick=GetTickCount();

+    BeginCountRdtsc(&li_rdtsc);

+    {

+        z_stream zcpr;

+        int ret=Z_OK;

+        long lOrigToDo = lFileSize;

+        long lOrigDone = 0;

+        int step=0;

+        memset(&zcpr,0,sizeof(z_stream));

+        deflateInit(&zcpr,cprLevel);

+

+        zcpr.next_in = FilePtr;

+        zcpr.next_out = CprPtr;

+

+

+        do

+        {

+            long all_read_before = zcpr.total_in;

+            zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);

+            zcpr.avail_out = BlockSizeCompress;

+            ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);

+            lOrigDone += (zcpr.total_in-all_read_before);

+            lOrigToDo -= (zcpr.total_in-all_read_before);

+            step++;

+        } while (ret==Z_OK);

+

+        lSizeCpr=zcpr.total_out;

+        deflateEnd(&zcpr);

+        dwGetTick=GetTickCount()-dwGetTick;

+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);

+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);

+        printf("total compress size = %u, in %u step\n",lSizeCpr,step);

+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);

+        printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);

+        printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);

+    }

+

+    CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);

+    UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);

+

+    BeginCountPerfCounter(&li_qp,TRUE);

+    dwGetTick=GetTickCount();

+    BeginCountRdtsc(&li_rdtsc);

+    {

+        z_stream zcpr;

+        int ret=Z_OK;

+        long lOrigToDo = lSizeCpr;

+        long lOrigDone = 0;

+        int step=0;

+        memset(&zcpr,0,sizeof(z_stream));

+        inflateInit(&zcpr);

+

+        zcpr.next_in = CprPtr;

+        zcpr.next_out = UncprPtr;

+

+

+        do

+        {

+            long all_read_before = zcpr.total_in;

+            zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);

+            zcpr.avail_out = BlockSizeUncompress;

+            ret=inflate(&zcpr,Z_SYNC_FLUSH);

+            lOrigDone += (zcpr.total_in-all_read_before);

+            lOrigToDo -= (zcpr.total_in-all_read_before);

+            step++;

+        } while (ret==Z_OK);

+

+        lSizeUncpr=zcpr.total_out;

+        inflateEnd(&zcpr);

+        dwGetTick=GetTickCount()-dwGetTick;

+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);

+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);

+        printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);

+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);

+        printf("uncpr  time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);

+        printf("uncpr  result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);

+    }

+

+    if (lSizeUncpr==lFileSize)

+    {

+        if (memcmp(FilePtr,UncprPtr,lFileSize)==0)

+            printf("compare ok\n");

+

+    }

+

+    return 0;

+}

diff --git a/contrib/testzlib/testzlib.txt b/contrib/testzlib/testzlib.txt
new file mode 100644
index 0000000..62258f1
--- /dev/null
+++ b/contrib/testzlib/testzlib.txt
@@ -0,0 +1,10 @@
+To build testzLib with Visual Studio 2005:

+

+copy to a directory file from :

+- root of zLib tree

+- contrib/testzlib

+- contrib/masmx86

+- contrib/masmx64

+- contrib/vstudio/vc7

+

+and open testzlib8.sln
\ No newline at end of file
diff --git a/contrib/testzlib/testzlib8.sln b/contrib/testzlib/testzlib8.sln
new file mode 100644
index 0000000..794f72d
--- /dev/null
+++ b/contrib/testzlib/testzlib8.sln
@@ -0,0 +1,32 @@
+

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib8", "testzlib8.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Debug|Win64 (AMD64) = Debug|Win64 (AMD64)

+		Release|Win32 = Release|Win32

+		Release|Win64 (AMD64) = Release|Win64 (AMD64)

+		ReleaseAsm|Win32 = ReleaseAsm|Win32

+		ReleaseAsm|Win64 (AMD64) = ReleaseAsm|Win64 (AMD64)

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win64 (AMD64).ActiveCfg = Debug|Win64 (AMD64)

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win64 (AMD64).Build.0 = Debug|Win64 (AMD64)

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win64 (AMD64).ActiveCfg = Release|Win64 (AMD64)

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win64 (AMD64).Build.0 = Release|Win64 (AMD64)

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win32.ActiveCfg = ReleaseAsm|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win32.Build.0 = ReleaseAsm|Win32

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win64 (AMD64).ActiveCfg = ReleaseAsm|Win64 (AMD64)

+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseAsm|Win64 (AMD64).Build.0 = ReleaseAsm|Win64 (AMD64)

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/contrib/testzlib/testzlib8.vcproj b/contrib/testzlib/testzlib8.vcproj
new file mode 100644
index 0000000..3cab776
--- /dev/null
+++ b/contrib/testzlib/testzlib8.vcproj
@@ -0,0 +1,638 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8,00"

+	Name="testzlib8"

+	ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="Win64 (AMD64)"

+		/>

+	</Platforms>

+	<ToolFiles>

+		<DefaultToolFile

+			FileName="masm.tool"

+		/>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="x86\$(ConfigurationName)"

+			IntermediateDirectory="x86\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				AssemblerOutput="4"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="gvmat32.obj inffas32.obj"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|Win64 (AMD64)"

+			OutputDirectory="amd64\$(ConfigurationName)"

+			IntermediateDirectory="amd64\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				AssemblerOutput="4"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				CommandLine=""

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="gvmat64.obj inffasx64.obj rdtsc64.obj"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"

+				SubSystem="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="x86\$(ConfigurationName)"

+			IntermediateDirectory="x86\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				OmitFramePointers="TRUE"

+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="TRUE"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="TRUE"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				OptimizeForWindows98="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win64 (AMD64)"

+			OutputDirectory="amd64\$(ConfigurationName)"

+			IntermediateDirectory="amd64\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				OmitFramePointers="TRUE"

+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="TRUE"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="TRUE"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="rdtsc64.obj"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				OptimizeForWindows98="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="ReleaseAsm|Win32"

+			OutputDirectory="x86\$(ConfigurationName)"

+			IntermediateDirectory="x86\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				OmitFramePointers="TRUE"

+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="TRUE"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="TRUE"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="gvmat32.obj inffas32.obj"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				OptimizeForWindows98="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="ReleaseAsm|Win64 (AMD64)"

+			OutputDirectory="amd64\$(ConfigurationName)"

+			IntermediateDirectory="amd64\$(ConfigurationName)"

+			ConfigurationType="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+				CommandLine=""

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="MASM"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				OmitFramePointers="TRUE"

+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="TRUE"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="TRUE"

+				UsePrecompiledHeader="0"

+				AssemblerOutput="4"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="TRUE"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				CommandLine=""

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="gvmat64.obj inffasx64.obj rdtsc64.obj"

+				OutputFile="$(OutDir)/testzlib.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				OptimizeForWindows98="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"

+			>

+			<File

+				RelativePath=".\adler32.c"

+				>

+			</File>

+			<File

+				RelativePath=".\compress.c"

+				>

+			</File>

+			<File

+				RelativePath=".\crc32.c"

+				>

+			</File>

+			<File

+				RelativePath=".\deflate.c"

+				>

+			</File>

+			<File

+				RelativePath=".\gvmat32c.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win64 (AMD64)"

+					ExcludedFromBuild="TRUE"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win64 (AMD64)"

+					ExcludedFromBuild="TRUE"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="ReleaseAsm|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="ReleaseAsm|Win64 (AMD64)"

+					ExcludedFromBuild="TRUE"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\infback.c"

+				>

+			</File>

+			<File

+				RelativePath=".\inffas8664.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					ExcludedFromBuild="TRUE"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="ReleaseAsm|Win32"

+					ExcludedFromBuild="TRUE"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\inffast.c"

+				>

+			</File>

+			<File

+				RelativePath=".\inflate.c"

+				>

+			</File>

+			<File

+				RelativePath=".\inftrees.c"

+				>

+			</File>

+			<File

+				RelativePath="testzlib.c"

+				>

+			</File>

+			<File

+				RelativePath=".\trees.c"

+				>

+			</File>

+			<File

+				RelativePath=".\uncompr.c"

+				>

+			</File>

+			<File

+				RelativePath=".\zutil.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc"

+			>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/contrib/vstudio/vc7/gvmat32.obj b/contrib/vstudio/vc7/gvmat32.obj
index 5b2f856..ebb3262 100644
--- a/contrib/vstudio/vc7/gvmat32.obj
+++ b/contrib/vstudio/vc7/gvmat32.obj
Binary files differ
diff --git a/contrib/vstudio/vc7/inffas32.obj b/contrib/vstudio/vc7/inffas32.obj
index a541a5a..bd6664d 100644
--- a/contrib/vstudio/vc7/inffas32.obj
+++ b/contrib/vstudio/vc7/inffas32.obj
Binary files differ
diff --git a/contrib/vstudio/vc7/zlib.rc b/contrib/vstudio/vc7/zlib.rc
index d35cef0..d0651ec 100644
--- a/contrib/vstudio/vc7/zlib.rc
+++ b/contrib/vstudio/vc7/zlib.rc
@@ -2,8 +2,8 @@
 

 #define IDR_VERSION1  1

 IDR_VERSION1	VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE

-  FILEVERSION	 1,2,2,2

-  PRODUCTVERSION 1,2,2,2

+  FILEVERSION	 1,2,2,3

+  PRODUCTVERSION 1,2,2,3

   FILEFLAGSMASK	VS_FFI_FILEFLAGSMASK

   FILEFLAGS	0

   FILEOS	VOS_DOS_WINDOWS32

@@ -17,7 +17,7 @@
 

     BEGIN

       VALUE "FileDescription", "zlib data compression library\0"

-      VALUE "FileVersion",	"1.2.2.2\0"

+      VALUE "FileVersion",	"1.2.2.3\0"

       VALUE "InternalName",	"zlib\0"

       VALUE "OriginalFilename",	"zlib.dll\0"

       VALUE "ProductName",	"ZLib.DLL\0"

diff --git a/crc32.c b/crc32.c
index 62b025f..9b1de04 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,5 +1,5 @@
 /* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * 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
@@ -273,7 +273,7 @@
         len--;
     }
 
-    buf4 = (const u4 FAR *)buf;
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
     while (len >= 32) {
         DOLIT32;
         len -= 32;
@@ -313,7 +313,7 @@
         len--;
     }
 
-    buf4 = (const u4 FAR *)buf;
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
     buf4--;
     while (len >= 32) {
         DOBIG32;
diff --git a/deflate.c b/deflate.c
index 159f946..5cd9a92 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,5 +1,5 @@
 /* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -52,7 +52,7 @@
 #include "deflate.h"
 
 const char deflate_copyright[] =
-   " deflate 1.2.2.2 Copyright 1995-2004 Jean-loup Gailly ";
+   " deflate 1.2.2.3 Copyright 1995-2005 Jean-loup Gailly ";
 /*
   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
@@ -334,9 +334,7 @@
     if (length < MIN_MATCH) return Z_OK;
     if (length > MAX_DIST(s)) {
         length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
         dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
     }
     zmemcpy(s->window, dictionary, length);
     s->strstart = length;
@@ -452,6 +450,25 @@
     return err;
 }
 
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
 /* =========================================================================
  * For the default windowBits of 15 and memLevel of 8, this function returns
  * a close to exact, as well as small, upper bound on the compressed size.
@@ -986,9 +1003,11 @@
     s->match_length = s->prev_length = MIN_MATCH-1;
     s->match_available = 0;
     s->ins_h = 0;
+#ifndef FASTEST
 #ifdef ASMV
     match_init(); /* initialize the asm code */
 #endif
+#endif
 }
 
 #ifndef FASTEST
diff --git a/examples/README.examples b/examples/README.examples
index 1084525..75e9970 100644
--- a/examples/README.examples
+++ b/examples/README.examples
@@ -4,6 +4,13 @@
     compress just enough input to nearly fill a requested output size
     - zlib isn't designed to do this, but fitblk does it anyway
 
+gun.c
+    uncompress a gzip file
+    - illustrates the use of inflateBack() for high speed file-to-file
+      decompression using call-back functions
+    - is approximately twice as fast as gzip -d
+    - also provides Unix uncompress functionality, again twice as fast
+
 gzappend.c
     append to a gzip file
     - illustrates the use of the Z_BLOCK flush parameter for inflate()
@@ -27,3 +34,4 @@
 zpipe.c
     reads and writes zlib streams from stdin to stdout
     - illustrates the proper use of deflate() and inflate()
+    - deeply commented in zlib_how.html (see above)
diff --git a/examples/gun.c b/examples/gun.c
new file mode 100644
index 0000000..1c0d8e5
--- /dev/null
+++ b/examples/gun.c
@@ -0,0 +1,692 @@
+/* gun.c -- simple gunzip to give an example of the use of inflateBack()
+ * Copyright (C) 2003, 2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+   Version 1.2  20 March 2005  Mark Adler */
+
+/* Version history:
+   1.0  16 Feb 2003  First version for testing of inflateBack()
+   1.1  21 Feb 2005  Decompress concatenated gzip streams
+                     Remove use of "this" variable (C++ keyword)
+                     Fix return value for in()
+                     Improve allocation failure checking
+                     Add typecasting for void * structures
+                     Add -h option for command version and usage
+                     Add a bunch of comments
+   1.2  20 Mar 2005  Add Unix compress (LZW) decompression
+                     Copy file attributes from input file to output file
+ */
+
+/*
+   gun [ -t ] [ name ... ]
+
+   decompresses the data in the named gzip files.  If no arguments are given,
+   gun will decompress from stdin to stdout.  The names must end in .gz, -gz,
+   .z, -z, _z, or .Z.  The uncompressed data will be written to a file name
+   with the suffix stripped.  On success, the original file is deleted.  On
+   failure, the output file is deleted.  For most failures, the command will
+   continue to process the remaining names on the command line.  A memory
+   allocation failure will abort the command.  If -t is specified, then the
+   listed files or stdin will be tested as gzip files for integrity (without
+   checking for a proper suffix), no output will be written, and no files
+   will be deleted.
+
+   Like gzip, gun allows concatenated gzip streams and will decompress them,
+   writing all of the uncompressed data to the output.  Unlike gzip, gun allows
+   an empty file on input, and will produce no error writing an empty output
+   file.
+
+   gun will also decompress files made by Unix compress, which uses LZW
+   compression.  These files are automatically detected by virtue of their
+   magic header bytes.  Since the end of Unix compress stream is marked by the
+   end-of-file, they cannot be concantenated.  If a Unix compress stream is
+   encountered in an input file, it is the last stream in that file.
+
+   Like gunzip and uncompress, the file attributes of the orignal compressed
+   file are maintained in the final uncompressed file, to the extent that the
+   user permissions allow it.
+
+   On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
+   1.2.4) is on the same file, when gun is linked with zlib 1.2.2.  Also the
+   LZW decompression provided by gun is about twice as fast as the standard
+   Unix uncompress command.
+ */
+
+/* external functions and related types and constants */
+#include <stdio.h>          /* fprintf() */
+#include <stdlib.h>         /* malloc(), free() */
+#include <string.h>         /* strerror(), strcmp(), strlen(), memcpy() */
+#include <errno.h>          /* errno */
+#include <fcntl.h>          /* open() */
+#include <unistd.h>         /* read(), write(), close(), chown(), unlink() */
+#include <sys/types.h>
+#include <sys/stat.h>       /* stat(), chmod() */
+#include <utime.h>          /* utime() */
+#include "zlib.h"           /* inflateBackInit(), inflateBack(), */
+                            /* inflateBackEnd(), crc32() */
+
+/* function declaration */
+#define local static
+
+/* buffer constants */
+#define SIZE 32768U         /* input and output buffer sizes */
+#define PIECE 16384         /* limits i/o chunks for 16-bit int case */
+
+/* structure for infback() to pass to input function in() -- it maintains the
+   input file and a buffer of size SIZE */
+struct ind {
+    int infile;
+    unsigned char *inbuf;
+};
+
+/* Load input buffer, assumed to be empty, and return bytes loaded and a
+   pointer to them.  read() is called until the buffer is full, or until it
+   returns end-of-file or error.  Return 0 on error. */
+local unsigned in(void *in_desc, unsigned char **buf)
+{
+    int ret;
+    unsigned len;
+    unsigned char *next;
+    struct ind *me = (struct ind *)in_desc;
+
+    next = me->inbuf;
+    *buf = next;
+    len = 0;
+    do {
+        ret = PIECE;
+        if ((unsigned)ret > SIZE - len)
+            ret = (int)(SIZE - len);
+        ret = (int)read(me->infile, next, ret);
+        if (ret == -1) {
+            len = 0;
+            break;
+        }
+        next += ret;
+        len += ret;
+    } while (ret != 0 && len < SIZE);
+    return len;
+}
+
+/* structure for infback() to pass to output function out() -- it maintains the
+   output file, a running CRC-32 check on the output and the total number of
+   bytes output, both for checking against the gzip trailer.  (The length in
+   the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
+   the output is greater than 4 GB.) */
+struct outd {
+    int outfile;
+    int check;                  /* true if checking crc and total */
+    unsigned long crc;
+    unsigned long total;
+};
+
+/* Write output buffer and update the CRC-32 and total bytes written.  write()
+   is called until all of the output is written or an error is encountered.
+   On success out() returns 0.  For a write failure, out() returns 1.  If the
+   output file descriptor is -1, then nothing is written.
+ */
+local int out(void *out_desc, unsigned char *buf, unsigned len)
+{
+    int ret;
+    struct outd *me = (struct outd *)out_desc;
+
+    if (me->check) {
+        me->crc = crc32(me->crc, buf, len);
+        me->total += len;
+    }
+    if (me->outfile != -1)
+        do {
+            ret = PIECE;
+            if ((unsigned)ret > len)
+                ret = (int)len;
+            ret = (int)write(me->outfile, buf, ret);
+            if (ret == -1)
+                return 1;
+            buf += ret;
+            len -= ret;
+        } while (len != 0);
+    return 0;
+}
+
+/* next input byte macro for use inside lunpipe() and gunpipe() */
+#define NEXT() (have ? 0 : (have = in(indp, &next)), \
+                last = have ? (have--, (int)(*next++)) : -1)
+
+/* memory for gunpipe() and lunpipe() --
+   the first 256 entries of prefix[] and suffix[] are never used, could
+   have offset the index, but it's faster to waste the memory */
+unsigned char inbuf[SIZE];              /* input buffer */
+unsigned char outbuf[SIZE];             /* output buffer */
+unsigned short prefix[65536];           /* index to LZW prefix string */
+unsigned char suffix[65536];            /* one-character LZW suffix */
+unsigned char match[65280 + 2];         /* buffer for reversed match or gzip
+                                           32K sliding window */
+
+/* throw out what's left in the current bits byte buffer (this is a vestigial
+   aspect of the compressed data format derived from an implementation that
+   made use of a special VAX machine instruction!) */
+#define FLUSHCODE() \
+    do { \
+        left = 0; \
+        rem = 0; \
+        if (chunk > have) { \
+            chunk -= have; \
+            have = 0; \
+            if (NEXT() == -1) \
+                break; \
+            chunk--; \
+            if (chunk > have) { \
+                chunk = have = 0; \
+                break; \
+            } \
+        } \
+        have -= chunk; \
+        next += chunk; \
+        chunk = 0; \
+    } while (0)
+
+/* Decompress a compress (LZW) file from indp to outfile.  The compress magic
+   header (two bytes) has already been read and verified.  There are have bytes
+   of buffered input at next.  strm is used for passing error information back
+   to gunpipe().
+
+   lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
+   file, read error, or write error (a write error indicated by strm->next_in
+   not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
+ */
+local int lunpipe(unsigned have, unsigned char *next, struct ind *indp,
+                  int outfile, z_stream *strm)
+{
+    int last;                   /* last byte read by NEXT(), or -1 if EOF */
+    int chunk;                  /* bytes left in current chunk */
+    int left;                   /* bits left in rem */
+    unsigned rem;               /* unused bits from input */
+    int bits;                   /* current bits per code */
+    unsigned code;              /* code, table traversal index */
+    unsigned mask;              /* mask for current bits codes */
+    int max;                    /* maximum bits per code for this stream */
+    int flags;                  /* compress flags, then block compress flag */
+    unsigned end;               /* last valid entry in prefix/suffix tables */
+    unsigned temp;              /* current code */
+    unsigned prev;              /* previous code */
+    unsigned final;             /* last character written for previous code */
+    unsigned stack;             /* next position for reversed string */
+    unsigned outcnt;            /* bytes in output buffer */
+    struct outd outd;           /* output structure */
+
+    /* set up output */
+    outd.outfile = outfile;
+    outd.check = 0;
+
+    /* process remainder of compress header -- a flags byte */
+    flags = NEXT();
+    if (last == -1)
+        return Z_BUF_ERROR;
+    if (flags & 0x60) {
+        strm->msg = "unknown lzw flags set";
+        return Z_DATA_ERROR;
+    }
+    max = flags & 0x1f;
+    if (max < 9 || max > 16) {
+        strm->msg = "lzw bits out of range";
+        return Z_DATA_ERROR;
+    }
+    if (max == 9)                           /* 9 doesn't really mean 9 */
+        max = 10;
+    flags &= 0x80;                          /* true if block compress */
+
+    /* clear table */
+    bits = 9;
+    mask = 0x1ff;
+    end = flags ? 256 : 255;
+
+    /* set up: get first 9-bit code, which is the first decompressed byte, but
+       don't create a table entry until the next code */
+    if (NEXT() == -1)                       /* no compressed data is ok */
+        return Z_OK;
+    final = prev = (unsigned)last;          /* low 8 bits of code */
+    if (NEXT() == -1)                       /* missing a bit */
+        return Z_BUF_ERROR;
+    if (last & 1) {                         /* code must be < 256 */
+        strm->msg = "invalid lzw code";
+        return Z_DATA_ERROR;
+    }
+    rem = (unsigned)last >> 1;              /* remaining 7 bits */
+    left = 7;
+    chunk = bits - 2;                       /* 7 bytes left in this chunk */
+    outbuf[0] = (unsigned char)final;       /* write first decompressed byte */
+    outcnt = 1;
+
+    /* decode codes */
+    stack = 0;
+    for (;;) {
+        /* if the table will be full after this, increment the code size */
+        if (end >= mask && bits < max) {
+            FLUSHCODE();
+            bits++;
+            mask <<= 1;
+            mask++;
+        }
+
+        /* get a code of length bits */
+        if (chunk == 0)                     /* decrement chunk modulo bits */
+            chunk = bits;
+        code = rem;                         /* low bits of code */
+        if (NEXT() == -1) {                 /* EOF is end of compressed data */
+            /* write remaining buffered output */
+            if (outcnt && out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf;     /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            return Z_OK;
+        }
+        code += (unsigned)last << left;     /* middle (or high) bits of code */
+        left += 8;
+        chunk--;
+        if (bits > left) {                  /* need more bits */
+            if (NEXT() == -1)               /* can't end in middle of code */
+                return Z_BUF_ERROR;
+            code += (unsigned)last << left; /* high bits of code */
+            left += 8;
+            chunk--;
+        }
+        code &= mask;                       /* mask to current code length */
+        left -= bits;                       /* number of unused bits */
+        rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
+
+        /* process clear code (256) */
+        if (code == 256 && flags) {
+            FLUSHCODE();
+            bits = 9;                       /* initialize bits and mask */
+            mask = 0x1ff;
+            end = 255;                      /* empty table */
+            continue;                       /* get next code */
+        }
+
+        /* special code to reuse last match */
+        temp = code;                        /* save the current code */
+        if (code > end) {
+            /* Be picky on the allowed code here, and make sure that the code
+               we drop through (prev) will be a valid index so that random
+               input does not cause an exception.  The code != end + 1 check is
+               empirically derived, and not checked in the original uncompress
+               code.  If this ever causes a problem, that check could be safely
+               removed.  Leaving this check in greatly improves gun's ability
+               to detect random or corrupted input after a compress header.
+               In any case, the prev > end check must be retained. */
+            if (code != end + 1 || prev > end) {
+                strm->msg = "invalid lzw code";
+                return Z_DATA_ERROR;
+            }
+            match[stack++] = (unsigned char)final;
+            code = prev;
+        }
+
+        /* walk through linked list to generate output in reverse order */
+        while (code >= 256) {
+            match[stack++] = suffix[code];
+            code = prefix[code];
+        }
+        match[stack++] = (unsigned char)code;
+        final = code;
+
+        /* link new table entry */
+        if (end < mask) {
+            end++;
+            prefix[end] = (unsigned short)prev;
+            suffix[end] = (unsigned char)final;
+        }
+
+        /* set previous code for next iteration */
+        prev = temp;
+
+        /* write output in forward order */
+        while (stack > SIZE - outcnt) {
+            while (outcnt < SIZE)
+                outbuf[outcnt++] = match[--stack];
+            if (out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf; /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            outcnt = 0;
+        }
+        do {
+            outbuf[outcnt++] = match[--stack];
+        } while (stack);
+
+        /* loop for next code with final and prev as the last match, rem and
+           left provide the first 0..7 bits of the next code, end is the last
+           valid table entry */
+    }
+}
+
+/* Decompress a gzip file from infile to outfile.  strm is assumed to have been
+   successfully initialized with inflateBackInit().  The input file may consist
+   of a series of gzip streams, in which case all of them will be decompressed
+   to the output file.  If outfile is -1, then the gzip stream(s) integrity is
+   checked and nothing is written.
+
+   The return value is a zlib error code: Z_MEM_ERROR if out of memory,
+   Z_DATA_ERROR if the header or the compressed data is invalid, or if the
+   trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
+   prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
+   stream) follows a valid gzip stream.
+ */
+local int gunpipe(z_stream *strm, int infile, int outfile)
+{
+    int ret, first, last;
+    unsigned have, flags, len;
+    unsigned char *next;
+    struct ind ind, *indp;
+    struct outd outd;
+
+    /* setup input buffer */
+    ind.infile = infile;
+    ind.inbuf = inbuf;
+    indp = &ind;
+
+    /* decompress concatenated gzip streams */
+    have = 0;                               /* no input data read in yet */
+    first = 1;                              /* looking for first gzip header */
+    strm->next_in = Z_NULL;                 /* so Z_BUF_ERROR means EOF */
+    for (;;) {
+        /* look for the two magic header bytes for a gzip stream */
+        if (NEXT() == -1) {
+            ret = Z_OK;
+            break;                          /* empty gzip stream is ok */
+        }
+        if (last != 31 || (NEXT() != 139 && last != 157)) {
+            strm->msg = "incorrect header check";
+            ret = first ? Z_DATA_ERROR : Z_ERRNO;
+            break;                          /* not a gzip or compress header */
+        }
+        first = 0;                          /* next non-header is junk */
+
+        /* process a compress (LZW) file -- can't be concatenated after this */
+        if (last == 157) {
+            ret = lunpipe(have, next, indp, outfile, strm);
+            break;
+        }
+
+        /* process remainder of gzip header */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != 8) {                  /* only deflate method allowed */
+            if (last == -1) break;
+            strm->msg = "unknown compression method";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        flags = NEXT();                     /* header flags */
+        NEXT();                             /* discard mod time, xflgs, os */
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        if (last == -1) break;
+        if (flags & 0xe0) {
+            strm->msg = "unknown header flags set";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        if (flags & 4) {                    /* extra field */
+            len = NEXT();
+            len += (unsigned)(NEXT()) << 8;
+            if (last == -1) break;
+            while (len > have) {
+                len -= have;
+                have = 0;
+                if (NEXT() == -1) break;
+                len--;
+            }
+            if (last == -1) break;
+            have -= len;
+            next += len;
+        }
+        if (flags & 8)                      /* file name */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 16)                     /* comment */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 2) {                    /* header crc */
+            NEXT();
+            NEXT();
+        }
+        if (last == -1) break;
+
+        /* set up output */
+        outd.outfile = outfile;
+        outd.check = 1;
+        outd.crc = crc32(0L, Z_NULL, 0);
+        outd.total = 0;
+
+        /* decompress data to output */
+        strm->next_in = next;
+        strm->avail_in = have;
+        ret = inflateBack(strm, in, indp, out, &outd);
+        if (ret != Z_STREAM_END) break;
+        next = strm->next_in;
+        have = strm->avail_in;
+        strm->next_in = Z_NULL;             /* so Z_BUF_ERROR means EOF */
+
+        /* check trailer */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != (outd.crc & 0xff) ||
+            NEXT() != ((outd.crc >> 8) & 0xff) ||
+            NEXT() != ((outd.crc >> 16) & 0xff) ||
+            NEXT() != ((outd.crc >> 24) & 0xff)) {
+            /* crc error */
+            if (last != -1) {
+                strm->msg = "incorrect data check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+        if (NEXT() != (outd.total & 0xff) ||
+            NEXT() != ((outd.total >> 8) & 0xff) ||
+            NEXT() != ((outd.total >> 16) & 0xff) ||
+            NEXT() != ((outd.total >> 24) & 0xff)) {
+            /* length error */
+            if (last != -1) {
+                strm->msg = "incorrect length check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+
+        /* go back and look for another gzip stream */
+    }
+
+    /* clean up and return */
+    return ret;
+}
+
+/* Copy file attributes, from -> to, as best we can.  This is best effort, so
+   no errors are reported.  The mode bits, including suid, sgid, and the sticky
+   bit are copied (if allowed), the owner's user id and group id are copied
+   (again if allowed), and the access and modify times are copied. */
+local void copymeta(char *from, char *to)
+{
+    struct stat was;
+    struct utimbuf when;
+
+    /* get all of from's Unix meta data, return if not a regular file */
+    if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
+        return;
+
+    /* set to's mode bits, ignore errors */
+    (void)chmod(to, was.st_mode & 07777);
+
+    /* copy owner's user and group, ignore errors */
+    (void)chown(to, was.st_uid, was.st_gid);
+
+    /* copy access and modify times, ignore errors */
+    when.actime = was.st_atime;
+    when.modtime = was.st_mtime;
+    (void)utime(to, &when);
+}
+
+/* Decompress the file inname to the file outnname, of if test is true, just
+   decompress without writing and check the gzip trailer for integrity.  If
+   inname is NULL or an empty string, read from stdin.  If outname is NULL or
+   an empty string, write to stdout.  strm is a pre-initialized inflateBack
+   structure.  When appropriate, copy the file attributes from inname to
+   outname.
+
+   gunzip() returns 1 if there is an out-of-memory error or an unexpected
+   return code from gunpipe().  Otherwise it returns 0.
+ */
+local int gunzip(z_stream *strm, char *inname, char *outname, int test)
+{
+    int ret;
+    int infile, outfile;
+
+    /* open files */
+    if (inname == NULL || *inname == 0) {
+        inname = "-";
+        infile = 0;     /* stdin */
+    }
+    else {
+        infile = open(inname, O_RDONLY, 0);
+        if (infile == -1) {
+            fprintf(stderr, "gun cannot open %s\n", inname);
+            return 0;
+        }
+    }
+    if (test)
+        outfile = -1;
+    else if (outname == NULL || *outname == 0) {
+        outname = "-";
+        outfile = 1;    /* stdout */
+    }
+    else {
+        outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+        if (outfile == -1) {
+            close(infile);
+            fprintf(stderr, "gun cannot create %s\n", outname);
+            return 0;
+        }
+    }
+    errno = 0;
+
+    /* decompress */
+    ret = gunpipe(strm, infile, outfile);
+    if (outfile > 2) close(outfile);
+    if (infile > 2) close(infile);
+
+    /* interpret result */
+    switch (ret) {
+    case Z_OK:
+    case Z_ERRNO:
+        if (infile > 2 && outfile > 2) {
+            copymeta(inname, outname);          /* copy attributes */
+            unlink(inname);
+        }
+        if (ret == Z_ERRNO)
+            fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
+                    inname);
+        break;
+    case Z_DATA_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
+        break;
+    case Z_MEM_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    case Z_BUF_ERROR:
+        if (outfile > 2) unlink(outname);
+        if (strm->next_in != Z_NULL) {
+            fprintf(stderr, "gun write error on %s: %s\n",
+                    outname, strerror(errno));
+        }
+        else if (errno) {
+            fprintf(stderr, "gun read error on %s: %s\n",
+                    inname, strerror(errno));
+        }
+        else {
+            fprintf(stderr, "gun unexpected end of file on %s\n",
+                    inname);
+        }
+        break;
+    default:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun internal error--aborting\n");
+        return 1;
+    }
+    return 0;
+}
+
+/* Process the gun command line arguments.  See the command syntax near the
+   beginning of this source file. */
+int main(int argc, char **argv)
+{
+    int ret, len, test;
+    char *outname;
+    unsigned char *window;
+    z_stream strm;
+
+    /* initialize inflateBack state for repeated use */
+    window = match;                         /* reuse LZW match buffer */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = inflateBackInit(&strm, 15, window);
+    if (ret != Z_OK) {
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    }
+
+    /* decompress each file to the same name with the suffix removed */
+    argc--;
+    argv++;
+    test = 0;
+    if (argc && strcmp(*argv, "-h") == 0) {
+        fprintf(stderr, "gun 1.2 (20 Mar 2005)\n");
+        fprintf(stderr, "Copyright (c) 2005 Mark Adler\n");
+        fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
+        return 0;
+    }
+    if (argc && strcmp(*argv, "-t") == 0) {
+        test = 1;
+        argc--;
+        argv++;
+    }
+    if (argc)
+        do {
+            if (test)
+                outname = NULL;
+            else {
+                len = (int)strlen(*argv);
+                if (strcmp(*argv + len - 3, ".gz") == 0 ||
+                    strcmp(*argv + len - 3, "-gz") == 0)
+                    len -= 3;
+                else if (strcmp(*argv + len - 2, ".z") == 0 ||
+                    strcmp(*argv + len - 2, "-z") == 0 ||
+                    strcmp(*argv + len - 2, "_z") == 0 ||
+                    strcmp(*argv + len - 2, ".Z") == 0)
+                    len -= 2;
+                else {
+                    fprintf(stderr, "gun error: no gz type on %s--skipping\n",
+                            *argv);
+                    continue;
+                }
+                outname = malloc(len + 1);
+                if (outname == NULL) {
+                    fprintf(stderr, "gun out of memory error--aborting\n");
+                    ret = 1;
+                    break;
+                }
+                memcpy(outname, *argv, len);
+                outname[len] = 0;
+            }
+            ret = gunzip(&strm, *argv, outname, test);
+            if (outname != NULL) free(outname);
+            if (ret) break;
+        } while (argv++, --argc);
+    else
+        ret = gunzip(&strm, NULL, NULL, test);
+
+    /* clean up */
+    inflateBackEnd(&strm);
+    return ret;
+}
diff --git a/examples/zlib_how.html b/examples/zlib_how.html
index b2bda6b..40998db 100644
--- a/examples/zlib_how.html
+++ b/examples/zlib_how.html
@@ -420,10 +420,11 @@
             }
 </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>.
+by not filling the output buffer, just as for <tt>deflate()</tt>.  In this case, we cannot
+assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
+does.
 <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
diff --git a/examples/zpipe.c b/examples/zpipe.c
index a602d59..26abb56 100644
--- a/examples/zpipe.c
+++ b/examples/zpipe.c
@@ -7,6 +7,7 @@
    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
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
  */
 
 #include <stdio.h>
@@ -127,7 +128,6 @@
                 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);
diff --git a/gzio.c b/gzio.c
index 217a4cc..b069b7a 100644
--- a/gzio.c
+++ b/gzio.c
@@ -1,5 +1,5 @@
 /* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  *
  * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
@@ -264,7 +264,7 @@
     if (s->z_eof) return EOF;
     if (s->stream.avail_in == 0) {
         errno = 0;
-        s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
         if (s->stream.avail_in == 0) {
             s->z_eof = 1;
             if (ferror(s->file)) s->z_err = Z_ERRNO;
@@ -300,7 +300,7 @@
     if (len < 2) {
         if (len) s->inbuf[0] = s->stream.next_in[0];
         errno = 0;
-        len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
         if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
         s->stream.avail_in += len;
         s->stream.next_in = s->inbuf;
@@ -415,6 +415,7 @@
         s->stream.avail_out--;
         s->back = EOF;
         s->out++;
+        start++;
         if (s->last) {
             s->z_err = Z_STREAM_END;
             return 1;
@@ -436,8 +437,8 @@
                 s->stream.avail_in  -= n;
             }
             if (s->stream.avail_out > 0) {
-                s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
-                                             s->file);
+                s->stream.avail_out -=
+                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
             }
             len -= s->stream.avail_out;
             s->in  += len;
@@ -448,17 +449,13 @@
         if (s->stream.avail_in == 0 && !s->z_eof) {
 
             errno = 0;
-            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
             if (s->stream.avail_in == 0) {
                 s->z_eof = 1;
                 if (ferror(s->file)) {
                     s->z_err = Z_ERRNO;
                     break;
                 }
-                if (feof(s->file)) {        /* avoid error for empty file */
-                    s->z_err = Z_STREAM_END;
-                    break;
-                }
             }
             s->stream.next_in = s->inbuf;
         }
@@ -903,6 +900,18 @@
 }
 
 /* ===========================================================================
+     Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return 0;
+    return s->transparent;
+}
+
+/* ===========================================================================
    Outputs a long in LSB order to the given file
 */
 local void putLong (file, x)
diff --git a/inflate.c b/inflate.c
index 5733437..7dccc9d 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,5 +1,5 @@
 /* inflate.c -- zlib decompression
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -1334,11 +1334,15 @@
     /* copy state */
     zmemcpy(dest, source, sizeof(z_stream));
     zmemcpy(copy, state, sizeof(struct inflate_state));
-    copy->lencode = copy->codes + (state->lencode - state->codes);
-    copy->distcode = copy->codes + (state->distcode - state->codes);
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1)
+    {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
     copy->next = copy->codes + (state->next - state->codes);
     if (window != Z_NULL)
-        zmemcpy(window, state->window, 1U << state->wbits);
+        zmemcpy(window, state->window, (uInt)(1U << state->wbits));
     copy->window = window;
     dest->state = (voidpf)copy;
     return Z_OK;
diff --git a/inftrees.c b/inftrees.c
index 72c5b75..471f735 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -1,5 +1,5 @@
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -9,7 +9,7 @@
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.2.2 Copyright 1995-2004 Mark Adler ";
+   " inflate 1.2.2.3 Copyright 1995-2005 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 199};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 66, 71};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -262,7 +262,7 @@
                 drop = root;
 
             /* increment past last table */
-            next += 1U << curr;
+            next += (unsigned)(1U << curr);
 
             /* determine length of next table */
             curr = len - drop;
diff --git a/minigzip.c b/minigzip.c
index 4ba5e50..4524b96 100644
--- a/minigzip.c
+++ b/minigzip.c
@@ -1,5 +1,5 @@
 /* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -295,6 +295,8 @@
         break;
       argc--, argv++;
     }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
     if (argc == 0) {
         SET_BINARY_MODE(stdin);
         SET_BINARY_MODE(stdout);
diff --git a/qnx/package.qpg b/qnx/package.qpg
index 03cd351..b08778d 100644
--- a/qnx/package.qpg
+++ b/qnx/package.qpg
@@ -25,10 +25,10 @@
       <QPG:Files>
          <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="../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.2.2"/>
-         <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.2.2" install="/opt/lib/" component="slib"/>
+         <QPG:Add file="../libz.so.1.2.2.3" 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.2.3"/>
+         <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.3"/>
+         <QPG:Add file="../libz.so.1.2.2.3" install="/opt/lib/" component="slib"/>
       </QPG:Files>
 
       <QPG:PackageFilter>
@@ -63,7 +63,7 @@
             </QPM:ProductDescription>
 
             <QPM:ReleaseDescription>
-               <QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion>
+               <QPM:ReleaseVersion>1.2.2.3</QPM:ReleaseVersion>
                <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
                <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
                <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
diff --git a/win32/zlib1.rc b/win32/zlib1.rc
index 1d37694..e49a81c 100644
--- a/win32/zlib1.rc
+++ b/win32/zlib1.rc
@@ -5,8 +5,8 @@
 #else
 VS_VERSION_INFO		VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
 #endif
-  FILEVERSION		1,2,2,2
-  PRODUCTVERSION	1,2,2,2
+  FILEVERSION		1,2,2,3
+  PRODUCTVERSION	1,2,2,3
   FILEFLAGSMASK		VS_FFI_FILEFLAGSMASK
 #ifdef _DEBUG
   FILEFLAGS		1
@@ -23,12 +23,12 @@
     //language ID = U.S. English, char set = Windows, Multilingual
     BEGIN
       VALUE "FileDescription",	"zlib data compression library\0"
-      VALUE "FileVersion",	"1.2.2.2\0"
+      VALUE "FileVersion",	"1.2.2.3\0"
       VALUE "InternalName",	"zlib1.dll\0"
       VALUE "LegalCopyright",	"(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
       VALUE "OriginalFilename",	"zlib1.dll\0"
       VALUE "ProductName",	"zlib\0"
-      VALUE "ProductVersion",	"1.2.2.2\0"
+      VALUE "ProductVersion",	"1.2.2.3\0"
       VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
     END
   END
diff --git a/zconf.h b/zconf.h
index 6897bf0..03a9431 100644
--- a/zconf.h
+++ b/zconf.h
@@ -1,5 +1,5 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -68,8 +68,10 @@
 #if defined(_WINDOWS) && !defined(WINDOWS)
 #  define WINDOWS
 #endif
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
 #endif
 #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
 #  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
diff --git a/zconf.in.h b/zconf.in.h
index 6897bf0..03a9431 100644
--- a/zconf.in.h
+++ b/zconf.in.h
@@ -1,5 +1,5 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -68,8 +68,10 @@
 #if defined(_WINDOWS) && !defined(WINDOWS)
 #  define WINDOWS
 #endif
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
 #endif
 #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
 #  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
diff --git a/zlib.3 b/zlib.3
index 17491cc..41e5fed 100644
--- a/zlib.3
+++ b/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "30 December 2004"
+.TH ZLIB 3 "27 May 2005"
 .SH NAME
 zlib \- compression/decompression library
 .SH SYNOPSIS
@@ -133,7 +133,7 @@
 Send questions and/or comments to zlib@gzip.org,
 or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
 .SH AUTHORS
-Version 1.2.2.2
+Version 1.2.2.3
 Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
 and Mark Adler (madler@alumni.caltech.edu).
 .LP
diff --git a/zlib.h b/zlib.h
index b13ca6f..9bb6931 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,7 +1,7 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.2.2, December 30th, 2004
+  version 1.2.2.3, May 27th, 2005
 
-  Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -37,8 +37,8 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.2.2"
-#define ZLIB_VERNUM 0x1222
+#define ZLIB_VERSION "1.2.2.3"
+#define ZLIB_VERNUM 0x1223
 
 /*
      The 'zlib' compression library provides in-memory compression and
@@ -556,7 +556,9 @@
    deflateInit or deflateInit2, a part of the dictionary may in effect be
    discarded, for example if the dictionary is larger than the window size in
    deflate or deflate2. Thus the strings most likely to be useful should be
-   put at the end of the dictionary, not at the front.
+   put at the end of the dictionary, not at the front. In addition, the
+   current implementation of deflate will use at most the window size minus
+   262 bytes of the provided dictionary.
 
      Upon return of this function, strm->adler is set to the adler32 value
    of the dictionary; the decompressor may later use this value to determine
@@ -622,6 +624,23 @@
    if strm->avail_out was zero.
 */
 
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
 ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
                                        uLong sourceLen));
 /*
@@ -703,7 +722,7 @@
      windowBits can also be greater than 15 for optional gzip decoding. Add
    32 to windowBits to enable zlib and gzip decoding with automatic header
    detection, or add 16 to decode only the gzip format (the zlib format will
-   return a Z_DATA_ERROR.  If a gzip stream is being decoded, strm->adler is
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
    a crc32 instead of an adler32.
 
      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
@@ -1185,6 +1204,12 @@
    input stream, otherwise zero.
 */
 
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns 1 if file is being read directly without decompression, otherwise
+   zero.
+*/
+
 ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
 /*
      Flushes all pending output if necessary, closes the compressed file
diff --git a/zutil.h b/zutil.h
index 5209d65..c800fab 100644
--- a/zutil.h
+++ b/zutil.h
@@ -1,5 +1,5 @@
 /* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -17,7 +17,9 @@
 #include "zlib.h"
 
 #ifdef STDC
-#  include <stddef.h>
+#  ifndef _WIN32_WCE
+#    include <stddef.h>
+#  endif
 #  include <string.h>
 #  include <stdlib.h>
 #endif
@@ -32,7 +34,9 @@
 #   endif
     extern int errno;
 #else
-#   include <errno.h>
+#  ifndef _WIN32_WCE
+#    include <errno.h>
+#  endif
 #endif
 
 #ifndef local