/// <summary> /// This reads input file and transfers bytes to Huffman code. /// </summary> /// <param name="nodes">Prepared hash table with codes for every type of byte.</param> /// <param name="fileIn">Input stream.</param> /// <param name="fileOut">Output stream.</param> /// <exception cref="System.OutOfMemoryException">BEWARE OF OUT OF MEMORY EXCEPTION</exception> internal static void EncodeFileBytes(BitArray[] nodes, BinaryReader fileIn, BinaryWriter fileOut) { int maxBufferSize = 100000; //Maximum for Huffman I => 1000000 int bufferPos = 0; BitArray writeBuffer = new BitArray(maxBufferSize * 8); while (fileIn.BaseStream.Position != fileIn.BaseStream.Length) { long diff = fileIn.BaseStream.Length - fileIn.BaseStream.Position; int maxSize = diff < maxBufferSize ? (int)(diff) : maxBufferSize; byte[] bytesBuffer = fileIn.ReadBytes(maxSize); for (int i = 0; i < bytesBuffer.Length; i++) { BitArray keyStream = nodes[bytesBuffer[i]]; BitArray tmp = BitArrayExtender.TryAppend(writeBuffer, bufferPos, keyStream); if (tmp != null) { fileOut.Write(BitArrayExtender.ToByteArray(writeBuffer)); BitArrayExtender.TryAppend(writeBuffer, 0, tmp); bufferPos = tmp.Length; } else { bufferPos += keyStream.Length; } } } writeBuffer.Length = bufferPos; fileOut.Write(BitArrayExtender.ToByteArray(writeBuffer)); }
/// <summary> /// Creates 64bit representation of Huffman Tree Node as: /// list: 0bit = 1 /// 1-55bit = node.sum /// 56-64 = node.code /// inner: 0bit = 0 /// 1-55bit = node.sum /// 56-64 = 0 /// </summary> /// <param name="tree">Current node.</param> /// <param name="fileOut">Output stream.</param> private void PrintNodeBinary(Node tree, BinaryWriter fileOut) { BitArray sumBits = new BitArray(BitConverter.GetBytes(tree.Sum)); BitArray node = new BitArray(64, false); BitArrayExtender.CopyToFromBitArray(1, 0, 55, sumBits, node); //List if (tree.Order == 0) { BitArray codeByte = new BitArray(new[] { tree.Code }); node.Set(0, true); BitArrayExtender.CopyToFromBitArray(56, 0, 8, codeByte, node); } //Inner else { node.Set(0, false); } byte[] nodeBytes = BitArrayExtender.ToByteArray(node); fileOut.Write(nodeBytes); }