Example #1
0
 public void Write(BinaryCode code)
 {
     foreach (bool b in code)
     {
         Write(b);
     }
 }
Example #2
0
        Dictionary <Symbol, BinaryCode> ParseNode(TreeNode node)
        {
            Dictionary <Symbol, BinaryCode> dict = new Dictionary <Symbol, BinaryCode>();

            if (node is TreeNodeLeaf leaf)
            {
                dict.Add(leaf.symbol, new BinaryCode());
            }
            else if (node is TreeNodeInternal inter)
            {
                for (int bit = 0; bit <= 1; bit++)
                {
                    Dictionary <Symbol, BinaryCode> dict0 = ParseNode(inter.next[bit]);
                    foreach (KeyValuePair <Symbol, BinaryCode> entry0 in dict0)
                    {
                        Symbol     sym  = entry0.Key;
                        BinaryCode code = entry0.Value;
                        code.Insert(0, bit == 1);
                        dict.Add(sym, code);
                    }
                }
            }
            else
            {
                throw new NotSupportedException("Node type is not supported!");
            }


            return(dict);
        }
Example #3
0
        static void decode(string inPath, string outPath)
        {
            BitReader  input        = new BitReader(new FileStream(inPath, FileMode.Open));
            FileStream outputStream = new FileStream(outPath, FileMode.OpenOrCreate);

            outputStream.SetLength(0);
            BinaryWriter output = new BinaryWriter(outputStream);

            // Check if everything is fine
            UInt32 magic = input.ReadUInt32();

            if (magic != headerMagic)
            {
                throw new ArgumentException("Bad Header");
            }
            Int64 fileSize = input.ReadInt64();

            magic = input.ReadUInt32();
            if (magic != codeMagic)
            {
                throw new ArgumentException("Bad Code Header");
            }
            Int16 letterCount = input.ReadInt16();

            // Create Huffman tree from the input data: deserialize CODE section
            Dictionary <BinaryCode, Symbol> dict = new Dictionary <BinaryCode, Symbol>();

            for (int i = 0; i < letterCount; i++)
            {
                magic = input.ReadByte();
                if (magic != letterCodeMagic)
                {
                    throw new ArgumentException("Bad Letter Code");
                }

                CharSymbol sym  = new CharSymbol(input);
                BinaryCode code = new BinaryCode(input);
                dict.Add(code, sym);
            }
            Tree huffTree = new Tree(dict);

            magic = input.ReadUInt32();
            if (magic != dataMagic)
            {
                throw new ArgumentException("Bad Data Header");
            }

            // Do it
            Tree.DecodeState state = new Tree.DecodeState(output, huffTree);
            while (state.writtenBytes < fileSize)
            {
                state.ParseBit(input.ReadBoolean());
            }


            input.Close();
            output.Close();
        }
Example #4
0
        static void encode(string inPath, string outPath)
        {
            FileStream input      = new FileStream(inPath, FileMode.Open);
            FileStream outputFile = new FileStream(outPath, FileMode.OpenOrCreate);

            outputFile.SetLength(0);
            BitWriter output = new BitWriter(outputFile);

            // Prepare parse states
            SortedSet <Symbol> symbols = generateSymbols(input);
            Tree huffTree = new Tree(symbols);
            Dictionary <Symbol, BinaryCode> codes = huffTree.GenerateCodeTable();

            foreach (KeyValuePair <Symbol, BinaryCode> entry in codes)
            {
                Console.WriteLine(String.Format("{0} : {1}", entry.Key, entry.Value));
            }

            // Output header information
            output.Write(headerMagic);
            output.Write((UInt64)input.Length);
            output.Write(codeMagic);
            output.Write((UInt16)codes.Keys.Count);
            foreach (KeyValuePair <Symbol, BinaryCode> entry in codes)
            {
                Symbol     sym  = entry.Key;
                BinaryCode code = entry.Value;

                output.Write(letterCodeMagic);
                sym.Serialize(output);
                code.Serialize(output);
            }
            output.Write(dataMagic);

            // Parse the input file
            int letter;

            while ((letter = input.ReadByte()) != -1)
            {
                CharSymbol symbol = new CharSymbol(0, (byte)letter);
                BinaryCode code   = codes[symbol];
                output.Write(code);
            }

            output.AlignAndWrite();
            output.Close();
            output.Dispose();
            input.Close();
            input.Dispose();
        }
Example #5
0
        public bool Equals(BinaryCode other)
        {
            bool cmpLength = Count.Equals(other.Count);

            if (!cmpLength)
            {
                return(cmpLength);
            }

            var symbolsZip = this.Zip(other, (n, w) => new { ThisSym = n, OtherSym = w });

            foreach (var nw in symbolsZip)
            {
                bool cmp = nw.ThisSym.Equals(nw.OtherSym);
                if (cmp)
                {
                    return(cmp);
                }
            }
            return(true);
        }
Example #6
0
        public int CompareTo(BinaryCode other)
        {
            int cmpLength = Count.CompareTo(other.Count);

            if (cmpLength != 0)
            {
                return(cmpLength);
            }

            var symbolsZip = this.Zip(other, (n, w) => new { ThisSym = n, OtherSym = w });

            foreach (var nw in symbolsZip)
            {
                int cmp = nw.ThisSym.CompareTo(nw.OtherSym);
                if (cmp != 0)
                {
                    return(cmp);
                }
            }
            return(0);
        }
Example #7
0
        public Tree(Dictionary <BinaryCode, Symbol> codes)
        {
            root = new TreeNodeInternal();

            // Recreate Tree from provided BinaryCodes
            foreach (KeyValuePair <BinaryCode, Symbol> entry in codes)
            {
                BinaryCode code = entry.Key;
                Symbol     sym  = entry.Value;

                TreeNodeInternal node = root;
                TreeNodeInternal prev = null;

                // Traverse the tree and create necessary internal nodes on fly
                // FIXME: Dirty but idk how to fix
                int bitint = 0;
                foreach (bool bit in code)
                {
                    prev = node;

                    bitint = bit ? 1 : 0;
                    if (node.next[bitint] == null)
                    {
                        node.next[bitint] = new TreeNodeInternal();
                    }

                    if (node.next[bitint] is TreeNodeInternal inter)
                    {
                        node = inter;
                    }
                    else
                    {
                        throw new ArgumentException("Invalid Code!");
                    }
                }

                prev.next[bitint] = new TreeNodeLeaf(sym);
            }
        }