public static void Decompress(FileInfo inputFile) { Stopwatch stopwacth = new Stopwatch(); stopwacth.Start(); Console.WriteLine("Starting decompression..."); DecompressionInfo di = new DecompressionInfo(); HuffmanNode root = null; HuffmanNode iteratedNode = null; byte[] fileBytes = null; int bytesOfDataToSkip = 0; using (FileStream stream = new FileStream(inputFile.FullName, FileMode.Open)) { using (BinaryReader reader = new BinaryReader(stream)) { di.SizeInBytes = reader.ReadInt32(); di.DecompressionInfoString = Encoding.UTF8.GetString(reader.ReadBytes(di.SizeInBytes)); di.OrderLevel = reader.ReadInt16(); fileBytes = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); reader.Close(); } } List <bool> decodedTextBits = new List <bool>(); BitArray bitmap = new BitArray(fileBytes); BitArray encodedTextBits = new BitArray(bitmap.Length - di.OrderLevel * 8); BitArray firstSymbols = new BitArray(di.OrderLevel * 8); // copy first symbols to know starting context and what's left to encoded text array int index = 0; for (int p = 0; p < di.OrderLevel * 8; p++) { firstSymbols[index] = bitmap[p]; index++; } index = 0; byte[] firstSymbolBytes = new byte[firstSymbols.Length / 8]; firstSymbols.CopyTo(firstSymbolBytes, 0); string firstSymbolsString = Encoding.ASCII.GetString(firstSymbolBytes); for (int h = di.OrderLevel * 8; h < bitmap.Length; h++) { encodedTextBits[index] = bitmap[h]; index++; } Dictionary <string, HuffmanNode> decompressionTrees = ConstructDecompressionTree(di.DecompressionInfoString); int i = 0; string currentContext = firstSymbolsString; string decodedText = currentContext; HuffmanNode treeByContext = decompressionTrees[currentContext]; iteratedNode = treeByContext; for (int l = 0; l < encodedTextBits.Length; l++) { if (iteratedNode.Left == null && iteratedNode.Right == null) { decodedText += iteratedNode.Character; currentContext = decodedText.Substring(decodedText.Length - di.OrderLevel, di.OrderLevel); // decoded one symbol, return tree node to root iteratedNode = decompressionTrees[currentContext]; continue; } else { if (encodedTextBits[l] == true) { iteratedNode = iteratedNode.Right; } else { iteratedNode = iteratedNode.Left; } } l++; } /*BitArray tempTextBitsArray = new BitArray(decodedTextBits.ToArray()); * byte[] bytesToWrite = new byte[tempTextBitsArray.Length / 8 + (tempTextBitsArray.Length % 8 == 0 ? 0 : 1)]; * tempTextBitsArray.CopyTo(bytesToWrite, 0); * decodedText = Encoding.ASCII.GetString(bytesToWrite);*/ string outputFile = $"dec_{inputFile.Name.Substring(0, inputFile.Name.Length - 5)}"; outputFile = Path.Combine(inputFile.DirectoryName, outputFile); File.WriteAllText(outputFile, decodedText); stopwacth.Stop(); Console.WriteLine($"Decompression finished in: {stopwacth.ElapsedMilliseconds}"); Console.WriteLine("Ending decompression...\n"); }
public static void Compress(Dictionary <string, Dictionary <char, string> > huffmanCodes, Dictionary <string, Dictionary <char, int> > contextFrequencies, int orderLevel, string originalText, string outputFile) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.WriteLine("\nStarting compression..."); DecompressionInfo decInfo = ConstructDecompressionInfoObject(contextFrequencies, (short)orderLevel); if (File.Exists(outputFile)) { File.Delete(outputFile); } var encodedText = ""; var firstSymbols = new BitArray(System.Text.ASCIIEncoding.ASCII.GetBytes(originalText.Substring(0, orderLevel))); foreach (bool bit in firstSymbols) { encodedText += (bit == true) ? "1" : "0"; } int contextPosition = 0; for (int i = orderLevel; i < originalText.Length; i++) { var currentSymbol = originalText[i]; var currentContext = originalText.Substring(contextPosition, orderLevel); encodedText += huffmanCodes[currentContext][currentSymbol]; contextPosition++; } BitArray textBits = new BitArray(encodedText.Length); for (int i = 0; i < encodedText.Length; i++) { textBits[i] = (encodedText[i].Equals('1')) ? true : false; } byte[] bytesToWrite = new byte[textBits.Length / 8 + (textBits.Length % 8 == 0 ? 0 : 1)]; textBits.CopyTo(bytesToWrite, 0); using (FileStream stream = new FileStream(outputFile, FileMode.OpenOrCreate)) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(decInfo.SizeInBytes); writer.Write(decInfo.DecompressionInfoString.ToCharArray(), 0, decInfo.DecompressionInfoString.Length); writer.Write(decInfo.OrderLevel); writer.Write(bytesToWrite); writer.Close(); } } stopwatch.Stop(); Console.WriteLine("Compression finished in: {0}", stopwatch.ElapsedMilliseconds); Console.WriteLine("Ending compression..."); }