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); }
public void ExportLzwCompressedCodeStreamToTextFile(LzwGifToolsTestCase testCase) { LzwCompressor compressor = new LzwCompressor(testCase.LzwMinimumCodeSize); List <int> lzwCompressedStream = compressor.Compress(testCase.CodeStream); using (StreamWriter sw = File.CreateText(Config.WorkingDirectory + @"/" + "lzw-compressed-code-stream.txt")) { int index = 0; foreach (int i in lzwCompressedStream) { index++; sw.Write(string.Format("{0} ", i)); if (index % 8 == 0) { sw.WriteLine(""); } } } }
public void Write(string path, Image image) { Color[,] colors = GetColors(image.Bitmap); Color[] table = GetTable(colors); int tableSize = AlignToPowerOfTwo(table.Length); byte power = (byte)((byte)Math.Log2(tableSize) - 1); string stringPower = Convert.ToString(power, 2).PadLeft(3, '0'); List <int> codes = LzwCompressor.Compress(colors, table, tableSize); byte minCodeSize = (byte)(power + 1 < 2 ? 2 : power + 1); List <byte> bytes = LzwBytePacker.PackBytes(codes, minCodeSize); byte fullBlock = 255; int fullBlockQuantity = bytes.Count / fullBlock; byte partialBlockCount = (byte)(bytes.Count % fullBlock); short height = (short)image.Header.Height; short width = (short)image.Header.Width; BinaryWriter writer; try { writer = new BinaryWriter(File.Open(path + ".gif", FileMode.Create)); } catch (Exception e) { throw new InvalidOperationException(e.Message); } WriteHeader(); WriteLogicalScreen(); WriteColorTable(); WriteImageDescriptor(); WriteImageData(); WriteTrailer(); writer.Close(); void WriteHeader() { foreach (var ch in _header) { writer.Write(ch); } } void WriteLogicalScreen() { writer.Write(width); writer.Write(height); byte packedField = Convert.ToByte(GlobalTableBit + stringPower + SortBit + stringPower, 2); writer.Write(packedField); writer.Write(BgColorIndex); writer.Write(PixelAspectRatio); } void WriteColorTable() { for (int i = 0; i < tableSize; i++) { if (i < table.Length) { writer.Write((byte)table[i].R); writer.Write((byte)table[i].G); writer.Write((byte)table[i].B); } else { for (int j = 0; j < ColorBytes; j++) { writer.Write(EmptyColorByte); } } } } void WriteImageDescriptor() { writer.Write(ImageSeparator); writer.Write(ImageLeft); writer.Write(ImageRight); writer.Write(width); writer.Write(height); writer.Write(ImagePackedField); } void WriteImageData() { writer.Write(minCodeSize); for (int i = 0; i < fullBlockQuantity; i++) { writer.Write(fullBlock); for (int j = 0; j < fullBlock; j++) { writer.Write(bytes[i * fullBlock + j]); } } if (partialBlockCount != 0) { writer.Write(partialBlockCount); for (int i = 0; i < partialBlockCount; i++) { writer.Write(bytes[fullBlockQuantity * fullBlock + i]); } } writer.Write(BlockTerminator); } void WriteTrailer() { writer.Write(Trailer); } }