public void GlobalSetup()
        {
            var sourceFile = Common.GetSourceImagePath(imageIndex);

            image          = ImageFrame.FromFile(sourceFile).AsGrayScale(Colors);
            LZEncoded      = image.AsLZEncodedUsingHashTable(12289);
            HuffmanEncoded = image.AsHuffmanEncoded();
            GZipEncoded    = image.AsGZipEncoded();
        }
        public void GlobalSetup()
        {
            var sourceFile = Common.GetSourceImagePath(imageIndex);

            image = ImageFrame.FromFile(sourceFile).AsCroppedImage(new CropSetup {
                LeftPx = Crop * 16, RightPx = Crop * 16, TopPx = Crop * 16, BottomPx = Crop * 16
            }).AsGrayScale();
            LZEncoded      = image.AsLZEncodedUsingHashTable(12289);
            HuffmanEncoded = image.AsHuffmanEncoded();
            GZipEncoded    = image.AsGZipEncoded();
        }
示例#3
0
            public void AsHuffmanEncodedAndDecodedWithSave(int imageIndex)
            {
                var i         = imageIndex;
                var cropSetup = new CropSetup {
                    LeftPx = 27 * 16, RightPx = 29 * 16, TopPx = 1 * 16, BottomPx = 6 * 16
                };
                var sourceFile      = Common.GetSourceImagePath(i);
                var image           = ImageFrame.FromFile(sourceFile).AsCroppedImage(cropSetup).AsGrayScale();
                var encodedFilename = Common.GetSaveImagePath(i, "gray-huffman-encoded");

                image.AsHuffmanEncoded().Save(encodedFilename);
                var encoded         = new HuffmanImageFrame().Open(encodedFilename);
                var decodedFilename = Common.GetSaveImagePath(i, "gray-huffman-decoded.bmp");

                encoded.AsImageGrayScaleFrame().Save(decodedFilename);
                var decoded = ImageFrame.FromFile(decodedFilename);

                Assert.True(image.Image.Compare(decoded.Image));
            }
