public static HashTable<char, BitStream> MakeEncodingTable(Node node, BitStream progress)
        {
            HashTable<char,BitStream> result = new HashTable<char,BitStream>(char.MaxValue,HashChar);

            //if the current node is not null and it is a leaf, we want to add it to result
            if (node != null && node.Left == null && node.Right == null) {
                //we only store leaf nodes in the result array
                //make a new bit stream
                BitStream stream = new BitStream();
                //append progress to it
                stream.Append(progress);
                //add node.data and the new stream to result
                result.Add(node.Data, stream);
            }

            //else if the node is not null, we are going to want to process it's childern
            else {
                if (node != null && node.Left != null) {
                    //if left subtree is not null
                    //make new bit stream
                    BitStream stream = new BitStream();
                    //append progress
                    stream.Append(progress);
                    //append 0 (because we are going left)
                    stream.Append(false);
                    //recursivley call this function on node.Left with the new stream we just created
                    //store the result of the previous call in a local hashtable
                    HashTable<char, BitStream> local = MakeEncodingTable(node.Left, stream);
                    //loop through the just created hash table(the return of the recursive function)
                    SLinkedList<char> list = local.Keys;
                    for (int i = 0; i < list.Size; i++) {
                        //add each key value pair to this function's result hash table
                        result.Add(list[i], local[list[i]]);
                        //we do this because the results of each recursion bubble back up to the top.
                        //by the time the root returns, all of the leaf nodes will be in the final hash table
                    }//end loop
                }//end if
                if (node != null && node.Right != null) {
                    //repeat above for the right subtree
                    BitStream stream = new BitStream();
                    stream.Append(progress);
                    stream.Append(true);
                    HashTable<char, BitStream> local = MakeEncodingTable(node.Right, stream);
                    SLinkedList<char> list = local.Keys;
                    for (int i = 0; i < list.Size; i++) {
                        result.Add(list[i], local[list[i]]);
                    }
                }//end else
            }
            return result;
        }
Example #2
0
 public void Append(BitStream stream)
 {
     // Cache stream size as a member variable. We do this because
     int streamSize = stream.BitCount;
     //   it's valid to add elements mid loop. If we do this however,
     //   we will face an infinite loop if the stream passed in is the
     //   same stream we are writing to. To avoid this scenario, we need
     //   a 'Stream Size' to be recorded in a variable local to this function
     //   we loop on this integer, not stream.Size.
     //(Inside the loop) Get every bit, and call the existing Append function
     for (int i = 0; i < streamSize; i++) {
         if (stream.BitAt(i)) {
             Append(true);
         }
         else{
             Append(false);
         }
     }
 }
        public static byte[] Compress(string toCompress)
        {
            //then at the end of the function we're going to convert it to an array, and return it.
            Vector<byte> result = new Vector<byte>();

            //make an encoding table out of the huffman tree, out of a frequency table
            Console.WriteLine("Making Huffman frequency table");
            HashTable<char, int> FreqTable = MakeFrequencyTable(toCompress); //copy to memory because we access it multiple times
            Console.WriteLine("Making Huffman tree");
            Node huffmanTree = MakeHuffmanTree(FreqTable);
            Console.WriteLine("Making Huffman encoding table");
            HashTable<char, BitStream> encodingTable = MakeEncodingTable(huffmanTree, new BitStream()); // add to memory because accessed twice
            //convert the size of the frequency table to bytes.
            Console.WriteLine("Converting to bytes");
            byte[] freqToByte = IntToBytes(FreqTable.Size);
            //and all four bytes to the resuld linked list
            Console.WriteLine("Adding bytes bytes");
            result.AddRange(freqToByte);

            //next loop through the frequency table
            SLinkedList<char> list = FreqTable.Keys;
            Console.WriteLine("looping through frequency table");
            for (int i = 0; i < list.Size; i++) {
                //convert current key to two bytes
                byte[] key = CharToBytes(list[i]);
                //add both bytes to the linked list
                result.AddRange(key);

                //convert the current value to foure bytes,
                byte[] value = IntToBytes(FreqTable[list[i]]);
                //add alll four bytes to the linked list
                result.AddRange(value);

            }//end loop

            //make new bitstream (datastream) to hold bits
            BitStream datastream = new BitStream();

            //loop through the string
            Console.WriteLine("Looping through input and adding to datastream");
            for (int i = 0; i < toCompress.Length; i++) {
                //append the bitstream of the encoding table to the newely created bitstream
                datastream.Append(encodingTable[toCompress[i]]);
            }//end loop

            //get the bit streams bit count as an integer
            int streamBitCount = datastream.BitCount;
            //convert this integer to bytes and add it to the result list
            Console.WriteLine("Converting bytes");
            byte[] streambitByte = IntToBytes(streamBitCount);
            result.AddRange(streambitByte);

            Console.WriteLine("Copying Bytes");
            result.AddRange(datastream.Bytes);

            //finally convert the result list to a byte array.
            Console.WriteLine("Convert results list to byte array");
            byte[] byteResult = result.ToArray();

            //return the array
            return byteResult;
        }
