zlib 0.93
diff --git a/ChangeLog b/ChangeLog
index 57f9986..fc70594 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 		ChangeLog file for zlib
 
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
 Changes in 0.92 (3 May 95)
 - don't assume that char is signed (problem on SGI)
 - Clear bit buffer when starting a stored block
diff --git a/README b/README
index bc4a663..e82b56f 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-zlib 0.92 is a beta version of a general purpose compression library.
+zlib 0.93 is a beta version of a general purpose compression library.
 
 The data format used by the zlib library is described in the
 files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available
@@ -14,9 +14,12 @@
 To install in a different directory, use for example: make install prefix=$HOME
 This will install in $HOME/lib instead of /usr/local/lib.
 
-The changes made in version 0.92 are documented in the file ChangeLog.
+The changes made in version 0.93 are documented in the file ChangeLog.
 The main changes since 0.9 are:
-- don't assume that char is signed (problem on SGI)
+- temporarily disable inline functions
+- make deflate deterministic
+- don't use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
 - Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
 - Document the memory requirements in zconf.h
 - added "make install"
@@ -50,7 +53,7 @@
   3. This notice may not be removed or altered from any source distribution.
 
   Jean-loup Gailly        Mark Adler
-  gzip@prep.ai.mit.edu    madler@cco.caltech.edu
+  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
 
 If you use the zlib library in a product, we would appreciate *not*
 receiving lengthy legal documents to sign. The sources are provided
diff --git a/crc32.c b/crc32.c
index d9485c2..92bc3f0 100644
--- a/crc32.c
+++ b/crc32.c
@@ -7,57 +7,35 @@
 
 #include "zlib.h"
 
-extern uLong crc_table[];   /* crc table, defined below */
+#define local static
 
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf)  DO1(buf); DO1(buf);
-#define DO4(buf)  DO2(buf); DO2(buf);
-#define DO8(buf)  DO4(buf); DO4(buf);
-
-/* ========================================================================= */
-uLong crc32(crc, buf, len)
-    uLong crc;
-    Byte *buf;
-    uInt len;
-{
-    if (buf == Z_NULL) return 0L;
-    crc = crc ^ 0xffffffffL;
-    while (len >= 8)
-    {
-      DO8(buf);
-      len -= 8;
-    }
-    if (len) do {
-      DO1(buf);
-    } while (--len);
-    return crc ^ 0xffffffffL;
-}
-
+#ifdef DYNAMIC_CRC_TABLE
 /* =========================================================================
  * Make the crc table. This function is needed only if you want to compute
  * the table dynamically.
  */
-#ifdef DYNAMIC_CRC_TABLE
+local int crc_table_empty = 1;
+local uLong crc_table[256];
 
 local void make_crc_table()
 {
   uLong c;
   int n, k;
  
-  for (n = 0; n < 256; n++)
+  for (n = 0; n < 256; n++)
   {
     c = (uLong)n;
-    for (k = 0; k &lt; 8; k++)
+    for (k = 0; k < 8; k++)
       c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
     crc_table[n] = c;
   }
+  crc_table_empty = 0;
 }
-#endif
-
+#else
 /* ========================================================================
  * Table of CRC-32's of all single-byte values (made by make_crc_table)
  */
-uLong crc_table[] = {
+local uLong crc_table[] = {
   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
@@ -111,3 +89,32 @@
   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
   0x2d02ef8dL
 };
+#endif
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong crc32(crc, buf, len)
+    uLong crc;
+    Byte *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
diff --git a/deflate.c b/deflate.c
index 6c0cd0a..726da18 100644
--- a/deflate.c
+++ b/deflate.c
@@ -117,7 +117,7 @@
 local int  deflate_fast  __P((deflate_state *s, int flush));
 local int  deflate_slow  __P((deflate_state *s, int flush));
 local void lm_init       __P((deflate_state *s));
-local int  longest_match __P((deflate_state *s, IPos cur_match));
+local inline int longest_match __P((deflate_state *s, IPos cur_match));
 local void putShortMSB   __P((deflate_state *s, uInt b));
 local void flush_pending __P((z_stream *strm));
 local int read_buf       __P((z_stream *strm, char *buf, unsigned size));
@@ -354,13 +354,17 @@
         } else {
             quit = deflate_slow(strm->state, flush);
         }
