Example #1
0
/* given a data stream and a tree, decode a symbol */
static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
{
   int sum = 0, cur = 0, len = 0;

   /* get more bits while code value is above sum */
   do {

      cur = 2*cur + tinf_getbit(d);

      if (++len == TINF_ARRAY_SIZE(t->table)) {
         return TINF_DATA_ERROR;
      }

      sum += t->table[len];
      cur -= t->table[len];

   } while (cur >= 0);

   sum += cur;
   if (sum < 0 || sum >= (int)(TINF_ARRAY_SIZE(t->trans))) {
      return TINF_DATA_ERROR;
   }

   return t->trans[sum];
}
Example #2
0
/* inflate next byte of compressed stream */
int uzlib_uncompress(TINF_DATA *d)
{
    do {
        int res;

        /* start a new block */
        if (d->btype == -1) {
next_blk:
            /* read final block flag */
            d->bfinal = tinf_getbit(d);
            /* read block type (2 bits) */
            d->btype = tinf_read_bits(d, 2, 0);

            //printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);

            if (d->btype == 1) {
                /* build fixed huffman trees */
                tinf_build_fixed_trees(&d->ltree, &d->dtree);
            } else if (d->btype == 2) {
                /* decode trees from stream */
                res = tinf_decode_trees(d, &d->ltree, &d->dtree);
                if (res != TINF_OK) {
                    return res;
                }
            }
        }

        /* process current block */
        switch (d->btype)
        {
        case 0:
            /* decompress uncompressed block */
            res = tinf_inflate_uncompressed_block(d);
            break;
        case 1:
        case 2:
            /* decompress block with fixed/dynamic huffman trees */
            /* trees were decoded previously, so it's the same routine for both */
            res = tinf_inflate_block_data(d, &d->ltree, &d->dtree);
            break;
        default:
            return TINF_DATA_ERROR;
        }

        if (res == TINF_DONE && !d->bfinal) {
            /* the block has ended (without producing more data), but we
               can't return without data, so start procesing next block */
            goto next_blk;
        }

        if (res != TINF_OK) {
            return res;
        }

    } while (--d->destSize);

    return TINF_OK;
}
Example #3
0
/* inflate stream from source to dest */
int tinf_uncompress(void *dest, unsigned int *destLen,
                    const void *source, unsigned int sourceLen)
{
    TINF_DATA d;
    int bfinal;

    d.source = (const unsigned char *)source;
    d.bitcount = 0;

    d.dest = (unsigned char *)dest;
    d.destLen = destLen;

    *destLen = 0;

    do {

       unsigned int btype;
       int res;

       /* read final block flag */
       bfinal = tinf_getbit(&d);

       /* read block type (2 bits) */
       btype = tinf_read_bits(&d, 2, 0);

       /* decompress block */
       switch (btype)
       {
       case 0:
          /* decompress uncompressed block */
          res = tinf_inflate_uncompressed_block(&d);
          break;
        case 1:
          /* decompress block with fixed huffman trees */
          res = tinf_inflate_fixed_block(&d,&tbl);
          break;
       case 2:
          /* decompress block with dynamic huffman trees */
          res = tinf_inflate_dynamic_block(&d,&tbl);
          break;
       default:
          return TINF_DATA_ERROR;
       }

       if (res != TINF_OK) return TINF_DATA_ERROR;

       if (d.source > (unsigned char *)source + sourceLen)
           return TINF_DATA_ERROR;
    } while (!bfinal);

    return TINF_OK;
}
Example #4
0
/* inflate stream from source to dest */
int tinf_uncompress(void *dest, unsigned int *destLen,
                    const void *source, unsigned int sourceLen,
                    const unsigned int swapped_btype[3])
{
    TINF_DATA d;
    int bfinal;

    /* initialise data */
    d.source = (const unsigned char *)source;
    d.bitcount = 0;

    d.dest = (unsigned char *)dest;
    d.destLen = destLen;

    d.sourceLen = 0;
    d.sourceSize = sourceLen;
    d.destSize = *destLen;

    *destLen = 0;

    do {

        unsigned int btype;
        int res;

        /* read final block flag */
        bfinal = tinf_getbit(&d);

        /* read block type (2 bits) */
        btype = tinf_read_bits(&d, 2, 0);

        /* decompress block */
        if(btype == swapped_btype[0]) {
            /* decompress uncompressed block */
            res = tinf_inflate_uncompressed_block(&d);
        } else if(btype == swapped_btype[1]) {
            /* decompress block with fixed huffman trees */
            res = tinf_inflate_fixed_block(&d);
        } else if(btype == swapped_btype[2]) {
            /* decompress block with dynamic huffman trees */
            res = tinf_inflate_dynamic_block(&d);
        } else {
            return TINF_DATA_ERROR;
        }

        if (res != TINF_OK) return TINF_DATA_ERROR;

    } while (!bfinal);

    return TINF_OK;
}
Example #5
0
/* inflate stream from source to dest */
int tinf_uncompress(void *dest, unsigned int *destLen,
                    const void *source, unsigned int sourceLen)
{
   TINF_DATA d;
   int bfinal;

   /* initialise data */
   d.source = (const unsigned char *)source;
   d.bitcount = 0;

   d.dest = (unsigned char *)dest;
   d.destLen = destLen;

   *destLen = 0;

   do {

      unsigned int btype;
      int res;

      /* read block type (2 bits) */
      btype = tinf_read_bits(&d, 3, 0);
      
      /* read final block flag */
      bfinal = tinf_getbit(&d);

      /* decompress block */
      switch (btype)
      {
      case 7:
         /* decompress uncompressed block */
         res = tinf_inflate_uncompressed_block(&d);
         break;
      case 5:
         /* decompress block with fixed huffman trees */
         res = tinf_inflate_fixed_block(&d);
         break;
      case 6:
         /* decompress block with dynamic huffman trees */
         res = tinf_inflate_dynamic_block(&d);
         break;
      default:
         return -1;
      }

      if (res != TINF_OK) return -1;

   } while (!bfinal);

   return ((char*)d.source - (char *)source);
}
Example #6
0
/* read a num bit value from a stream and add base */
static unsigned int tinf_read_bits(TINF_DATA *d, int num, int base)
{
   unsigned int val = 0;

   /* read num bits */
   if (num)
   {
      unsigned int limit = 1 << (num);
      unsigned int mask;

      for (mask = 1; mask < limit; mask *= 2)
         if (tinf_getbit(d)) val += mask;
   }

   return val + base;
}
Example #7
0
/* given a data stream and a tree, decode a symbol */
static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
{
   int sum = 0, cur = 0, len = 0;

   /* get more bits while code value is above sum */
   do {

      cur = 2*cur + tinf_getbit(d);

      ++len;

      sum += t->table[len];
      cur -= t->table[len];

   } while (cur >= 0);

   return t->trans[sum + cur];
}