Beispiel #1
0
        public void Encode(Stream input, Stream output)
        {
            var rootNode = _treeBuilder.Build(input.ToArray(), _bitDepth, _byteOrder);

            // For a more even distribution of the children over the branches, we'll label the tree nodes
            var labelList = LabelTreeNodes(rootNode);

            // Create huffman bit codes
            var bitCodes = labelList[0].GetHuffCodes().ToDictionary(node => node.Item1, node => node.Item2);

            // Write header + tree
            using (var bw = new BinaryWriter(output))
            {
                // Write header
                var header = new[] { (byte)(0x20 + _bitDepth), (byte)(input.Length & 0xFF), (byte)((input.Length >> 8) & 0xFF), (byte)((input.Length >> 16) & 0xFF) };
                bw.Write(header, 0, 4);
                bw.Write((byte)labelList.Count);

                // Write Huffman tree
                foreach (var node in labelList.Take(1).Concat(labelList.SelectMany(node => node.Children)))
                {
                    if (node.Children != null)
                    {
                        node.Code |= node.Children.Select((child, i) => child.IsLeaf ? (byte)(0x80 >> i) : 0).Sum();
                    }
                    bw.Write((byte)node.Code);
                }

                // Write bits to stream
                using (var bitWriter = new BitWriter(bw.BaseStream, BitOrder.MsbFirst, 4, ByteOrder.LittleEndian))
                {
                    switch (_bitDepth)
                    {
                    case 4:
                        while (input.Position < input.Length)
                        {
                            var value = input.ReadByte();
                            if (_byteOrder == ByteOrder.LittleEndian)
                            {
                                foreach (var bit in bitCodes[value % 16])
                                {
                                    bitWriter.WriteBit(bit - '0');
                                }
                                foreach (var bit in bitCodes[value / 16])
                                {
                                    bitWriter.WriteBit(bit - '0');
                                }
                            }
                            else
                            {
                                foreach (var bit in bitCodes[value / 16])
                                {
                                    bitWriter.WriteBit(bit - '0');
                                }
                                foreach (var bit in bitCodes[value % 16])
                                {
                                    bitWriter.WriteBit(bit - '0');
                                }
                            }
                        }
                        break;

                    case 8:
                        while (input.Position < input.Length)
                        {
                            var value = input.ReadByte();
                            foreach (var bit in bitCodes[value])
                            {
                                bitWriter.WriteBit(bit - '0');
                            }
                        }

                        break;
                    }
                    bitWriter.Flush();
                }
            }
        }
Beispiel #2
0
 private HuffmanTreeNode CreateDisplacementIndexTree(Block block, IHuffmanTreeBuilder treeBuilder)
 {
     return(treeBuilder.Build(block.dispIndexes, 8, NibbleOrder.LowNibbleFirst));
 }
Beispiel #3
0
        private HuffmanTreeNode CreateRawValueTree(Stream input, Match[] matches, IHuffmanTreeBuilder treeBuilder)
        {
            var huffmanInput = RemoveMatchesFromInput(input.ToArray(), matches);

            return(treeBuilder.Build(huffmanInput, 8, NibbleOrder.LowNibbleFirst));
        }
Beispiel #4
0
 private HuffmanTreeNode CreateIndexValueTree(Block block, IHuffmanTreeBuilder treeBuilder)
 {
     return(treeBuilder.Build(block.countIndexes, 8, NibbleOrder.LowNibbleFirst));
 }
        private HuffmanTreeNode CreateRawValueTree(Stream input, Match[] matches)
        {
            var huffmanInput = RemoveMatchesFromInput(input.ToArray(), matches);

            return(_treeBuilder.Build(huffmanInput, 8, ByteOrder.LittleEndian));
        }