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); }
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); } }
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++; } } } }
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; } } } }