-        if (flush == Z_FULL_FLUSH) {
+        if (flush == Z_FULL_FLUSH || flush == Z_SYNC_FLUSH) {
             ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */
             flush_pending(strm);
-            CLEAR_HASH(strm->state);             /* forget history */
-            if (strm->avail_out == 0) return Z_OK;
+	    if (flush == Z_FULL_FLUSH) {
+		CLEAR_HASH(strm->state);             /* forget history */
+	    }
+        } else if (flush == Z_PARTIAL_FLUSH) {
+            ct_align(strm->state);
+            flush_pending(strm);
         }
-        if (quit) return Z_OK;
+        if (quit || strm->avail_out == 0) return Z_OK;
     }
     Assert(strm->avail_out > 0, "bug2");
 
@@ -447,8 +451,6 @@
 local void lm_init (s)
     deflate_state *s;
 {
-    register unsigned j;
-
     s->window_size = (ulg)2L*s->w_size;
 
     CLEAR_HASH(s);
@@ -465,15 +467,10 @@
     s->lookahead = 0;
     s->match_length = MIN_MATCH-1;
     s->match_available = 0;
+    s->ins_h = 0;
 #ifdef ASMV
     match_init(); /* initialize the asm code */
 #endif
-
-    s->ins_h = 0;
-    for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(s, s->ins_h, s->window[j]);
-    /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
-     * not important since only literal bytes will be emitted.
-     */
 }
 
 /* ===========================================================================
@@ -488,7 +485,7 @@
 /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
  * match.S. The code will be functionally equivalent.
  */
-local INLINE int longest_match(s, cur_match)
+local inline int longest_match(s, cur_match)
     deflate_state *s;
     IPos cur_match;                             /* current match */
 {
@@ -730,6 +727,16 @@
                      more);
         s->lookahead += n;
 
+        /* Initialize the hash value now that we have some input: */
+        if (s->strstart == 0 && s->lookahead >= MIN_MATCH-1) {
+            for (n=0; n<MIN_MATCH-1; n++) {
+                UPDATE_HASH(s, s->ins_h, s->window[n]);
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
     } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
 }
 
diff --git a/deflate.h b/deflate.h
index c292fc7..fb6c233 100644
--- a/deflate.h
+++ b/deflate.h
@@ -268,5 +268,6 @@
 void ct_init       __P((deflate_state *s));
 int  ct_tally      __P((deflate_state *s, int dist, int lc));
 ulg ct_flush_block __P((deflate_state *s, char *buf, ulg stored_len, int eof));
+void ct_align      __P((deflate_state *s));
 void ct_stored_block __P((deflate_state *s, char *buf, ulg stored_len,
                           int eof));
diff --git a/infblock.c b/infblock.c
index 3a9cf85..04a5653 100644
--- a/infblock.c
+++ b/infblock.c
@@ -71,7 +71,11 @@
   if (s->mode == BTREE || s->mode == DTREE)
     ZFREE(z, s->sub.trees.blens);
   if (s->mode == CODES)
-    inflate_codes_free(s->sub.codes, z);
+  {
+    inflate_codes_free(s->sub.decode.codes, z);
+    inflate_trees_free(s->sub.decode.td, z);
+    inflate_trees_free(s->sub.decode.tl, z);
+  }
   s->mode = TYPE;
   s->bitk = 0;
   s->bitb = 0;
@@ -147,12 +151,14 @@
             inflate_huft *tl, *td;
 
             inflate_trees_fixed(&bl, &bd, &tl, &td);
