Example #1
0
            public Byte[] GetBytes()
            {
                Int32 n = GetByteCount();

                if (n == -1)
                {
                    return(null);
                }
                Byte[] buf = new Byte[n];
                if (n == 0)
                {
                    return(buf);
                }

                Int32   MAX_BITS   = mData[2] & 0x1f;
                Boolean BLOCK_MODE = ((mData[2] & 0x80) != 0);

                n           = 1 << MAX_BITS;
                mPrefixCode = new Int32[n];
                mSuffixByte = new Byte[n];
                for (Int32 i = 0; i < 256; i++)
                {
                    mPrefixCode[i] = -1;
                    mSuffixByte[i] = (Byte)i;
                }

                Int32      block_offset = 3;
                BitReaderL R            = new BitReaderL(mData, block_offset);
                Int32      code_size    = 9;
                Int32      code_max     = (1 << code_size) - 1;
                Int32      next_free    = (BLOCK_MODE) ? 257 : 256;
                Int32      code         = R.Next(code_size);

                n = 0;
                Byte  b         = Put(buf, ref n, code); // first code gets output without adding anything to dictionary
                Int32 prev_code = code;

                while ((code = R.Next(code_size)) != -1)
                {
                    if ((code == 256) && BLOCK_MODE)
                    {
                        // start reading a new block, with code size reset to 9
                        R         = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size));
                        code_max  = (1 << (code_size = 9)) - 1;
                        next_free = 256; // use 256 instead of 257 so next code isn't (usably) added to dictionary
                        continue;
                    }
                    if (code == next_free)
                    {
                        // special case: the last byte of this code is the same as the first byte of the previous code
                        mLength[code]     = mLength[prev_code] + 1;
                        mPrefixCode[code] = prev_code;
                        mSuffixByte[code] = b;
                    }
                    b = Put(buf, ref n, code);
                    if (next_free <= code_max)
                    {
                        // add a new code to dictionary for prev_code plus the first byte of current code
                        mLength[next_free]     = mLength[prev_code] + 1;
                        mPrefixCode[next_free] = prev_code;
                        mSuffixByte[next_free] = b;
                        if ((next_free == code_max) && (code_size < MAX_BITS))
                        {
                            // start reading a new block, with code size increased by 1
                            R        = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size));
                            code_max = (1 << ++code_size) - 1;
                        }
                        next_free++;
                    }
                    prev_code = code;
                }
                return(buf);
            }
Example #2
0
            public Int32 GetByteCount()
            {
                if (mSize != -2)
                {
                    return(mSize);
                }
                if (!HasHeader(mData))
                {
                    return(mSize = -1);
                }
                Int32 MAX_BITS = mData[2] & 0x1f;

                if (MAX_BITS > 24)
                {
                    return(mSize = -1);                 // current BitReader only handles up to 24-bit code words
                }
                if ((mData[2] & 0x60) != 0)
                {
                    return(mSize = -1);                          // unsupported flag bits
                }
                Boolean BLOCK_MODE = ((mData[2] & 0x80) != 0);

                Int32 n = 1 << MAX_BITS;

                mLength = new Int32[n];
                for (Int32 i = 0; i < 256; i++)
                {
                    mLength[i] = 1;
                }
                Int32      block_offset = 3;
                BitReaderL R            = new BitReaderL(mData, block_offset);
                Int32      code_size    = 9;
                Int32      code_max     = (1 << code_size) - 1;
                Int32      next_free    = (BLOCK_MODE) ? 257 : 256;
                Int32      code         = R.Next(code_size);

                if (code == -1)
                {
                    return(mSize = 0); // valid 0-byte output
                }
                n = 1;                 // first code is always for 1 byte, so start count at 1
                Int32 prev_code = code;

                while ((code = R.Next(code_size)) != -1)
                {
                    if ((code == 256) && BLOCK_MODE)
                    {
                        // start reading a new block, with code size reset to 9
                        R         = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size));
                        code_max  = (1 << (code_size = 9)) - 1;
                        next_free = 256; // use 256 instead of 257 so next code isn't (usably) added to dictionary
                        continue;
                    }
                    if (code > next_free)
                    {
                        return(mSize = -1);                    // invalid or corrupt input
                    }
                    if (next_free <= code_max)
                    {
                        // new dictionary entries are always 1 byte longer than the previously received one.
                        mLength[next_free] = mLength[prev_code] + 1;
                        if ((next_free == code_max) && (code_size < MAX_BITS))
                        {
                            // start reading a new block, with code size increased by 1
                            R        = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size));
                            code_max = (1 << ++code_size) - 1;
                        }
                        next_free++;
                    }
                    n        += mLength[code];
                    prev_code = code;
                }
                return(mSize = n);
            }