Exemple #1
0
/* given a stream and two trees, inflate a block of data */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
    if (d->curlen == 0) {
        unsigned int offs;
        int dist;
        int sym = tinf_decode_symbol(d, lt);
        //printf("huff sym: %02x\n", sym);

        if (d->eof) {
            return TINF_DATA_ERROR;
        }

        /* literal byte */
        if (sym < 256) {
            TINF_PUT(d, sym);
            return TINF_OK;
        }

        /* end of block */
        if (sym == 256) {
            return TINF_DONE;
        }

        /* substring from sliding dictionary */
        sym -= 257;
        /* possibly get more bits from length code */
        d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);

        dist = tinf_decode_symbol(d, dt);
        if (dist < 0) {
            return dist;
        }
        /* possibly get more bits from distance code */
        offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
        if (d->dict_ring) {
            if (offs > d->dict_size) {
                return TINF_DICT_ERROR;
            }
            d->lzOff = d->dict_idx - offs;
            if (d->lzOff < 0) {
                d->lzOff += d->dict_size;
            }
        } else {
            d->lzOff = -offs;
        }
    }

    /* copy next byte from dict substring */
    if (d->dict_ring) {
        TINF_PUT(d, d->dict_ring[d->lzOff]);
        if ((unsigned)++d->lzOff == d->dict_size) {
            d->lzOff = 0;
        }
    } else {
        d->dest[0] = d->dest[d->lzOff];
        d->dest++;
    }
    d->curlen--;
    return TINF_OK;
}
Exemple #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;
}
Exemple #3
0
/* given a stream and two trees, inflate a block of data */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
   /* remember current output position */
   unsigned char *start = d->dest;

   while (1)
   {
      int sym = tinf_decode_symbol(d, lt);

      /* check for end of block */
      if (sym == 256)
      {
         *d->destLen += d->dest - start;
         return TINF_OK;
      }

      if (sym < 256)
      {
         *d->dest++ = sym;

      } else {

         int length, dist, offs;
         int i;

         sym -= 257;

         /* possibly get more bits from length code */
         length = tinf_read_bits(d, length_bits[sym], length_base[sym]);

         dist = tinf_decode_symbol(d, dt);

         /* possibly get more bits from distance code */
         offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);

         /* copy match */
         for (i = 0; i < length; ++i)
         {
            d->dest[i] = d->dest[i - offs];
         }

         d->dest += length;
      }
   }
}
Exemple #4
0
/* given a stream and two trees, inflate a block of data */
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
    while (1)
    {
        int sym = tinf_decode_symbol(d, lt);

        /* check for end of block */
        if (sym == 256) break;

        if (sym < 256)
        {
            if ((*d->destLen + 1) > d->destSize) return TINF_DATA_ERROR;
            *d->dest++ = sym;
            *d->destLen += 1;

        } else {

            int length, dist, offs;
            int i;

            sym -= 257;

            /* possibly get more bits from length code */
            length = tinf_read_bits(d, length_bits[sym], length_base[sym]);

            dist = tinf_decode_symbol(d, dt);

            /* possibly get more bits from distance code */
            offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);

            /* copy match */
            if ((*d->destLen + length) > d->destSize) return TINF_DATA_ERROR;
            for (i = 0; i < length; ++i)
            {
                d->dest[i] = d->dest[i - offs];
            }

            d->dest += length;
            *d->destLen += length;
        }
    }
    return TINF_OK;
}
Exemple #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;

    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;
}
Exemple #6
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;
}
Exemple #7
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);
}
Exemple #8
0
/* given a data stream, decode dynamic trees from it */
static int tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
   unsigned char lengths[288+32];
   unsigned int hlit, hdist, hclen, hlimit;
   unsigned int i, num, length;

   /* get 5 bits HLIT (257-286) */
   hlit = tinf_read_bits(d, 5, 257);

   /* get 5 bits HDIST (1-32) */
   hdist = tinf_read_bits(d, 5, 1);

   /* get 4 bits HCLEN (4-19) */
   hclen = tinf_read_bits(d, 4, 4);

   for (i = 0; i < 19; ++i) lengths[i] = 0;

   /* read code lengths for code length alphabet */
   for (i = 0; i < hclen; ++i)
   {
      /* get 3 bits code length (0-7) */
      unsigned int clen = tinf_read_bits(d, 3, 0);

      lengths[clcidx[i]] = clen;
   }

   /* build code length tree, temporarily use length tree */
   tinf_build_tree(lt, lengths, 19);

   /* decode code lengths for the dynamic trees */
   hlimit = hlit + hdist;
   for (num = 0; num < hlimit; )
   {
      int sym = tinf_decode_symbol(d, lt);
      unsigned char fill_value = 0;
      int lbits, lbase = 3;

      /* error decoding */
      if (sym < 0) return sym;

      switch (sym)
      {
      case 16:
          if (num == 0) {
              return TINF_DATA_ERROR;
          }
         /* copy previous code length 3-6 times (read 2 bits) */
         fill_value = lengths[num - 1];
         lbits = 2;
         break;
      case 17:
         /* repeat code length 0 for 3-10 times (read 3 bits) */
         lbits = 3;
         break;
      case 18:
         /* repeat code length 0 for 11-138 times (read 7 bits) */
         lbits = 7;
         lbase = 11;
         break;
      default:
         /* values 0-15 represent the actual code lengths */
         lengths[num++] = sym;
         /* continue the for loop */
         continue;
      }

      /* special code length 16-18 are handled here */
      length = tinf_read_bits(d, lbits, lbase);
      if (num + length >= hlimit) return TINF_DATA_ERROR;
      for (; length; --length)
      {
         lengths[num++] = fill_value;
      }
   }

   /* build dynamic trees */
   tinf_build_tree(lt, lengths, hlit);
   tinf_build_tree(dt, lengths + hlit, hdist);

   return TINF_OK;
}
Exemple #9
0
/* given a data stream, decode dynamic trees from it */
static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
{
   TINF_TREE code_tree;
   unsigned char lengths[288+32];
   unsigned int hlit, hdist, hclen;
   unsigned int i, num, length;

   /* get 5 bits HLIT (257-286) */
   hlit = tinf_read_bits(d, 5, 257);

   /* get 5 bits HDIST (1-32) */
   hdist = tinf_read_bits(d, 5, 1);

   /* get 4 bits HCLEN (4-19) */
   hclen = tinf_read_bits(d, 4, 4);

   for (i = 0; i < 19; ++i) lengths[i] = 0;

   /* read code lengths for code length alphabet */
   for (i = 0; i < hclen; ++i)
   {
      /* get 3 bits code length (0-7) */
      unsigned int clen = tinf_read_bits(d, 3, 0);

      lengths[clcidx[i]] = clen;
   }

   /* build code length tree */
   tinf_build_tree(&code_tree, lengths, 19);

   /* decode code lengths for the dynamic trees */
   for (num = 0; num < hlit + hdist; )
   {
      int sym = tinf_decode_symbol(d, &code_tree);

      switch (sym)
      {
      case 16:
         /* copy previous code length 3-6 times (read 2 bits) */
         {
            unsigned char prev = lengths[num - 1];
            for (length = tinf_read_bits(d, 2, 3); length; --length)
            {
               lengths[num++] = prev;
            }
         }
         break;
      case 17:
         /* repeat code length 0 for 3-10 times (read 3 bits) */
         for (length = tinf_read_bits(d, 3, 3); length; --length)
         {
            lengths[num++] = 0;
         }
         break;
      case 18:
         /* repeat code length 0 for 11-138 times (read 7 bits) */
         for (length = tinf_read_bits(d, 7, 11); length; --length)
         {
            lengths[num++] = 0;
         }
         break;
      default:
         /* values 0-15 represent the actual code lengths */
         lengths[num++] = sym;
         break;
      }
   }

   /* build dynamic trees */
   tinf_build_tree(lt, lengths, hlit);
   tinf_build_tree(dt, lengths + hlit, hdist);
}