You are on page 1of 8

Huffman code

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Huffman
{
    public class HTreeNode
    {
        public string Data;
        public int Freq;
        public HTreeNode Left;
        public HTreeNode Right;

        public HTreeNode(Char C, int Freq)


        {
            this.Data = ""+C;
            this.Freq = Freq;
            this.Left = null;
            this.Right = null;
        }

        public HTreeNode(HTreeNode L, HTreeNode R)


        {
            this.Data = L.Data + R.Data;
            this.Freq = L.Freq + R.Freq;
            this.Left = L;
            this.Right = R;
        }
    }

    class Program
    {

        //--------------------------------------------------- WriteInt
        static void WriteInt(FileStream F, int N)
        {
            byte B1 = (byte)((N & 0xFF000000) >> 24);
            F.WriteByte(B1);

            byte B2 = (byte)((N & 0x00FF0000) >> 16);


            F.WriteByte(B2);
            
            byte B3 = (byte)((N & 0x0000FF00) >> 8);
            F.WriteByte(B3);
            
            byte B4 = (byte)((N & 0x000000FF) >> 0);
            F.WriteByte(B4);
        }

        //-------------------====---------------------------- ReadInt
        static int ReadInt(FileStream F)
        {
            byte B1 = (byte)F.ReadByte();
            byte B2 = (byte)F.ReadByte();
            byte B3 = (byte)F.ReadByte();
            byte B4 = (byte)F.ReadByte();

            return B1 << 24 | B2 << 16 | B3 << 8 | B4 << 0;


        }

        //--------------------------------------------------- Main
        static void Main(string[] args)
        {
            Compress("Test.txt", "CompressedTest.txt");
            Decompress("CompressedTest.txt", "DecompressedTest.txt");
        }

        //---------------------------------------------------- Decompress
        static void Decompress(string InputFile, string OutputFile)
        {
            int[] Freq = new int[256];

            FileStream Fin = new FileStream(InputFile, FileMode.Open);

            int CharsToDecode_count = ReadInt(Fin);


            int CharsUsed = Fin.ReadByte()+1;

            for (int i = 0; i < CharsUsed; i++)


            {
                byte B = (byte) Fin.ReadByte();
                Freq[B] = ReadInt(Fin);
            }

            HTreeNode H = MakeHuffmanTree(Freq);

            FileStream Fout = new FileStream(OutputFile, FileMode.Create);

            byte BitBuffer = 0;   //0000 0000


            int BitCount = 0;

            for (int i = 0; i < CharsToDecode_count; i++)


            {
                HTreeNode N = H;

                while (N.Left != null) //ie: N is not a leaf node


                {
                    if (BitCount == 0)
                    {
                        BitBuffer = (byte) Fin.ReadByte();
                        BitCount = 8;
                    }

                    int Bit = BitBuffer & 0x80;    // 1000 0000


                    BitBuffer = (byte) (BitBuffer << 1);
                    BitCount--;

                    if (Bit == 0)
                    {
                        N = N.Left;
                    }
                    else
                    {
                        N = N.Right;
                    }
                }

                Fout.WriteByte((byte)(N.Data[0]));
            }

            Fout.Flush();
            Fout.Close();

            Fin.Close();

        }

        //------------------------------------------------ Compress
        static void Compress(string InputFile, string OutputFile)
        {
            int[] Freq = new int[256];

            FileStream Fin = new FileStream(InputFile, FileMode.Open);


            for (int i = 0; i < Fin.Length; i++)
            {
                int B = Fin.ReadByte();
                Freq[B]++;
            }

            HTreeNode H = MakeHuffmanTree(Freq);

            FileStream Fout = new FileStream(OutputFile, FileMode.Create);

            WriteInt(Fout, (int)Fin.Length);

            Fout.WriteByte((byte)(H.Data.Length - 1));

            for (int i = 0; i < Freq.Length; i++)


            {
                if (Freq[i] > 0)
                {
                    Fout.WriteByte((byte)i);
                    WriteInt(Fout, Freq[i]);
                }
            }

            byte BitBuffer = 0;   //0000 0000


            int BitCount = 0;

            Fin.Seek(0, SeekOrigin.Begin);
            for (int i = 0; i < Fin.Length; i++)
            {
                char C = (char) Fin.ReadByte();

                HTreeNode N = H;

                while (N.Left != null)  // ie: N is not a leaf Node


                {
                    int bit=0;
                    if (N.Left.Data.Contains(C))
                    {
                        N=N.Left;
                        bit=0;
                    }
                    else
                    {
                        N=N.Right;
                        bit=1;
                    }
                    BitBuffer = (byte) ((BitBuffer << 1) | bit);

                    BitCount++;

                    if (BitCount == 8)
                    {
                        Fout.WriteByte(BitBuffer);
                        BitBuffer = 0;
                        BitCount = 0;
                    }
                }
            }

            if (BitCount > 0)


            {
                BitBuffer = (byte)(BitBuffer << (8 - BitCount));
                Fout.WriteByte(BitBuffer);
            }

            Fout.Flush();
            Fout.Close();

            Fin.Close();
        }

        //------------------------------------------------- MakeHuffmanTree
        public static HTreeNode MakeHuffmanTree(int[] Freq)
        {
            Heap<HTreeNode> H = new Heap<HTreeNode>(Freq.Length);

            for (int i = 0; i < Freq.Length; i++)


            {
                if (Freq[i] > 0)
                {
                    HTreeNode node = new HTreeNode((char)i, Freq[i]);
                    H.insert(node, -node.Freq);
                }
            }

            while (H.Count() > 1)


            {
                HTreeNode node1 = H.remove();
                HTreeNode node2 = H.remove();
                HTreeNode node = new HTreeNode(node1, node2);

                H.insert(node, -node.Freq);
            }

            return H.remove();
        }
    }
}

