infcodes.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* infcodes.c -- process literals and length/distance pairs
  2.  * Copyright (C) 1995-1998 Mark Adler
  3.  * For conditions of distribution and use, see copyright notice in zlib.h 
  4.  */
  5. #include <linux/zutil.h>
  6. #include "inftrees.h"
  7. #include "infblock.h"
  8. #include "infcodes.h"
  9. #include "infutil.h"
  10. #include "inffast.h"
  11. /* simplify the use of the inflate_huft type with some defines */
  12. #define exop word.what.Exop
  13. #define bits word.what.Bits
  14. inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z)
  15. uInt bl, bd;
  16. inflate_huft *tl;
  17. inflate_huft *td; /* need separate declaration for Borland C++ */
  18. z_streamp z;
  19. {
  20.   inflate_codes_statef *c;
  21.   c = &WS(z)->working_state;
  22.   {
  23.     c->mode = START;
  24.     c->lbits = (Byte)bl;
  25.     c->dbits = (Byte)bd;
  26.     c->ltree = tl;
  27.     c->dtree = td;
  28.   }
  29.   return c;
  30. }
  31. int zlib_inflate_codes(s, z, r)
  32. inflate_blocks_statef *s;
  33. z_streamp z;
  34. int r;
  35. {
  36.   uInt j;               /* temporary storage */
  37.   inflate_huft *t;      /* temporary pointer */
  38.   uInt e;               /* extra bits or operation */
  39.   uLong b;              /* bit buffer */
  40.   uInt k;               /* bits in bit buffer */
  41.   Bytef *p;             /* input data pointer */
  42.   uInt n;               /* bytes available there */
  43.   Bytef *q;             /* output window write pointer */
  44.   uInt m;               /* bytes to end of window or read pointer */
  45.   Bytef *f;             /* pointer to copy strings from */
  46.   inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
  47.   /* copy input/output information to locals (UPDATE macro restores) */
  48.   LOAD
  49.   /* process input and output based on current state */
  50.   while (1) switch (c->mode)
  51.   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
  52.     case START:         /* x: set up for LEN */
  53. #ifndef SLOW
  54.       if (m >= 258 && n >= 10)
  55.       {
  56.         UPDATE
  57.         r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
  58.         LOAD
  59.         if (r != Z_OK)
  60.         {
  61.           c->mode = r == Z_STREAM_END ? WASH : BADCODE;
  62.           break;
  63.         }
  64.       }
  65. #endif /* !SLOW */
  66.       c->sub.code.need = c->lbits;
  67.       c->sub.code.tree = c->ltree;
  68.       c->mode = LEN;
  69.     case LEN:           /* i: get length/literal/eob next */
  70.       j = c->sub.code.need;
  71.       NEEDBITS(j)
  72.       t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
  73.       DUMPBITS(t->bits)
  74.       e = (uInt)(t->exop);
  75.       if (e == 0)               /* literal */
  76.       {
  77.         c->sub.lit = t->base;
  78.         c->mode = LIT;
  79.         break;
  80.       }
  81.       if (e & 16)               /* length */
  82.       {
  83.         c->sub.copy.get = e & 15;
  84.         c->len = t->base;
  85.         c->mode = LENEXT;
  86.         break;
  87.       }
  88.       if ((e & 64) == 0)        /* next table */
  89.       {
  90.         c->sub.code.need = e;
  91.         c->sub.code.tree = t + t->base;
  92.         break;
  93.       }
  94.       if (e & 32)               /* end of block */
  95.       {
  96.         c->mode = WASH;
  97.         break;
  98.       }
  99.       c->mode = BADCODE;        /* invalid code */
  100.       z->msg = (char*)"invalid literal/length code";
  101.       r = Z_DATA_ERROR;
  102.       LEAVE
  103.     case LENEXT:        /* i: getting length extra (have base) */
  104.       j = c->sub.copy.get;
  105.       NEEDBITS(j)
  106.       c->len += (uInt)b & zlib_inflate_mask[j];
  107.       DUMPBITS(j)
  108.       c->sub.code.need = c->dbits;
  109.       c->sub.code.tree = c->dtree;
  110.       c->mode = DIST;
  111.     case DIST:          /* i: get distance next */
  112.       j = c->sub.code.need;
  113.       NEEDBITS(j)
  114.       t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
  115.       DUMPBITS(t->bits)
  116.       e = (uInt)(t->exop);
  117.       if (e & 16)               /* distance */
  118.       {
  119.         c->sub.copy.get = e & 15;
  120.         c->sub.copy.dist = t->base;
  121.         c->mode = DISTEXT;
  122.         break;
  123.       }
  124.       if ((e & 64) == 0)        /* next table */
  125.       {
  126.         c->sub.code.need = e;
  127.         c->sub.code.tree = t + t->base;
  128.         break;
  129.       }
  130.       c->mode = BADCODE;        /* invalid code */
  131.       z->msg = (char*)"invalid distance code";
  132.       r = Z_DATA_ERROR;
  133.       LEAVE
  134.     case DISTEXT:       /* i: getting distance extra */
  135.       j = c->sub.copy.get;
  136.       NEEDBITS(j)
  137.       c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
  138.       DUMPBITS(j)
  139.       c->mode = COPY;
  140.     case COPY:          /* o: copying bytes in window, waiting for space */
  141. #ifndef __TURBOC__ /* Turbo C bug for following expression */
  142.       f = (uInt)(q - s->window) < c->sub.copy.dist ?
  143.           s->end - (c->sub.copy.dist - (q - s->window)) :
  144.           q - c->sub.copy.dist;
  145. #else
  146.       f = q - c->sub.copy.dist;
  147.       if ((uInt)(q - s->window) < c->sub.copy.dist)
  148.         f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
  149. #endif
  150.       while (c->len)
  151.       {
  152.         NEEDOUT
  153.         OUTBYTE(*f++)
  154.         if (f == s->end)
  155.           f = s->window;
  156.         c->len--;
  157.       }
  158.       c->mode = START;
  159.       break;
  160.     case LIT:           /* o: got literal, waiting for output space */
  161.       NEEDOUT
  162.       OUTBYTE(c->sub.lit)
  163.       c->mode = START;
  164.       break;
  165.     case WASH:          /* o: got eob, possibly more output */
  166.       if (k > 7)        /* return unused byte, if any */
  167.       {
  168.         k -= 8;
  169.         n++;
  170.         p--;            /* can always return one */
  171.       }
  172.       FLUSH
  173.       if (s->read != s->write)
  174.         LEAVE
  175.       c->mode = END;
  176.     case END:
  177.       r = Z_STREAM_END;
  178.       LEAVE
  179.     case BADCODE:       /* x: got error */
  180.       r = Z_DATA_ERROR;
  181.       LEAVE
  182.     default:
  183.       r = Z_STREAM_ERROR;
  184.       LEAVE
  185.   }
  186. #ifdef NEED_DUMMY_RETURN
  187.   return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
  188. #endif
  189. }
  190. void zlib_inflate_codes_free(c, z)
  191. inflate_codes_statef *c;
  192. z_streamp z;
  193. {
  194. }