⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inflate.c

📁 该代码包为INTEL IXP2400单板的BSP,同时经过修改,可以对MSN和ixf1104做自定义配置
💻 C
📖 第 1 页 / 共 5 页
字号:
            /* 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 - (UINT)(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 = (char*)"invalid distance code";
            UNGRAB
            ZUPDATE
            return Z_DATA_ERROR;
          }
        } while (1);
        break;
      }
      if ((e & 64) == 0)
      {
        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;
        }
      }
      else if (e & 32)
      {
        Tracevv((stderr, "inflate:         * end of block\n"));
        UNGRAB
        ZUPDATE
        return Z_STREAM_END;
      }
      else
      {
        z->msg = (char*)"invalid literal/length code";
        UNGRAB
        ZUPDATE
        return Z_DATA_ERROR;
      }
    } while (1);
  } while (m >= 258 && n >= 10);

  /* not enough input or output--restore pointers and return */
  UNGRAB
  ZUPDATE
  return Z_OK;
}

/******************************************************************************
*
* inflate_codes_new -
*/

static inflate_codes_statef *inflate_codes_new(
    UINT bl, UINT bd,
    inflate_huft *tl,
    inflate_huft *td, /* need separate declaration for Borland C++ */
    ZAR_STREAM* z )
{
  inflate_codes_statef *c;

  if ((c = (inflate_codes_statef *)
       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != NULL)
  {
    c->mode = START;
    c->lbits = (BYTE)bl;
    c->dbits = (BYTE)bd;
     c->ltree = tl;
    c->dtree = td;
    Tracev((stderr, "inflate:       codes new\n"));
  }
  return c;
}

/******************************************************************************
*
* inflate_codes -
*/

static int inflate_codes(   inflate_blocks_statef *s,
                            ZAR_STREAM* z,
                            int r)
{
  UINT j;               /* temporary storage */
  inflate_huft *t;      /* temporary pointer */
  UINT e;               /* extra bits or operation */
  ULONG b;              /* bit buffer */
  UINT k;               /* bits in bit buffer */
  BYTE *p;             /* input data pointer */
  UINT n;               /* bytes available there */
  BYTE *q;             /* output window write pointer */
  UINT m;               /* bytes to end of window or read pointer */
  BYTE *f;             /* pointer to copy strings from */
  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */

  /* copy input/output information to locals (ZUPDATE macro restores) */
  LOAD

  /* process input and output based on current state */
  while (1) switch (c->mode)
  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
    case START:         /* x: set up for LEN */
      if (m >= 258 && n >= 10)
      {
        ZUPDATE
        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
        LOAD
        if (r != Z_OK)
        {
          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
          break;
        }
      }
      c->sub.code.need = c->lbits;
      c->sub.code.tree = c->ltree;
      c->mode = LEN;
    case LEN:           /* i: get length/literal/eob next */
      j = c->sub.code.need;
      NEEDBITS(j)
      t = c->sub.code.tree + ((UINT)b & inflate_mask[j]);
      DUMPBITS(t->bits)
      e = (UINT)(t->exop);
      if (e == 0)               /* literal */
      {
        c->sub.lit = t->base;
        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
                 "inflate:         literal '%c'\n" :
                 "inflate:         literal 0x%02x\n", t->base));
        c->mode = LIT;
          break;
      }
      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 = (char*)"invalid literal/length code";
      r = Z_DATA_ERROR;
      ZLEAVE
    case LENEXT:        /* i: getting length extra (have base) */
      j = c->sub.copy.get;
      NEEDBITS(j)
      c->len += (UINT)b & inflate_mask[j];
      DUMPBITS(j)
      c->sub.code.need = c->dbits;
      c->sub.code.tree = c->dtree;
      Tracevv((stderr, "inflate:         length %u\n", c->len));
      c->mode = DIST;
    case DIST:          /* i: get distance next */
      j = c->sub.code.need;
      NEEDBITS(j)
      t = c->sub.code.tree + ((UINT)b & inflate_mask[j]);
      DUMPBITS(t->bits)
      e = (UINT)(t->exop);
      if (e & 16)               /* distance */
      {
        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->mode = BADCODE;        /* invalid code */
      z->msg = (char*)"invalid distance code";
      r = Z_DATA_ERROR;
      ZLEAVE
    case DISTEXT:       /* i: getting distance extra */
      j = c->sub.copy.get;

        NEEDBITS(j)

        c->sub.copy.dist += (UINT)b & inflate_mask[j];
        DUMPBITS(j)
        Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
        c->mode = COPY;
     case COPY:          /* o: copying bytes in window, waiting for space */
#ifndef __TURBOC__ /* Turbo C bug for following expression */
        f = (UINT)(q - s->window) < c->sub.copy.dist ?
             s->end - (c->sub.copy.dist - (q - s->window)) :
             q - c->sub.copy.dist;
#else
        f = q - c->sub.copy.dist;
        if ((UINT)(q - s->window) < c->sub.copy.dist)
          f = s->end - (c->sub.copy.dist - (UINT)(q - s->window));
#endif
        while (c->len)
        {
          NEEDOUT
          OUTBYTE(*f++)
          if (f == s->end)
             f = s->window;
          c->len--;
        }
        c->mode = START;
        break;
     case LIT:           /* o: got literal, waiting for output space */
        NEEDOUT
        OUTBYTE(c->sub.lit)
        c->mode = START;
        break;
     case WASH:          /* o: got eob, possibly more output */
        FLUSH
        if (s->read != s->write)
          ZLEAVE
        c->mode = END;
     case END:
        r = Z_STREAM_END;
        ZLEAVE
     case BADCODE:       /* x: got error */
        r = Z_DATA_ERROR;
        ZLEAVE
     default:
        r = Z_STREAM_ERROR;
        ZLEAVE
  }
}

