Пример #1
0
        int Decode(Huffman *h)
        {
            int    len;         /* current number of Bits in code */
            int    code;        /* len Bits being decoded */
            int    first;       /* first code of length len */
            int    count;       /* number of Codes of length len */
            int    index;       /* index of first code of length len in symbol table */
            int    bitbuf;      /* Bits from stream */
            int    left;        /* Bits left in next or left to process */
            short *next;        /* next number of Codes */

            bitbuf = this.bitbuf;
            left   = bitcnt;
            code   = first = index = 0;
            len    = 1;
            next   = h->count + 1;
            while (true)
            {
                while (left-- != 0)
                {
                    code    |= bitbuf & 1;
                    bitbuf >>= 1;
                    count    = *next++;
                    if (code < first + count)   /* if length len, return symbol */
                    {
                        this.bitbuf = bitbuf;
                        bitcnt      = (bitcnt - len) & 7;
                        return(h->symbol[index + (code - first)]);
                    }
                    index  += count;            /* else update for next length */
                    first  += count;
                    first <<= 1;
                    code  <<= 1;
                    len++;
                }
                left = (MAXBITS + 1) - len;
                if (left == 0)
                {
                    break;
                }
                if (incnt == inlen)
                {
                    throw new InvalidDataException("Output of input");                 //longjmp(env, 1);   /* out of input */
                }
                //if (incnt == inlen) throw new Exception("Out of length");
                bitbuf = inBuffer[incnt++];
                if (incnt == incntToJump)
                {
                    JumpToNextSourceChunk();
                }
                if (left > 8)
                {
                    left = 8;
                }
            }
            return(-9);                          /* ran out of Codes */
        }
Пример #2
0
        int Construct(Huffman *h, short *length, int n)
        {
            int    symbol;                               /* current symbol when stepping through length[] */
            int    len;                                  /* current length when stepping through h->count[] */
            int    left;                                 /* number of possible Codes left of current length */
            short *offs = stackalloc short[MAXBITS + 1]; /* offsets in symbol table for each length */

            /* count number of Codes of each length */
            for (len = 0; len <= MAXBITS; len++)
            {
                h->count[len] = 0;
            }
            for (symbol = 0; symbol < n; symbol++)
            {
                (h->count[length[symbol]])++;   /* assumes lengths are within bounds */
            }
            if (h->count[0] == n)               /* no Codes! */
            {
                return(0);                      /* complete, but Decode() will fail */
            }
            /* check for an over-subscribed or incomplete set of lengths */
            left = 1;                           /* one possible code of zero length */
            for (len = 1; len <= MAXBITS; len++)
            {
                left <<= 1;                     /* one more bit, double Codes left */
                left  -= h->count[len];         /* deduct count from possible Codes */
                if (left < 0)
                {
                    return(left);               /* over-subscribed--return negative */
                }
            }                                   /* left > 0 means incomplete */

            /* generate offsets into symbol table for each length for sorting */
            offs[1] = 0;
            for (len = 1; len < MAXBITS; len++)
            {
                offs[len + 1] = (short)(offs[len] + h->count[len]);
            }

            /*
             * put symbols in table sorted by length, by symbol order within each
             * length
             */
            for (symbol = 0; symbol < n; symbol++)
            {
                if (length[symbol] != 0)
                {
                    h->symbol[offs[length[symbol]]++] = (short)symbol;
                }
            }

            /* return zero for complete set, positive for incomplete set */
            return(left);
        }
Пример #3
0
        int Codes(Huffman *lencode, Huffman *distcode)
        {
            int  symbol;    /* decoded symbol */
            int  len;       /* length for copy */
            uint dist;      /* distance for copy */

            /* Decode literals and length/distance pairs */
            do
            {
                symbol = Decode(lencode);
                if (symbol < 0)
                {
                    return(symbol);             /* invalid symbol */
                }
                if (symbol < 256)               /* literal: symbol is the byte */
                /* write out the literal */
                {
                    if (outBuffer != NIL)
                    {
                        if (outcnt == outlen)
                        {
                            return(1);
                        }
                        outBuffer[outcnt] = (byte)symbol;
                    }
                    outcnt++;
                }
                else if (symbol > 256)          /* length */
                /* get and compute length */
                {
                    symbol -= 257;
                    if (symbol >= 29)
                    {
                        return(-9);                     /* invalid fixed code */
                    }
                    len = lens[symbol] + Bits(lext[symbol]);

                    /* get and check distance */
                    symbol = Decode(distcode);
                    if (symbol < 0)
                    {
                        return(symbol);                 /* invalid symbol */
                    }
                    dist = (uint)(dists[symbol] + Bits(dext[symbol]));
                    if (dist > outcnt)
                    {
                        return(-10);     /* distance too far back */
                    }
                    /* copy length bytes from distance bytes back */
                    if (outBuffer != NIL)
                    {
                        if (outcnt + len > outlen)
                        {
                            return(1);
                        }
                        while (len-- != 0)
                        {
                            outBuffer[outcnt] = outBuffer[outcnt - dist];
                            outcnt++;
                        }
                    }
                    else
                    {
                        outcnt += (uint)len;
                    }
                }
            } while (symbol != 256);            /* end of block symbol */

            /* done with a valid fixed or dynamic block */
            return(0);
        }