Example #4
0
        public static void Main(string[] args)
        {
            BitStream stream = new BitStream ();

            stream.Append (true);
            stream.Append (true);
            stream.Append (true);

            string debug = stream.ToString ();
            Console.WriteLine (debug);
            if (debug != "111") {
                Error ("Expecting 111, got " + debug);
                Console.ReadLine();
                return;
            }

            stream.Append (false);
            stream.Append (true);
            stream.Append (false);
            stream.Append (false);
            stream.Append (true);
            debug = stream.ToString ();
            Console.WriteLine (debug);
            if (debug != "11101001") {
                Error ("Expecting 11101001, got " + debug);
                Console.ReadLine();
                return;
            }

            Console.WriteLine ("0: " + stream.BitAt (0) + " / True");
            if (!stream.BitAt (0)) {
                Error ("Expecting bit 0 to be on, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("1: " + stream.BitAt (1) + " / True");
            if (!stream.BitAt (1)) {
                Error ("Expecting bit 1 to be on, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("2: " + stream.BitAt (2) + " / True");
            if (!stream.BitAt (2)) {
                Error ("Expecting bit 2 to be on, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("3: " + stream.BitAt (3) + " / False");
            if (stream.BitAt (3)) {
                Error ("Expecting bit 3 to be off, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("4: " + stream.BitAt (4) + " / True");
            if (!stream.BitAt (4)) {
                Error ("Expecting bit 4 to be on, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("5: " + stream.BitAt (5) + " / False");
            if (stream.BitAt (5)) {
                Error ("Expecting bit 5 to be off, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("6: " + stream.BitAt (6) + " / False");
            if (stream.BitAt (6)) {
                Error ("Expecting bit 6 to be off, it was not");
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("7: " + stream.BitAt (7) + " / True");
            if (!stream.BitAt (7)) {
                Error ("Expecting bit 7 to be on, it was not");
                Console.ReadLine();
                return;
            }

            stream.Append (stream);
            debug = stream.ToString ();
            Console.WriteLine (debug);
            if (debug != "1110100111101001") {
                Error ("Expecting 1110100111101001, got " + debug);
                Console.ReadLine();
                return;
            }

            stream.Append ("110011");
            debug = stream.ToString ();
            Console.WriteLine (debug);
            if (debug != "1110100111101001110011") {
                Error ("Expecting 1110100111101001110011, got " + debug);
                Console.ReadLine();
                return;
            }

            try {
                stream.Append("1A");
                Error("ERROR! Should not be able to insert A");
                Console.ReadLine();
                return;
            }
            catch (System.Exception e) {
                Console.WriteLine ("Was not able to insert A (As expected)");
            }
            debug = stream.ToString ();
            Console.WriteLine (debug);
            if (debug != "11101001111010011100111") {
                Error ("Expecting 11101001111010011100111, got " + debug);
                Console.ReadLine();
                return;
            }

            Console.WriteLine(stream.ByteAt (0) + " / 233");
            if (stream.ByteAt (0) != 233) {
                Error ("Expected byte at 0 to be 233, not: " + stream.ByteAt (0));
                Console.ReadLine();
                return;
            }
            Console.WriteLine (stream.ByteAt (1) + " / 233");
            if (stream.ByteAt (1) != 233) {
                Error ("Expected byte at 1 to be 233, not: " + stream.ByteAt (1));
                Console.ReadLine();
                return;
            }
            Console.WriteLine (stream.ByteAt (2) + " / 206");
            if (stream.ByteAt (2) != 206) {
                Error ("Expected byte at 2 to be 206, not: " + stream.ByteAt (2));
                Console.ReadLine();
                return;
            }

            Console.WriteLine ("Num bytes: " + stream.ByteCount + " / 3");
            if (stream.ByteCount != 3) {
                Error ("Expecting ByteCount to be 3, not: " + stream.ByteCount);
                Console.ReadLine();
                return;
            }
            Console.WriteLine ("Num bits: " + stream.BitCount + " / 23");
            if (stream.BitCount != 23) {
                Error ("Expecting BitCount to be 23, not: " + stream.BitCount);
                Console.ReadLine();
                return;
            }

            Console.WriteLine (stream.ToString ());
            byte[] bits = stream.Bytes;
            for (int i = 0; i < bits.Length; ++i) {
                Console.Write(Convert.ToString(bits[i], 2).PadLeft(8, '0'));
            }
            Console.Write ("\n");
            Console.ReadLine();
        }