Пример #1
0
        /// <summary> insert node into sorted forest while preserving ordering </summary>
        private static void SortInsert(List <HuffmannTree> forest, HuffmannTree node)
        {
            if (forest.Count == 0)
            {
                forest.Add(node);
                return;
            }

            int i = 0;

            while (NodeCompare(forest[i], node))
            {
                i++;

                if (i == forest.Count)
                {
                    // node is bigger or equal to the whole forest, it is supposed to be last
                    forest.Add(node);
                    return;
                }
            }

            // forest[i] > node, we want to insert node before i-th forest's node
            forest.Insert(i, node);
        }
Пример #2
0
 /// <summary> returns bool, whether node1 <= node2 </summary>
 private static bool NodeCompare(HuffmannTree node1, HuffmannTree node2)
 {
     if (node1.Weight != node2.Weight)
     {
         return(node1.Weight < node2.Weight);
     }
     else
     {
         if (node1.IsLeaf() && node2.IsLeaf())
         {
             return(node1.Symbol <= node2.Symbol);
         }
         else if (node1.IsLeaf() && !node2.IsLeaf())
         {
             // leaves are lighter then inner nodes
             return(true);
         }
         else if (!node1.IsLeaf() && node2.IsLeaf())
         {
             return(false);
         }
         else
         {
             // two inner nodes with the same Weight
             return(true);
         }
     }
 }
Пример #3
0
        static void Main(string[] args)
        {
            // check cmd args
            if (args.Length != 1 || args[0] == "")
            {
                Console.WriteLine("Argument Error");
                return;
            }


            try
            {
                FileStream   fs           = new FileStream(args[0], FileMode.Open);
                HuffmannTree huffmannTree = HuffmannTree.BuildTree(fs);

                FileStream outputFile = new FileStream(args[0] + ".huff", FileMode.Create);

                outputFile.Write(new byte[] { 0x7B, 0x68, 0x75, 0x7C, 0x6D, 0x7D, 0x66, 0x66 }); // write header
                huffmannTree.PrintTree(outputFile, true);
            }

            catch (Exception ex)
            {
                if (ex is IOException || ex is UnauthorizedAccessException)
                {
                    Console.WriteLine("File Error");
                    return;
                }

                throw;
            }
        }
Пример #4
0
        public static void Encode(Stream inputStream, Stream outputStream)
        {
            HuffmannTree huffmannTree = HuffmannTree.BuildTree(inputStream);

            outputStream.Write(new byte[] { 0x7B, 0x68, 0x75, 0x7C, 0x6D, 0x7D, 0x66, 0x66 }, 0, 8); // write header
            huffmannTree.PrintTree(outputStream, true);
            outputStream.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 8); // huffmann tree representation is ended with 8 bytes of zeros

            inputStream.Position = 0;

            EncodeData(inputStream, outputStream, huffmannTree);
        }
Пример #5
0
 void BuildPathsDictionary(HuffmannTree node, List <byte> path)
 {
     if (node.IsLeaf())
     {
         paths.Add((char)node.Symbol, path.ToArray());
     }
     else
     {
         path.Add(0);
         BuildPathsDictionary(node.Left, path);
         path.RemoveAt(path.Count - 1);
         path.Add(1);
         BuildPathsDictionary(node.Right, path);
         path.RemoveAt(path.Count - 1);
     }
 }
Пример #6
0
        /// <summary>Build huffmann tree from byte frequency array</summary>
        public static HuffmannTree BuildTree(UInt64[] freq)
        {
            List <HuffmannTree> forest = new List <HuffmannTree>();

            for (int i = 0; i < 256; i++)
            {
                if (freq[i] > 0)
                {
                    forest.Add(new HuffmannTree {
                        Left = null, Right = null, Symbol = (byte)i, Weight = freq[i]
                    });
                }
            }

            if (forest.Count == 0)
            {
                return(null);
            }

            // initial leaf ordering
            forest = forest.OrderBy(node => node.Weight).ThenBy(node => node.Symbol).ToList();


            while (forest.Count > 1)
            {
                HuffmannTree parent = new HuffmannTree();
                parent.Left   = forest[0];
                parent.Right  = forest[1];
                parent.Weight = parent.Left.Weight + parent.Right.Weight;

                forest.RemoveRange(0, 2);
                SortInsert(forest, parent);
            }

            HuffmannTree huffmannTree = forest[0];

            huffmannTree.paths = new Dictionary <char, byte[]>();
            huffmannTree.BuildPathsDictionary();
            return(huffmannTree);
        }
Пример #7
0
        public static void EncodeData(Stream inputStream, Stream outputStream, HuffmannTree huffmannTree)
        {
            int       b;
            BitWriter writer = new BitWriter(outputStream);

            while ((b = inputStream.ReadByte()) != -1)
            {
                byte[] path = huffmannTree.paths[(char)b];

                /*
                 * foreach (var bit in path)
                 * {
                 *  Console.Write(bit);
                 * }
                 * Console.WriteLine();
                 */

                writer.WriteBits(path);
            }

            writer.Flush();
        }