Skip to content
Snippets Groups Projects
zlib.c 62.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* 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 */
    	e = (t = td + ((uInt)b & md))->exop;
    	do {
    	  DUMPBITS(t->bits)
    	  if (e & 16)
    	  {
    	    /* get extra bits to add to distance base */
    	    e &= 15;
    	    GRABBITS(e)         /* get extra bits (up to 13) */
    	    d = t->base + ((uInt)b & inflate_mask[e]);
    	    DUMPBITS(e)
    	    Tracevv((stderr, "inflate:         * distance %u\n", d));
    
    	    /* do the copy */
    	    m -= c;
    	    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;
    	  }
    	} while (1);
    	break;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
          }
          if ((e & 64) == 0)
          {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
    	{
    	  DUMPBITS(t->bits)
    	  Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
    		    "inflate:         * literal '%c'\n" :
    		    "inflate:         * literal 0x%02x\n", t->base));
    	  *q++ = (Byte)t->base;
    	  m--;
    	  break;
    	}
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
          }
          else if (e & 32)
          {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	Tracevv((stderr, "inflate:         * end of block\n"));
    	UNGRAB
    	UPDATE
    	return Z_STREAM_END;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
          }
          else
          {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	z->msg = "invalid literal/length code";
    	UNGRAB
    	UPDATE
    	return Z_DATA_ERROR;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
          }
        } while (1);
      } while (m >= 258 && n >= 10);
    
      /* not enough input or output--restore pointers and return */
      UNGRAB
      UPDATE
      return Z_OK;
    }
    
    
    /*+++++*/
    /* zutil.c -- target dependent utility functions for the compression library
     * Copyright (C) 1995 Jean-loup Gailly.
     * For conditions of distribution and use, see copyright notice in zlib.h
     */
    
    /* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
    
    char *zlib_version = ZLIB_VERSION;
    
    char *z_errmsg[] = {
    "stream end",          /* Z_STREAM_END    1 */
    "",                    /* Z_OK            0 */
    "file error",          /* Z_ERRNO        (-1) */
    "stream error",        /* Z_STREAM_ERROR (-2) */
    "data error",          /* Z_DATA_ERROR   (-3) */
    "insufficient memory", /* Z_MEM_ERROR    (-4) */
    "buffer error",        /* Z_BUF_ERROR    (-5) */
    ""};
    
    
    /*+++++*/
    /* adler32.c -- compute the Adler-32 checksum of a data stream
     * Copyright (C) 1995 Mark Adler
     * For conditions of distribution and use, see copyright notice in zlib.h
     */
    
    /* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
    
    #define BASE 65521L /* largest prime smaller than 65536 */
    #define NMAX 5552
    /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
    
    #define DO1(buf)  {s1 += *buf++; s2 += s1;}
    #define DO2(buf)  DO1(buf); DO1(buf);
    #define DO4(buf)  DO2(buf); DO2(buf);
    #define DO8(buf)  DO4(buf); DO4(buf);
    #define DO16(buf) DO8(buf); DO8(buf);
    
    /* ========================================================================= */
    uLong adler32(adler, buf, len)
        uLong adler;
        Bytef *buf;
        uInt len;
    {
        unsigned long s1 = adler & 0xffff;
        unsigned long s2 = (adler >> 16) & 0xffff;
        int k;
    
        if (buf == Z_NULL) return 1L;
    
        while (len > 0) {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	k = len < NMAX ? len : NMAX;
    	len -= k;
    	while (k >= 16) {
    	    DO16(buf);
    	    k -= 16;
    	}
    	if (k != 0) do {
    	    DO1(buf);
    	} while (--k);
    	s1 %= BASE;
    	s2 %= BASE;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
        }
        return (s2 << 16) | s1;
    }