public void LzwEncodingIsReversible(LzwGifToolsTestCase testCase) // and decoding { LzwCompressor compressor = new LzwCompressor(testCase.LzwMinimumCodeSize); LzwDecompressor decompressor = new LzwDecompressor(testCase.LzwMinimumCodeSize); List <int> lzwCompressedStream = compressor.Compress(testCase.CodeStream); List <int> lzwDecompressedStream = decompressor.Decompress(lzwCompressedStream); CollectionAssert.AreEqual(testCase.CodeStream, lzwDecompressedStream); }
public void AllMethodsWork(LzwGifToolsTestCase testCase) { LzwCompressor compressor = new LzwCompressor(testCase.LzwMinimumCodeSize); StreamPacker packer = new StreamPacker(testCase.LzwMinimumCodeSize); StreamUnpacker unpacker = new StreamUnpacker(testCase.LzwMinimumCodeSize); LzwDecompressor decompressor = new LzwDecompressor(testCase.LzwMinimumCodeSize); List <int> lzwEncodedCodeStream = compressor.Compress(testCase.CodeStream); List <byte> packedBytes = packer.Pack(lzwEncodedCodeStream); List <int> lzwEncodedCodeStream2 = unpacker.Unpack(packedBytes); List <int> codeStream = decompressor.Decompress(lzwEncodedCodeStream2); CollectionAssert.AreEqual(testCase.CodeStream, codeStream); }
/// <summary> /// Reads one lead payload at a time from the XLI compressed stream. /// </summary> /// <returns>Uncompressed lead data.</returns> public int[] ReadLeadPayload() { var chunkHeader = new byte[8]; if (chunkHeader.Length != this.stream.Read(chunkHeader, 0, chunkHeader.Length)) { throw new InvalidOperationException("Not enough data to read header from the stream"); } // Each chunk begins with an 8 byte header consisting of: // - 32-bit integer describing the length of the chunk // - 16-bit integer (unknown payload, seemingly always 1) // - 16-bit integer describing the first delta code // // After this header exists LZW-compressed delta codes, using 10-bit code words: // 0 2 4 6 8 ... // +--------+--------+--------+--------+--------+--------+--------+--------+--------+ // | Size | Unk. | Delta | LZW compressed deltas (10-bit codes) | // +--------+--------+--------+--------+ | // | ... [Size bytes] | // +--------+--------+--------+--------+--------+--------+--------+--------+--------+ var size = BitConverter.ToInt32(chunkHeader, 0); // CAW: var unknown = BitConverter.ToInt16(chunkHeader, 4); var start = BitConverter.ToInt16(chunkHeader, 6); var chunk = new byte[size]; if (chunk.Length != this.stream.Read(chunk, 0, size)) { throw new InvalidOperationException("Not enough data in the compressed chunk"); } // LZW 10-bit codes using (var decompressor = new LzwDecompressor(chunk, 10)) { var output = decompressor.Decompress() .ToArray(); // Once the data is decompressed it is packed [HIWORDS...LOWORDS] // and needs to be reconstituted. var deltas = Unpack(output); return(DecodeDeltas(deltas, start)); } }
public void LzwDecodingAndVariableWidthDecompressionSuccessful() { byte[] imageData = vcvj.DataStream.GetTableBasedImages().First().ImageData.Bytes; int lzwSize = vcvj.DataStream.GetTableBasedImages().First().ImageData.LzwMinimumCodeSize; LzwDecompressor decompressor = new LzwDecompressor((byte)lzwSize); LzwTools.Decoder decoder = new LzwTools.Decoder((byte)lzwSize); List <int> decompressedStream = decompressor.Decompress(imageData.Select((b) => (int)b).ToList <int>()); List <int> decodedStream = decoder.Decode(decompressedStream.Select(x => (byte)x).ToList <byte>()); // assuming no error is thrown, we're... probably good. yeah this is kind of // an awkward test until we can derive a lzw code table from the global // color index and re-encode everything to match the original bytestream Assert.IsTrue(decodedStream.Count > imageData.Length); }