public void Write(BinaryCode code) { foreach (bool b in code) { Write(b); } }
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); }
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(); }
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(); }
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); }
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); }
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); } }