-            s->sub.codes = inflate_codes_new(bl, bd, tl, td, z);
-            if (s->sub.codes == Z_NULL)
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
             {
               r = Z_MEM_ERROR;
               LEAVE
             }
+            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
+            s->sub.decode.td = Z_NULL;
           }
           DUMPBITS(3)
           s->mode = CODES;
@@ -181,7 +187,7 @@
         LEAVE
       }
       s->sub.left = (uInt)b & 0xffff;
-      k = b = 0;                      /* dump bits */
+      b = k = 0;                      /* dump bits */
       Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
       s->mode = s->sub.left ? STORED : TYPE;
       break;
@@ -318,7 +324,9 @@
           LEAVE
         }
         ZFREE(z, s->sub.trees.blens);
-        s->sub.codes = c;
+        s->sub.decode.codes = c;
+        s->sub.decode.tl = tl;
+        s->sub.decode.td = td;
       }
       s->mode = CODES;
     case CODES:
@@ -326,7 +334,9 @@
       if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
         return inflate_flush(s, z, r);
       r = Z_OK;
-      inflate_codes_free(s->sub.codes, z);
+      inflate_codes_free(s->sub.decode.codes, z);
+      inflate_trees_free(s->sub.decode.td, z);
+      inflate_trees_free(s->sub.decode.tl, z);
       LOAD
       Tracev((stderr, "inflate:       codes end, %lu total out\n",
               z->total_out + (q >= s->read ? q - s->read :
diff --git a/infcodes.c b/infcodes.c
index 87e661b..4305290 100644
--- a/infcodes.c
+++ b/infcodes.c
@@ -83,7 +83,7 @@
 {
   uInt j;               /* temporary storage */
   inflate_huft *t;      /* temporary pointer */
-  int e;                /* extra bits or operation */
+  uInt e;               /* extra bits or operation */
   uLong b;              /* bit buffer */
   uInt k;               /* bits in bit buffer */
   Byte *p;              /* input data pointer */
@@ -91,7 +91,7 @@
   Byte *q;              /* output window write pointer */
   uInt m;               /* bytes to end of window or read pointer */
   Byte *f;              /* pointer to copy strings from */
-  struct inflate_codes_state *c = s->sub.codes; /* codes state */
+  struct inflate_codes_state *c = s->sub.decode.codes;  /* codes state */
 
   /* copy input/output information to locals (UPDATE macro restores) */
   LOAD
@@ -121,27 +121,8 @@
       NEEDBITS(j)
       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
       DUMPBITS(t->bits)
-      if ((e = (int)(t->exop)) < 0)
-      {
-        if (e == -128)          /* invalid code */
-        {
-          c->mode = BADCODE;
-          z->msg = "invalid literal/length code";
-          r = Z_DATA_ERROR;
-          LEAVE
-        }
-        e = -e;
-        if (e & 64)             /* end of block */
-        {
-          Tracevv((stderr, "inflate:         end of block\n"));
-          c->mode = WASH;
-          break;
-        }
-        c->sub.code.need = e;
-        c->sub.code.tree = t->next;
-        break;
-      }
-      if (e & 16)               /* literal */
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
       {
         c->sub.lit = t->base;
         Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
@@ -150,9 +131,29 @@
         c->mode = LIT;
         break;
       }
-      c->sub.copy.get = e;
-      c->len = t->base;
-      c->mode = LENEXT;
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = "invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
     case LENEXT:        /* i: getting length extra (have base) */
       j = c->sub.copy.get;
       NEEDBITS(j)
@@ -167,22 +168,24 @@
       NEEDBITS(j)
       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
       DUMPBITS(t->bits)
-      if ((e = (int)(t->exop)) < 0)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
       {
-        if (e == -128)
-        {
-          c->mode = BADCODE;
-          z->msg = "invalid distance code";
-          r = Z_DATA_ERROR;
-          LEAVE
-        }
-        c->sub.code.need = -e;
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
         c->sub.code.tree = t->next;
         break;
       }
-      c->sub.copy.dist = t->base;
-      c->sub.copy.get = e;
-      c->mode = DISTEXT;
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = "invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
     case DISTEXT:       /* i: getting distance extra */
       j = c->sub.copy.get;
       NEEDBITS(j)
@@ -231,8 +234,6 @@
 struct inflate_codes_state *c;
 z_stream *z;
 {
-  inflate_trees_free(c->dtree, z);
-  inflate_trees_free(c->ltree, z);
   ZFREE(z, c);
   Tracev((stderr, "inflate:       codes free\n"));
 }
diff --git a/inffast.c b/inffast.c
index 2fd707e..49ed1df 100644
--- a/inffast.c
+++ b/inffast.c
@@ -17,10 +17,6 @@
 #define bits word.what.Bits
 
 /* macros for bit input with no checking and for returning unused bytes */
-#ifdef DEBUG
-#  undef NEXTBYTE
-#  define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++)
-#endif
 #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
 #define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
 
@@ -36,7 +32,7 @@
 z_stream *z;
 {
   inflate_huft *t;      /* temporary pointer */
-  int e;                /* extra bits or operation */
+  uInt e;               /* extra bits or operation */
   uLong b;              /* bit buffer */
   uInt k;               /* bits in bit buffer */
   Byte *p;              /* input data pointer */
@@ -52,7 +48,7 @@
   /* load input, output, bit values */
   LOAD
 
-  /* initialize masks in registers */
+  /* initialize masks */
   ml = inflate_mask[bl];
   md = inflate_mask[bd];
 
@@ -60,93 +56,106 @@
   do {                          /* assume called with m >= 258 && n >= 10 */
     /* get literal/length code */
     GRABBITS(20)                /* max bits for literal/length code */
-    if ((e = (t = tl + ((uInt)b & ml))->exop) < 0)
-      do {
-        if (e == -128)
-        {
-          z->msg = "invalid literal/length code";
-          UNGRAB
-          UPDATE
-          return Z_DATA_ERROR;
-        }
-        DUMPBITS(t->bits)
-        e = -e;
-        if (e & 64)             /* end of block */
-        {
-          Tracevv((stderr, "inflate:         * end of block\n"));
-          UNGRAB
-          UPDATE
-          return Z_STREAM_END;
-        }
-      } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0);
-    DUMPBITS(t->bits)
-
-    /* process literal or length (end of block already trapped) */
-    if (e & 16)                 /* then it's a literal */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
     {
+      DUMPBITS(t->bits)
       Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
                 "inflate:         * literal '%c'\n" :
                 "inflate:         * literal 0x%02x\n", t->base));
       *q++ = (Byte)t->base;
       m--;
+      continue;
     }
-    else                        /* it's a length */
-    {
-      /* get length of block to copy (already have extra bits) */
-      c = t->base + ((uInt)b & inflate_mask[e]);
-      DUMPBITS(e);
-      Tracevv((stderr, "inflate:         * length %u\n", c));
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
 
-      /* decode distance base of block to copy */
-      GRABBITS(15);             /* max bits for distance code */
-      if ((e = (t = td + ((uInt)b & md))->exop) < 0)
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
         do {
-          if (e == -128)
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (q - s->window);  /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+          else
           {
             z->msg = "invalid distance code";
             UNGRAB
             UPDATE
             return Z_DATA_ERROR;
           }
-          DUMPBITS(t->bits)
-          e = -e;
-        } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0);
-      DUMPBITS(t->bits)
-
-      /* get extra bits to add to distance base */
-      GRABBITS((uInt)e)         /* get extra bits (up to 13) */
-      d = t->base + ((uInt)b & inflate_mask[e]);
-      DUMPBITS(e)
-      Tracevv((stderr, "inflate:         * distance %u\n", d));
-
-      /* do the copy */
-      m -= c;
-      if ((uInt)(q - s->window) >= d)   /* if offset before destination, */
-      {                                 /*  just copy */
-        r = q - d;
-        *q++ = *r++;  c--;              /* minimum count is three, */
-        *q++ = *r++;  c--;              /*  so unroll loop a little */
-        do {
-          *q++ = *r++;
-        } while (--c);
+        } while (1);
+        break;
       }
-      else                              /* else offset after destination */
+      if ((e & 64) == 0)
       {
-        e = d - (q - s->window);        /* bytes from offset to end */
-        r = s->end - e;                 /* pointer to offset */
-        if (c > (uInt)e)                /* if source crosses, */
+        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
         {
-          c -= e;                       /* copy to end of window */
-          do {
-            *q++ = *r++;
-          } while (--e);
-          r = s->window;                /* copy rest from start of window */
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
         }
-        do {                            /* copy all or what's left */
-          *q++ = *r++;
-        } while (--c);
       }
-    }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = "invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
   } while (m >= 258 && n >= 10);
 
   /* not enough input or output--restore pointers and return */