/******************************************************************************
*
* inflate_codes_free -
*/

static void inflate_codes_free
     (
     inflate_codes_statef *c,
     ZAR_STREAM* z
     )
     {
     ZFREE(z, c);
     }

/******************************************************************************
*
* inflate_blocks_reset -
*/

static void inflate_blocks_reset(   inflate_blocks_statef *s,
                                    ZAR_STREAM* z,
                                    ULONG *c )
{
  if (s->checkfn != NULL)
     *c = s->check;
  if (s->mode == BTREE || s->mode == DTREE)
     ZFREE(z, s->sub.trees.blens);
  if (s->mode == CODES)
  {
     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;
  s->read = s->write = s->window;
  if (s->checkfn != NULL)
     z->adler = s->check = (*s->checkfn)(0L, NULL, 0);
  Trace((stderr, "inflate:   blocks reset\n"));
}

/******************************************************************************
*
* inflate_blocks_new -
*/

static inflate_blocks_statef *inflate_blocks_new(
        ZAR_STREAM* z,
        check_func c,
        UINT w )
{
  inflate_blocks_statef *s;

  if ((s = (inflate_blocks_statef *)ZALLOC
         (z,1,sizeof(struct inflate_blocks_state))) == NULL)
     return s;
  if ((s->window = (BYTE *)ZALLOC(z, 1, w)) == NULL)
  {
     ZFREE(z, s);
     return NULL;
  }
  s->end = s->window + w;
  s->checkfn = c;
  s->mode = TYPE;
  Trace((stderr, "inflate:   blocks allocated\n"));
  inflate_blocks_reset(s, z, &s->check);
  return s;
}


/******************************************************************************
*
* inflate_block -
*/

static int inflate_blocks(
    inflate_blocks_statef *s,
    ZAR_STREAM* z,
    int r)
{
  UINT t;               /* temporary storage */
  ULONG b;              /* bit buffer */
  UINT k;               /* bits in bit buffer */
  BYTE *p;             /* input data pointer */
  UINT n;               /* bytes available there */
  BYTE *q;             /* output window write pointer */
  UINT m;               /* bytes to end of window or read pointer */

  /* copy input/output information to locals (ZUPDATE macro restores) */
  LOAD

  /* process input based on current state */
  while (1) switch (s->mode)
  {
     case TYPE:
        NEEDBITS(3)
        t = (UINT)b & 7;
        s->last = t & 1;
        switch (t >> 1)
        {
          case 0:                         /* stored */
             Trace((stderr, "inflate:     stored block%s\n",
                      s->last ? " (last)" : ""));
             DUMPBITS(3)
             t = k & 7;                    /* go to byte boundary */
             DUMPBITS(t)
             s->mode = LENS;               /* get length of stored block */
             break;
          case 1:                         /* fixed */
             Trace((stderr, "inflate:     fixed codes block%s\n",
                      s->last ? " (last)" : ""));
             {
                UINT bl, bd;
                inflate_huft *tl, *td;

                inflate_trees_fixed(z,&bl, &bd, &tl, &td);
                s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
                if (s->sub.decode.codes == NULL)
                {
                  r = Z_MEM_ERROR;
                  ZLEAVE
                }
                s->sub.decode.tl = NULL;  /* don't try to free these */
                s->sub.decode.td = NULL;
             }
             DUMPBITS(3)
             s->mode = CODES;
             break;
          case 2:                         /* dynamic */
             Trace((stderr, "inflate:     dynamic codes block%s\n",
                      s->last ? " (last)" : ""));
             DUMPBITS(3)
             s->mode = TABLE;
             break;
          case 3:                         /* illegal */
             DUMPBITS(3)
             s->mode = BAD;
             z->msg = (char*)"invalid block type";
             r = Z_DATA_ERROR;
             ZLEAVE
        }
        break;
     case LENS:
        NEEDBITS(32)
        if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
        {
          s->mode = BAD;
          z->msg = (char*)"invalid stored block lengths";
          r = Z_DATA_ERROR;
          ZLEAVE
        }
        s->sub.left = (UINT)b & 0xffff;
        b = k = 0;                      /* dump bits */
        Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
        s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
        break;
     case STORED:
        if (n == 0)
          ZLEAVE
        NEEDOUT
        t = s->sub.left;
        if (t > n) t = n;
        if (t > m) t = m;
        memcpy(q, p, t);
        p += t;  n -= t;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -