infcodes.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: infcodes.c,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 15:48:47  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* infcodes.c -- process literals and length/distance pairs
  10.  * Copyright (C) 1995-2002 Mark Adler
  11.  * For conditions of distribution and use, see copyright notice in zlib.h 
  12.  */
  13. #include "zutil.h"
  14. #include "inftrees.h"
  15. #include "infblock.h"
  16. #include "infcodes.h"
  17. #include "infutil.h"
  18. #include "inffast.h"
  19. /* simplify the use of the inflate_huft type with some defines */
  20. #define exop word.what.Exop
  21. #define bits word.what.Bits
  22. typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
  23.       START,    /* x: set up for LEN */
  24.       LEN,      /* i: get length/literal/eob next */
  25.       LENEXT,   /* i: getting length extra (have base) */
  26.       DIST,     /* i: get distance next */
  27.       DISTEXT,  /* i: getting distance extra */
  28.       COPY,     /* o: copying bytes in window, waiting for space */
  29.       LIT,      /* o: got literal, waiting for output space */
  30.       WASH,     /* o: got eob, possibly still output waiting */
  31.       END,      /* x: got eob and all data flushed */
  32.       BADCODE}  /* x: got error */
  33. inflate_codes_mode;
  34. /* inflate codes private state */
  35. struct inflate_codes_state {
  36.   /* mode */
  37.   inflate_codes_mode mode;      /* current inflate_codes mode */
  38.   /* mode dependent information */
  39.   uInt len;
  40.   union {
  41.     struct {
  42.       inflate_huft *tree;       /* pointer into tree */
  43.       uInt need;                /* bits needed */
  44.     } code;             /* if LEN or DIST, where in tree */
  45.     uInt lit;           /* if LIT, literal */
  46.     struct {
  47.       uInt get;                 /* bits to get for extra */
  48.       uInt dist;                /* distance back to copy from */
  49.     } copy;             /* if EXT or COPY, where and how much */
  50.   } sub;                /* submode */
  51.   /* mode independent information */
  52.   Byte lbits;           /* ltree bits decoded per branch */
  53.   Byte dbits;           /* dtree bits decoder per branch */
  54.   inflate_huft *ltree;          /* literal/length/eob tree */
  55.   inflate_huft *dtree;          /* distance tree */
  56. };
  57. inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
  58. uInt bl, bd;
  59. inflate_huft *tl;
  60. inflate_huft *td; /* need separate declaration for Borland C++ */
  61. z_streamp z;
  62. {
  63.   inflate_codes_statef *c;
  64.   if ((c = (inflate_codes_statef *)
  65.        ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
  66.   {
  67.     c->mode = START;
  68.     c->lbits = (Byte)bl;
  69.     c->dbits = (Byte)bd;
  70.     c->ltree = tl;
  71.     c->dtree = td;
  72.     Tracev((stderr, "inflate:       codes newn"));
  73.   }
  74.   return c;
  75. }
  76. int inflate_codes(s, z, r)
  77. inflate_blocks_statef *s;
  78. z_streamp z;
  79. int r;
  80. {
  81.   uInt j;               /* temporary storage */
  82.   inflate_huft *t;      /* temporary pointer */
  83.   uInt e;               /* extra bits or operation */
  84.   uLong b;              /* bit buffer */
  85.   uInt k;               /* bits in bit buffer */
  86.   Bytef *p;             /* input data pointer */
  87.   uInt n;               /* bytes available there */
  88.   Bytef *q;             /* output window write pointer */
  89.   uInt m;               /* bytes to end of window or read pointer */
  90.   Bytef *f;             /* pointer to copy strings from */
  91.   inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
  92.   /* copy input/output information to locals (UPDATE macro restores) */
  93.   LOAD
  94.   /* process input and output based on current state */
  95.   while (1) switch (c->mode)
  96.   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
  97.     case START:         /* x: set up for LEN */
  98. #ifndef SLOW
  99.       if (m >= 258 && n >= 10)
  100.       {
  101.         UPDATE
  102.         r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
  103.         LOAD
  104.         if (r != Z_OK)
  105.         {
  106.           c->mode = r == Z_STREAM_END ? WASH : BADCODE;
  107.           break;
  108.         }
  109.       }
  110. #endif /* !SLOW */
  111.       c->sub.code.need = c->lbits;
  112.       c->sub.code.tree = c->ltree;
  113.       c->mode = LEN;
  114.     case LEN:           /* i: get length/literal/eob next */
  115.       j = c->sub.code.need;
  116.       NEEDBITS(j)
  117.       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
  118.       DUMPBITS(t->bits)
  119.       e = (uInt)(t->exop);
  120.       if (e == 0)               /* literal */
  121.       {
  122.         c->sub.lit = t->base;
  123.         Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
  124.                  "inflate:         literal '%c'n" :
  125.                  "inflate:         literal 0x%02xn", t->base));
  126.         c->mode = LIT;
  127.         break;
  128.       }
  129.       if (e & 16)               /* length */
  130.       {
  131.         c->sub.copy.get = e & 15;
  132.         c->len = t->base;
  133.         c->mode = LENEXT;
  134.         break;
  135.       }
  136.       if ((e & 64) == 0)        /* next table */
  137.       {
  138.         c->sub.code.need = e;
  139.         c->sub.code.tree = t + t->base;
  140.         break;
  141.       }
  142.       if (e & 32)               /* end of block */
  143.       {
  144.         Tracevv((stderr, "inflate:         end of blockn"));
  145.         c->mode = WASH;
  146.         break;
  147.       }
  148.       c->mode = BADCODE;        /* invalid code */
  149.       z->msg = (char*)"invalid literal/length code";
  150.       r = Z_DATA_ERROR;
  151.       LEAVE
  152.     case LENEXT:        /* i: getting length extra (have base) */
  153.       j = c->sub.copy.get;
  154.       NEEDBITS(j)
  155.       c->len += (uInt)b & inflate_mask[j];
  156.       DUMPBITS(j)
  157.       c->sub.code.need = c->dbits;
  158.       c->sub.code.tree = c->dtree;
  159.       Tracevv((stderr, "inflate:         length %un", c->len));
  160.       c->mode = DIST;
  161.     case DIST:          /* i: get distance next */
  162.       j = c->sub.code.need;
  163.       NEEDBITS(j)
  164.       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
  165.       DUMPBITS(t->bits)
  166.       e = (uInt)(t->exop);
  167.       if (e & 16)               /* distance */
  168.       {
  169.         c->sub.copy.get = e & 15;
  170.         c->sub.copy.dist = t->base;
  171.         c->mode = DISTEXT;
  172.         break;
  173.       }
  174.       if ((e & 64) == 0)        /* next table */
  175.       {
  176.         c->sub.code.need = e;
  177.         c->sub.code.tree = t + t->base;
  178.         break;
  179.       }
  180.       c->mode = BADCODE;        /* invalid code */
  181.       z->msg = (char*)"invalid distance code";
  182.       r = Z_DATA_ERROR;
  183.       LEAVE
  184.     case DISTEXT:       /* i: getting distance extra */
  185.       j = c->sub.copy.get;
  186.       NEEDBITS(j)
  187.       c->sub.copy.dist += (uInt)b & inflate_mask[j];
  188.       DUMPBITS(j)
  189.       Tracevv((stderr, "inflate:         distance %un", c->sub.copy.dist));
  190.       c->mode = COPY;
  191.     case COPY:          /* o: copying bytes in window, waiting for space */
  192.       f = q - c->sub.copy.dist;
  193.       while (f < s->window)             /* modulo window size-"while" instead */
  194.         f += s->end - s->window;        /* of "if" handles invalid distances */
  195.       while (c->len)
  196.       {
  197.         NEEDOUT
  198.         OUTBYTE(*f++)
  199.         if (f == s->end)
  200.           f = s->window;
  201.         c->len--;
  202.       }
  203.       c->mode = START;
  204.       break;
  205.     case LIT:           /* o: got literal, waiting for output space */
  206.       NEEDOUT
  207.       OUTBYTE(c->sub.lit)
  208.       c->mode = START;
  209.       break;
  210.     case WASH:          /* o: got eob, possibly more output */
  211.       if (k > 7)        /* return unused byte, if any */
  212.       {
  213.         Assert(k < 16, "inflate_codes grabbed too many bytes")
  214.         k -= 8;
  215.         n++;
  216.         p--;            /* can always return one */
  217.       }
  218.       FLUSH
  219.       if (s->read != s->write)
  220.         LEAVE
  221.       c->mode = END;
  222.     case END:
  223.       r = Z_STREAM_END;
  224.       LEAVE
  225.     case BADCODE:       /* x: got error */
  226.       r = Z_DATA_ERROR;
  227.       LEAVE
  228.     default:
  229.       r = Z_STREAM_ERROR;
  230.       LEAVE
  231.   }
  232. #ifdef NEED_DUMMY_RETURN
  233.   return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
  234. #endif
  235. }
  236. void inflate_codes_free(c, z)
  237. inflate_codes_statef *c;
  238. z_streamp z;
  239. {
  240.   ZFREE(z, c);
  241.   Tracev((stderr, "inflate:       codes freen"));
  242. }