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("");
                    }
                }
            }
        }
Example #4
0
        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);
            }
        }