diff --git a/inftrees.c b/inftrees.c
index 9858927..377e8da 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -41,7 +41,7 @@
         /* actually lengths - 2; also see note #13 above about 258 */
 local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
         0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 128, 128}; /* 128==invalid */
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
 local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -246,7 +246,7 @@
         {
           x[h] = i;             /* save pattern for backing up */
           r.bits = (Byte)l;     /* bits to dump before this table */
-          r.exop = -(Char)j;    /* bits in this table */
+          r.exop = j;           /* bits in this table */
           r.next = q;           /* pointer to this table */
           j = i >> (w - l);     /* (get around Turbo C bug) */
           u[h-1][j] = r;        /* connect to last table */
@@ -256,15 +256,15 @@
       /* set up table entry in r */
       r.bits = (Byte)(k - w);
       if (p >= v + n)
-        r.exop = (Char)(-128);        /* out of values--invalid code */
+        r.exop = 128 + 64;      /* out of values--invalid code */
       else if (*p < s)
       {
-        r.exop = (Char)(*p < 256 ? 16 : -64);   /* 256 is end-of-block code */
+        r.exop = (*p < 256 ? 0 : 32 + 64);      /* 256 is end-of-block */
         r.base = *p++;          /* simple code is just the value */
       }
       else
       {
-        r.exop = (Char)e[*p - s];       /* non-simple--look up in lists */
+        r.exop = e[*p - s] + 16 + 64;   /* non-simple--look up in lists */
         r.base = d[*p++ - s];
       }
 
@@ -457,10 +457,6 @@
 {
   register inflate_huft *p, *q;
 
-  /* Don't free fixed trees */
-  if (t >= fixed_mem && t <= fixed_mem + FIXEDH)
-    return Z_OK;
-
   /* Go through linked list, freeing from the malloced (t[-1]) address. */
   p = t;
   while (p != Z_NULL)
diff --git a/inftrees.h b/inftrees.h
index 27e7222..03b85c5 100644
--- a/inftrees.h
+++ b/inftrees.h
@@ -9,24 +9,13 @@
  */
 
 /* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model).
-   Valid extra bits (exop) are 0..13.  exop == -64 is EOB (end of block),
-   exop == 16 means that v is a literal, exop < 0 means that v is a pointer
-   to the next table, which codes -exop bits, and lastly exop == -128
-   indicates an unused code.  If a code with exop == -128 is looked up,
-   this implies an error in the data. */
-
-#if defined(STDC) || defined(sgi)
-typedef signed char Char;
-#else
-typedef char Char; /* just hope that char is signed */
-#endif
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
 
 typedef struct inflate_huft_s inflate_huft;
 struct inflate_huft_s {
   union {
     struct {
-      Char Exop;        /* number of extra bits or operation */
+      Byte Exop;        /* number of extra bits or operation */
       Byte Bits;        /* number of bits in this code or subcode */
     } what;
     Byte *pad;          /* pad structure to a power of 2 (4 bytes for */
diff --git a/infutil.h b/infutil.h
index f234e9b..b5639d6 100644
--- a/infutil.h
+++ b/infutil.h
@@ -35,8 +35,11 @@
       uInt bb;                  /* bit length tree depth */
       inflate_huft *tb;         /* bit length decoding tree */
     } trees;            /* if DTREE, decoding info for trees */
-    struct inflate_codes_state
-      *codes;           /* if CODES, current state */
+    struct {
+      inflate_huft *tl, *td;    /* trees to free */
+      struct inflate_codes_state
+        *codes;
+    } decode;           /* if CODES, current state */
   } sub;                /* submode */
   uInt last;            /* true if this block is the last block */
 
diff --git a/minigzip.c b/minigzip.c
index 017c3e4..a542bfc 100644
--- a/minigzip.c
+++ b/minigzip.c
@@ -27,7 +27,7 @@
 #  include <string.h>
 #endif
 
-#ifdef MSDOS
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
 #  include <fcntl.h>
 #  include <io.h>
 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
diff --git a/trees.c b/trees.c
index f85716e..4c7c136 100644
--- a/trees.c
+++ b/trees.c
@@ -739,6 +739,17 @@
 }
 
 /* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate
+ */
+void ct_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+}
+
+/* ===========================================================================
  * Determine the best encoding for the current block: dynamic trees, static
  * trees or store, and output the encoded block to the zip file. This function
  * returns the total compressed length for the file so far.
diff --git a/zconf.h b/zconf.h
index ce93061..a819c8b 100644
--- a/zconf.h
+++ b/zconf.h
@@ -28,8 +28,14 @@
 #if defined(MSDOS) && !defined(__32BIT__)
 #  define MAXSEG_64K
 #endif
-#if !defined(STDC) && (defined(MSDOS) || defined(__STDC__))
-#  define STDC
+#ifndef STDC
+#  if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
+#    define STDC
+#  endif
+#endif
+
+#if !defined(STDC) && !defined(const)
+#  define const
 #endif
 
 /* Maximum value for memLevel in deflateInit2 */