示例#4
0
        /// <summary>
        /// Decodes Huffman encoded image back to gray scale image
        /// </summary>
        /// <param name="encodedImage"></param>
        /// <returns></returns>
        public static ImageFrameGrayScale AsImageGrayScaleFrame(this HuffmanImageFrame encodedImage)
        {
            //---------- generate tree from color codes -----------------

            var maxNodes = 0;

            for (int i = 0; i <= encodedImage.MaxCodeBitsLength + 1; i++)
            {
                maxNodes = 1 << i;
            }

            //simple help table for tree generation
            var nodeTree = new HuffmanTreeNode <int> [maxNodes - 1];
            var rootNode = new HuffmanTreeNode <int>();

            nodeTree[0] = rootNode;

            for (int i = 0; i < encodedImage.ColorCodeCount; i++)
            {
                var colorCodeItem = encodedImage.GetColorCodeItemFromHeader(i);
                var huffmanNode   = new HuffmanTreeNode <int>(colorCodeItem.Symbol, colorCodeItem.Code, colorCodeItem.CodeBitsCount);
                huffmanNode.PopulateBitTable();

                //start always from root bit and go to leaf
                var parentPos = 0;
                var parent    = nodeTree[0];

                for (int j = huffmanNode.CodeBitTable.Length - 1; j >= 0; j--)
                {
                    var childPos     = 0;
                    var isRightChild = huffmanNode.CodeBitTable[j];

                    if (isRightChild)
                    {
                        childPos = ((parentPos + 1) * 2 + 1) - 1;
                    }
                    else
                    {
                        childPos = ((parentPos + 1) * 2) - 1;
                    }

                    if (j == 0)
                    {
                        //leaf node
                        nodeTree[childPos] = huffmanNode;
                    }
                    else if (nodeTree[childPos] == null)
                    {
                        //create internal node
                        nodeTree[childPos] = new HuffmanTreeNode <int>();
                    }

                    nodeTree[childPos].SetParent(parent, isRightChild);
                    parent.SetChild(nodeTree[childPos]);
                    parent    = nodeTree[childPos];
                    parentPos = childPos;
                }
            }

            var imageHeaderSize = encodedImage.OriginalImageHeaderLength + ImageFrame.HEADER_256_COLOR_TABLE_SIZE;
            var imageData       = new byte[imageHeaderSize + encodedImage.OriginalImageDataLength];

            //-------------   set header ------------------------

            //copy original image non-encoded header to image
            encodedImage.Data.CopyBytesTo(
                encodedImage.FixedHeaderLength + encodedImage.ColorCodeHeaderLength,
                imageData,
                0,
                encodedImage.OriginalImageHeaderLength);

            //--------------- decode image -----------------------

            var node      = rootNode;
            var destIndex = imageHeaderSize;

            //read encoded stream bit by bit and travel tree using bit value
            //until leaf node is reached. read original color code from leaf node
            for (int i = 0; i < encodedImage.CompressedBits; i++)
            {
                //read right or left child based bit in stream
                node = encodedImage.GetBit(i) ? node.RightChild : node.LeftChild;
                if (node.Leaf)
                {
                    //set decoded byte to image
                    imageData[destIndex++] = (byte)node.Symbol;
                    //move back to root node
                    node = rootNode;
                }
            }

            var ret = new ImageFrameGrayScale(imageData);

            //generate color table
            ret.SetColorTable();

            return(ret);
        }
        /// <summary>
        /// Encodes gray scale image using huffman coding
        /// </summary>
        /// <param name="image">Image to encode</param>
        /// <returns>Huffman image frame</returns>
        public static HuffmanImageFrame AsHuffmanEncoded(this ImageFrameGrayScale image)
        {
            if (image.BitsPerPixel != 8)
            {
                throw new NotSupportedException("Only 8 bits per pixel images are supported");
            }

            var colors    = (1 << image.BitsPerPixel);
            var minHeap   = new MinHeap <HuffmanTreeNode <int> >(colors);
            var leafTable = new HuffmanTreeNode <int> [colors];

            var leafNodeCount = 0;

            //iterate through all bytes in image data and calculates color frequency
            for (int i = image.HeaderBytesLength; i < image.Image.Length; i++)
            {
                var colorCode = (int)image.Image[i];                //between 0 - 255
                if (leafTable[colorCode] == null)
                {
                    leafTable[colorCode] = new HuffmanTreeNode <int>(colorCode);
                    leafNodeCount++;
                }
                leafTable[colorCode].IncreaseFrequency();
            }

            var leafTableShrink = new HuffmanTreeNode <int> [leafNodeCount];

            var shrinkIndex = 0;

            //add leaf nodes to minheap and shrink table
            for (int i = 0; i < leafTable.Length; i++)
            {
                var leafNode = leafTable[i];
                if (leafNode != null)
                {
                    leafTableShrink[shrinkIndex++] = leafNode;
                    minHeap.Insert(leafNode.Frequency, leafNode);
                }
            }

            var internalNodesCount = 0;

            //create huffman tree from leaf nodes and internal nodes
            while (minHeap.HeapSize > 1)
            {
                var internalNode = HuffmanTreeNode <int> .InternalNodeCreate(minHeap.DelMin(), minHeap.DelMin());

                minHeap.Insert(internalNode.Frequency, internalNode);
                internalNodesCount++;
            }

            //traverse huffman tree from leaf to root and calculate code for node symbol
            for (int i = 0; i < leafTableShrink.Length; i++)
            {
                var node     = leafTableShrink[i];
                var leafNode = node;
                leafNode.ResetCode();
                while (node != null)
                {
                    leafNode.SetCodeNextBit(node.IsRightChild ? 1 : 0);
                    node.Parent?.SetChild(node);
                    node = node.Parent;
                }
            }

            var compressedBits   = 0;
            var maxCodeBits      = 0;
            var headerColorItems = new HuffmanImageFrame.HeaderColorItem[leafTableShrink.Length];

            for (int i = 0; i < leafTableShrink.Length; i++)
            {
                //creates simple array of code bits which is easy iterate in encoding
                leafTableShrink[i].PopulateBitTable();
                compressedBits     += leafTableShrink[i].TotalBits;
                maxCodeBits         = leafTableShrink[i].CodeBits > maxCodeBits ? leafTableShrink[i].CodeBits : maxCodeBits;
                headerColorItems[i] = new HuffmanImageFrame.HeaderColorItem(
                    leafTableShrink[i].Symbol,
                    leafTableShrink[i].CodeBits,
                    leafTableShrink[i].Code);
            }

            //------------------ Build return starts --------------------------------------

            var originalImageHeader = new byte[ImageFrame.HEADER_BYTES];

            image.Image.CopyBytesTo(0, originalImageHeader);

            var originalImageDataLength = image.Image.Length - image.HeaderBytesLength;

            var ret = new HuffmanImageFrame(compressedBits, headerColorItems, maxCodeBits, originalImageDataLength, originalImageHeader);

            var retBitIndex  = 7;                   //read bits from left to right
            var retByteIndex = ret.ImageDataOffSet; //start begin of image section

            //encode image bytes per byte using huffman code
            for (int i = image.HeaderBytesLength; i < image.Image.Length; i++)
            {
                //get color encoding info node from leafs table by index
                var colorCode = (int)image.Image[i];
                var leafNode  = leafTable[colorCode];

                //read bits from bits table from left to right
                for (int j = leafNode.CodeBitTable.Length - 1; j >= 0; j--)
                {
                    //write bits to byte from left to right
                    if (retBitIndex == -1)
                    {
                        //switch to next byte and start writing from left of byte (most significant bit)
                        retBitIndex = 7;
                        retByteIndex++;
                    }

                    //dest byte bits are set initally to 0 only change byte value when bit is set to 1
                    if (leafNode.CodeBitTable[j])
                    {
                        ret.Data[retByteIndex] = ret.Data[retByteIndex].SetBitToByte(retBitIndex);
                    }

                    retBitIndex--;
                }
            }

            return(ret);
        }