Exemple #1
0
 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);
 }
Exemple #2
0
 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");
 }
Exemple #3
0
 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);
 }
Exemple #4
0
 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);
 }
Exemple #5
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);
 }
Exemple #6
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);
        }