public int getChar(BitStream s) { HuffNode n = root; long bit; int ch; // find the leaf node: while (n.character == innode) { bit = s.ReadBits(1); n = ((bit & 1) != 0) ? n.right : n.left; } if (n.character == NYT) { // if the leaf is NYT, read the next character: ch = (int)s.ReadBits(codeSize); splitNYT(ch); n = leaves[ch].parent; } else { ch = n.character; } // update the tree: rearrangeTree(n); return(ch); }
private void splitNYT(int character) { HuffNode n1, n2; n1 = new HuffNode(NYT); n2 = new HuffNode(character); leaves[NYT].character = innode; leaves[NYT].freq = 1; // siblings: n1.next = n2; n2.next = leaves[NYT]; n2.prev = n1; leaves[NYT].prev = n2; // tree links: n1.parent = leaves[NYT]; n2.parent = leaves[NYT]; leaves[NYT].left = n1; leaves[NYT].right = n2; // update leaf node: leaves[NYT] = n1; leaves[character] = n2; }
public void init(int maxSymbol) { if (wordCount != maxSymbol + 2) { wordCount = maxSymbol + 2; // including NYT NYT = maxSymbol + 1; innode = maxSymbol + 2; // compute code-word size: codeSize = 1; int size = 2; while (size < NYT) { size += size; codeSize++; } // array of leaves: leaves = new HuffNode[wordCount]; } else { for (int i = 0; i < wordCount;) { leaves[i] = null; } } // root item: root = new HuffNode(NYT); leaves[NYT] = root; }
private void writeCode(HuffNode node, BitStream s) { if (node == root) { return; } writeCode(node.parent, s); s.WriteBits((node.parent.left == node) ? 0 : 1, 1); }
private void rearrangeTree(HuffNode node) { while (node != root) { node = swapLast(node); node.freq++; node = node.parent; } node.freq++; }
private void printTreeInner(HuffNode node) { if (node == null) { return; } printTreeInner(node.left); printTreeInner(node.right); }
/// <summary> /// Builds tree. /// </summary> /// <param name="source"></param> public void Build(byte[] source) { Frequencies = new Dictionary <byte, int>(); for (int i = 0; i < source.Length; i++) { if (!Frequencies.ContainsKey(source[i])) { //table.Add(source[i], 0); Frequencies.Add(source[i], 0); //ary.Add(new KeyValuePair<byte, int>(source[i],0)); } Frequencies[source[i]]++; //int temp = ary.ElementAt(i).Value; //ary.RemoveAt(i); //ary.Insert(i, new KeyValuePair<byte, int>(source[i],++temp)); //int temp = (int)table[source[i]]; //table.Remove(source[i]); //table.Add(source[i], +temp); } foreach (KeyValuePair <byte, int> symbol in Frequencies) { nodes.Add(new HuffNode() { Symbol = symbol.Key, Frequency = symbol.Value }); } while (nodes.Count > 1) { List <HuffNode> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList <HuffNode>(); if (orderedNodes.Count >= 2) { // Take first two items List <HuffNode> taken = orderedNodes.Take(2).ToList <HuffNode>(); // Create a parent node by combining the frequencies HuffNode parent = new HuffNode() { Symbol = (byte)'*', Frequency = taken[0].Frequency + taken[1].Frequency, Left = taken[0], Right = taken[1] }; nodes.Remove(taken[0]); nodes.Remove(taken[1]); nodes.Add(parent); } this.Root = nodes.FirstOrDefault(); } }
public byte[] Decode(BitArray bits) { int[] size = { 0 }; ExtractFront(bits, sizeof(int) * 8).CopyTo(size, 0); bits = ExtractEnd(bits, bits.Length - sizeof(int) * 8);//bits is bits - size MemoryStream ms = new MemoryStream(); Frequencies = new Dictionary <byte, int>(); for (int i = 0; i < size[0]; i++) { BitArray freq = ExtractFront(bits, sizeof(byte) * 8);// byte[] key = { 0 }; freq.CopyTo(key, 0); bits = ExtractEnd(bits, bits.Length - sizeof(byte) * 8); freq = ExtractFront(bits, sizeof(int) * 8); int[] value = { 0 }; freq.CopyTo(value, 0); bits = ExtractEnd(bits, bits.Length - sizeof(int) * 8); Frequencies.Add(key[0], value[0]); } Build(); //Frequencies = (Dictionary<byte, int>)bs.Deserialize(ms); HuffNode current = this.Root; List <byte> decoded = new List <byte>(); foreach (bool bit in bits) { if (bit) { if (current.Right != null) { current = current.Right; } } else { if (current.Left != null) { current = current.Left; } } if (IsLeaf(current)) { decoded.Add(current.Symbol); current = this.Root; } } return(decoded.ToArray()); }
/// <summary> /// Builds tree with already constructed frequencies table. /// </summary> public void Build() { foreach (KeyValuePair <byte, int> symbol in Frequencies) { nodes.Add(new HuffNode() { Symbol = symbol.Key, Frequency = symbol.Value }); } while (nodes.Count > 1) { List <HuffNode> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList <HuffNode>(); if (orderedNodes.Count >= 2) { // Take first two items List <HuffNode> taken = orderedNodes.Take(2).ToList <HuffNode>(); // Create a parent node by combining the frequencies HuffNode parent = new HuffNode() { Symbol = (byte)'*', Frequency = taken[0].Frequency + taken[1].Frequency, Left = taken[0], Right = taken[1] }; nodes.Remove(taken[0]); nodes.Remove(taken[1]); nodes.Add(parent); } this.Root = nodes.FirstOrDefault(); } }
/// <summary> /// Check if node is a leaf node. /// </summary> /// <param name="node"></param> /// <returns></returns> public bool IsLeaf(HuffNode node) { return(node.Left == null && node.Right == null); }
private HuffNode swapLast(HuffNode node) { HuffNode n; // find the last node with the same frequency.. n = node; while (n.next != null && n.next != root && n.next.freq == node.freq) { n = n.next; } // it's me and my parent => dont swap if (n == node) { return(node); } // swap data: int d = node.character; node.character = n.character; n.character = d; long f = node.freq; node.freq = n.freq; n.freq = f; // swap children: HuffNode h; h = node.left; node.left = n.left; n.left = h; h = node.right; node.right = n.right; n.right = h; if (node.character == innode) { node.left.parent = node; node.right.parent = node; } if (n.character == innode) { n.left.parent = n; n.right.parent = n; } // update list of leaves: if (node.character != innode) { leaves[node.character] = node; } if (n.character != innode) { leaves[n.character] = n; } return(n); }