예제 #1
0
        public void ReadOneLSB()
        {
            var buff = new byte[1] {
                0x01
            };
            var          mem    = new MemoryStream(buff);
            BitReaderLSB reader = new BitReaderLSB(mem);
            var          val    = reader.GetBits(1);

            Assert.AreEqual(1, val);
        }
예제 #2
0
        public void ReadWriteLSB()
        {
            byte[] buff = new byte[0x1ff * 9 / 8 + 2];
            var    mem  = new MemoryStream(buff);

            BitWriterLSB writer = new BitWriterLSB(mem);

            for (int i = 0; i <= 0x1ff; i++)
            {
                writer.WriteBits(i, 9);
            }
            writer.Flush();

            mem.Seek(0, SeekOrigin.Begin);
            BitReaderLSB reader = new BitReaderLSB(mem);

            for (int i = 0; i <= 0x1ff; i++)
            {
                var val = reader.GetBits(9);
                Assert.AreEqual(i, val);
            }
        }
예제 #3
0
        protected override void GoUnpack()
        {
            var reader = new BitReaderLSB(_stream);

            ushort numbits;
            ushort curtoken, endtoken;

            numbits  = 9;
            curtoken = 0x102;
            endtoken = 0x1ff;

            ushort token; // The last received value

            ushort[] tokenlist       = new ushort[4096];
            ushort[] tokenlengthlist = new ushort[4096];

            while (!IsFinished())
            {
                token = (ushort)reader.GetBits((byte)numbits);

                if (token == 0x101)
                {
                    return; // terminator
                }

                if (token == 0x100)
                { // reset command
                    numbits  = 9;
                    curtoken = 0x0102;
                    endtoken = 0x1FF;
                }
                else
                {
                    ushort tokenlastlength;
                    if (token > 0xff)
                    {
                        if (token >= curtoken)
                        {
                            throw new IOException(String.Format("unpackLZW: Bad token {0:X4}", token));
                        }

                        tokenlastlength = (ushort)(tokenlengthlist[token] + 1);
                        if (_dwWrote + tokenlastlength > _szUnpacked)
                        {
                            // For me this seems a normal situation, It's necessary to handle it
                            Console.WriteLine("unpackLZW: Trying to write beyond the end of array(len={0}, destctr={1}, tok_len={2})", _szUnpacked, _dwWrote, tokenlastlength);
                            for (int i = 0; _dwWrote < _szUnpacked; i++)
                            {
                                PutByte(_dest[tokenlist[token] + i]);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < tokenlastlength; i++)
                            {
                                PutByte(_dest[tokenlist[token] + i]);
                            }
                        }
                    }
                    else
                    {
                        tokenlastlength = 1;
                        if (_dwWrote >= _szUnpacked)
                        {
                            Console.WriteLine("unpackLZW: Try to write single byte beyond end of array");
                        }
                        else
                        {
                            PutByte((byte)token);
                        }
                    }
                    if (curtoken > endtoken && numbits < 12)
                    {
                        numbits++;
                        endtoken = (ushort)((endtoken << 1) + 1);
                    }
                    if (curtoken <= endtoken)
                    {
                        tokenlist[curtoken]       = (ushort)(_dwWrote - tokenlastlength);
                        tokenlengthlist[curtoken] = tokenlastlength;
                        curtoken++;
                    }
                }
            }
        }
예제 #4
0
        protected override void GoUnpack()
        {
            reader = new BitReaderLSB(_stream);

            byte[] dictionary     = new byte[4096];
            var    mode           = reader.GetByte();
            var    dictionaryType = reader.GetByte();
            int    dictionaryPos  = 0;
            ushort tokenOffset;

            if (mode != DCL_BINARY_MODE && mode != DCL_ASCII_MODE)
            {
                throw new Exception("Wrong DCL format");
            }

            ushort dictionarySize;

            switch (dictionaryType)
            {
            case 4:
                dictionarySize = 1024;
                break;

            case 5:
                dictionarySize = 2048;
                break;

            case 6:
                dictionarySize = 4096;
                break;

            default:
                throw new Exception("Wrong DCL format");
            }

            int dictionaryMask = dictionarySize - 1;

            while (_dwWrote < _szUnpacked)
            {
                if (reader.GetBits(1) == 1)
                {
                    var value = huffman_lookup(length_tree);

                    ushort tokenLength;
                    if (value < 8)
                    {
                        tokenLength = (ushort)(value + 2);
                    }
                    else
                    {
                        tokenLength = (ushort)(8 + (1 << (value - 7)) + reader.GetBits(value - 7));
                    }

                    if (tokenLength == 519)
                    {
                        break; // End of stream signal
                    }
                    value = huffman_lookup(distance_tree);

                    if (tokenLength == 2)
                    {
                        tokenOffset = (ushort)((value << 2) | (ushort)reader.GetBits(2));
                    }
                    else
                    {
                        tokenOffset = (ushort)((value << dictionaryType) | (ushort)reader.GetBits(dictionaryType));
                    }
                    tokenOffset++;

                    if (tokenLength + _dwWrote > _szUnpacked || _dwWrote < tokenOffset)
                    {
                        throw new Exception("Wrong DCL format");
                    }

                    int dictionaryBaseIndex = (dictionaryPos - tokenOffset) & dictionaryMask;
                    int dictionaryIndex     = dictionaryBaseIndex;
                    int dictionaryNextIndex = dictionaryPos;

                    while (tokenLength > 0)
                    {
                        // Write byte from dictionary
                        PutByte(dictionary[dictionaryIndex]);

                        dictionary[dictionaryNextIndex] = dictionary[dictionaryIndex];

                        dictionaryNextIndex = (dictionaryNextIndex + 1) & dictionaryMask;
                        dictionaryIndex     = (dictionaryIndex + 1) & dictionaryMask;

                        if (dictionaryIndex == dictionaryPos)
                        {
                            dictionaryIndex = dictionaryBaseIndex;
                        }
                        if (dictionaryNextIndex == dictionarySize)
                        {
                            dictionaryNextIndex = 0;
                        }

                        tokenLength--;
                    }
                    dictionaryPos = dictionaryNextIndex;
                }
                else
                {
                    byte value;
                    if (mode == DCL_ASCII_MODE)
                    {
                        value = (byte)huffman_lookup(ascii_tree);
                    }
                    else
                    {
                        value = reader.GetByte();
                    }
                    PutByte(value);

                    dictionary[dictionaryPos] = value;
                    dictionaryPos++;
                    if (dictionaryPos >= dictionarySize)
                    {
                        dictionaryPos = 0;
                    }
                }
            }
        }