public void EmptyPrefixTableTest() { PrefixTable pt = new PrefixTable(); int length; Assert.AreEqual(-1, pt.Find(new byte[0], 0, out length)); Assert.AreEqual(0, length); Assert.AreEqual(-1, pt.Find(new byte[1] { 0 }, 0, out length)); Assert.AreEqual(0, length); Assert.AreEqual(-1, pt.Find(new byte[1] { 1 }, 0, out length)); Assert.AreEqual(0, length); }
public void OneBytePrefixTableTest() { PrefixTable pt = new PrefixTable(); int length; for (int n = 0; n < 16; ++n) { pt.Add(n, -1, (byte)n); } for (int n = 0; n < 16; ++n) { Assert.AreEqual(n, pt.Find(new byte[1] { (byte)n }, 0, out length), "checking code"); Assert.AreEqual(1, length, "checking length"); } Assert.AreEqual(-1, pt.Find(new byte[1] { 17 }, 0, out length), "checking code not found"); Assert.AreEqual(0, length, "checking length not found"); }
public void OffsetPrefixTableTest() { PrefixTable pt = new PrefixTable(); int length; pt.Add(0, -1, 0); pt.Add(1, 0, 1); pt.Add(2, 0, 2); pt.Add(3, 0, 3); Assert.AreEqual(1, pt.Find(new byte[7] { 0, 1, 0, 2, 0, 3, 99 }, 0, out length)); Assert.AreEqual(2, length); Assert.AreEqual(2, pt.Find(new byte[7] { 0, 1, 0, 2, 0, 3, 99 }, 2, out length)); Assert.AreEqual(2, length); Assert.AreEqual(3, pt.Find(new byte[7] { 0, 1, 0, 2, 0, 3, 99 }, 4, out length)); Assert.AreEqual(2, length); }
public void DivergentPrefixTableTest() { PrefixTable pt = new PrefixTable(); int length; pt.Add(0, -1, 0); pt.Add(1, 0, 1); pt.Add(2, 0, 2); pt.Add(3, 0, 3); Assert.AreEqual(0, pt.Find(new byte[2] { 0, 99 }, 0, out length)); Assert.AreEqual(1, length); Assert.AreEqual(1, pt.Find(new byte[3] { 0, 1, 99 }, 0, out length)); Assert.AreEqual(2, length); Assert.AreEqual(2, pt.Find(new byte[3] { 0, 2, 99 }, 0, out length)); Assert.AreEqual(2, length); Assert.AreEqual(3, pt.Find(new byte[3] { 0, 3, 99 }, 0, out length)); Assert.AreEqual(2, length); }
private void WriteImageData(Image image) { // Figure out which color table is in use and deduce the code size ColorTable colorTable = image.LocalColorTable ?? GlobalColorTable; int colorTableBitSize = colorTable.BitSize(); int codeSize = (colorTableBitSize == 1 ? 2 : colorTableBitSize); if (Debug) { Console.Error.WriteLine("Writing code size {0} bits", codeSize); } WriteByte(codeSize); // Initial code length is one more than code size, to accomodate the // Clear and End codes. BitWriter writer = new BitWriter() { Output = Output, CodeLength = 1 + codeSize, Debug = this.Debug, }; // Initialize the prefix table with matches for all single-unit codes PrefixTable prefixes = new PrefixTable(); for (int n = 0; n < (1 << codeSize); ++n) { prefixes.Add(n, -1, (byte)n); } int minCode = (1 << codeSize) + 2; int nextCode = minCode; // Start with a Clear. (Pointless - the decoder knows perfectly well what // the initial state is.) if (Debug) { Console.Error.WriteLine("Bit-writing clear marker {0}", 1 << codeSize); } writer.WriteBits(1 << codeSize); int pos = 0; if (Debug) { Console.Error.WriteLine("Bit-writing {0} pixels of image data", image.ImageData.Length); } while (pos < image.ImageData.Length) { // Find the longest known prefix that matches this point in the image data int bestLength; int bestCode = prefixes.Find(image.ImageData, pos, out bestLength); // Output the best code we found writer.WriteBits(bestCode); // Add a new dictionary entry if (nextCode < 4096 && pos + bestLength < image.ImageData.Length) { if (Debug) { Console.Error.WriteLine("Define code {0:X} as code {1:X} + byte {2:X2}", nextCode, bestCode, image.ImageData[pos + bestLength]); } prefixes.Add(nextCode, bestCode, image.ImageData[pos + bestLength]); // Update the output bit size if(nextCode >= (1 << writer.CodeLength)) { ++writer.CodeLength; } ++nextCode; } pos += bestLength; } // Finish with an End. (Also pointless - the decoder knows what size the image data should be.) if (Debug) { Console.Error.WriteLine("Bit-writing end marker {0}", (1 << codeSize) + 1); } writer.WriteBits((1 << codeSize) + 1); if (Debug) { Console.Error.WriteLine("Flushing bits"); } writer.FlushBits(); if (Debug) { Console.Error.WriteLine("Flushing bytes"); } writer.FlushBytes(); // A zero-sized sub-block terminates. if (Debug) { Console.Error.WriteLine("Writing image terminator"); } WriteByte(0); }
private void WriteImageData(Image image) { // Figure out which color table is in use and deduce the code size ColorTable colorTable = image.LocalColorTable ?? GlobalColorTable; int colorTableBitSize = colorTable.BitSize(); int codeSize = (colorTableBitSize == 1 ? 2 : colorTableBitSize); if (Debug) { Console.Error.WriteLine("Writing code size {0} bits", codeSize); } WriteByte(codeSize); // Initial code length is one more than code size, to accomodate the // Clear and End codes. BitWriter writer = new BitWriter() { Output = Output, CodeLength = 1 + codeSize, Debug = this.Debug, }; // Initialize the prefix table with matches for all single-unit codes PrefixTable prefixes = new PrefixTable(); for (int n = 0; n < (1 << codeSize); ++n) { prefixes.Add(n, -1, (byte)n); } int minCode = (1 << codeSize) + 2; int nextCode = minCode; // Start with a Clear. (Pointless - the decoder knows perfectly well what // the initial state is.) if (Debug) { Console.Error.WriteLine("Bit-writing clear marker {0}", 1 << codeSize); } writer.WriteBits(1 << codeSize); int pos = 0; if (Debug) { Console.Error.WriteLine("Bit-writing {0} pixels of image data", image.ImageData.Length); } while (pos < image.ImageData.Length) { // Find the longest known prefix that matches this point in the image data int bestLength; int bestCode = prefixes.Find(image.ImageData, pos, out bestLength); // Output the best code we found writer.WriteBits(bestCode); // Add a new dictionary entry if (nextCode < 4096 && pos + bestLength < image.ImageData.Length) { if (Debug) { Console.Error.WriteLine("Define code {0:X} as code {1:X} + byte {2:X2}", nextCode, bestCode, image.ImageData[pos + bestLength]); } prefixes.Add(nextCode, bestCode, image.ImageData[pos + bestLength]); // Update the output bit size if (nextCode >= (1 << writer.CodeLength)) { ++writer.CodeLength; } ++nextCode; } pos += bestLength; } // Finish with an End. (Also pointless - the decoder knows what size the image data should be.) if (Debug) { Console.Error.WriteLine("Bit-writing end marker {0}", (1 << codeSize) + 1); } writer.WriteBits((1 << codeSize) + 1); if (Debug) { Console.Error.WriteLine("Flushing bits"); } writer.FlushBits(); if (Debug) { Console.Error.WriteLine("Flushing bytes"); } writer.FlushBytes(); // A zero-sized sub-block terminates. if (Debug) { Console.Error.WriteLine("Writing image terminator"); } WriteByte(0); }