diff --git a/zlib.h b/zlib.h
index 00a4394..d27173d 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,5 +1,5 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 0.92 May 3rd, 1995.
+  version 0.93 June 25th, 1995.
 
   Copyright (C) 1995 Jean-loup Gailly and Mark Adler
 
@@ -20,7 +20,7 @@
   3. This notice may not be removed or altered from any source distribution.
 
   Jean-loup Gailly        Mark Adler
-  gzip@prep.ai.mit.edu    madler@cco.caltech.edu
+  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
  */
 
 #ifndef _ZLIB_H
@@ -28,7 +28,7 @@
 
 #include "zconf.h"
 
-#define ZLIB_VERSION "0.92"
+#define ZLIB_VERSION "0.93"
 
 /* 
      The 'zlib' compression library provides in-memory compression and
@@ -108,6 +108,7 @@
 #define Z_NO_FLUSH      0
 #define Z_PARTIAL_FLUSH 1
 #define Z_FULL_FLUSH    2
+#define Z_SYNC_FLUSH    3 /* experimental: partial_flush + byte align */
 #define Z_FINISH        4
 /* See deflate() below for the usage of these constants */
 
diff --git a/zutil.h b/zutil.h
index bc8af52..fc54d57 100644
--- a/zutil.h
+++ b/zutil.h
@@ -15,11 +15,9 @@
 
 #include "zlib.h"
 
-#ifdef __GNUC__
-#  define INLINE inline
-#else
-#  define INLINE
-#endif
+/* #ifndef __GNUC__   disable inline for now */
+#  define inline
+/* #endif */
 
 #ifdef MSDOS
 #   include <stddef.h>