示例#1
0
        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");
        }
示例#2
0
        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...");
        }