Heap.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Huffman
{
    class Heap<T>
    {
        class HeapNode
        {
            public T Data;
            public int Priority;

            public HeapNode(T Data, int Priority)


            {
                this.Data = Data;
                this.Priority = Priority;
            }
        }

        private HeapNode[] HeapArray;


        private int count;

        public Heap(int MaxSize)


        {
            HeapArray = new HeapNode[MaxSize];
            count = 0;
        }

        public void insert(T Data, int Priority)


        {
            HeapArray[count] = new HeapNode(Data, Priority);
            count++;
            //---------------------------------------upHeap

            int i = count - 1;

            while (i > 0)
            {
                int parent = (i - 1) / 2;

                if (HeapArray[parent].Priority >= HeapArray[i].Priority)


                {
                    break;
                }
                else
                {
                    HeapNode Temp = HeapArray[parent];
                    HeapArray[parent] = HeapArray[i];
                    HeapArray[i] = Temp;

                    i = parent;
                }
            }
        }

        public T remove()
        {
            T RemovedData = HeapArray[0].Data;

            HeapArray[0] = HeapArray[count - 1];


            count--;

            //--------------------------------dnHeap
            int i = 0;

            while (2*i+1 <= count-1)


            {
                int child = 2*i+1;

                if (2 * i + 2 <= count - 1)


                {
                    if (HeapArray[2 * i + 2].Priority > HeapArray[2 * i +
1].Priority)
                    {
                        child = 2 * i + 2;
                    }
                }

                if (HeapArray[child].Priority <= HeapArray[i].Priority)


                {
                    break;
                }
                else
                {
                    HeapNode Temp = HeapArray[child];
                    HeapArray[child] = HeapArray[i];
                    HeapArray[i] = Temp;

                    i = child;
                }
            }

            //-------------------------------
            return RemovedData;
        }
        
        public int Count()
        {
            return count;
        }
    }
}

You might also like