// Construct the Huffman coding tree. private void CreateTree() { IPriorityQueue <HuffNode> pq = new BinaryHeap <HuffNode>(); for (int i = 0; i < BitUtils.DIFF_BYTES; i++) { if (theCounts.GetCount(i) > 0) { HuffNode newNode = new HuffNode(i, theCounts.GetCount(i), null, null, null); theNodes[i] = newNode; pq.Insert(newNode); } } theNodes[END] = new HuffNode(END, 1, null, null, null); pq.Insert(theNodes[END]); while (pq.Size() > 1) { HuffNode n1 = pq.DeleteMin(); HuffNode n2 = pq.DeleteMin(); HuffNode result = new HuffNode(INCOMPLETE_CODE, n1.weight + n2.weight, n1, n2, null); n1.parent = n2.parent = result; pq.Insert(result); } root = pq.FindMin(); }
public void CalcIndex(HuffNode h) { if (h.e0 == null && h.e1 == null && !h.hasIndex) { int u; if (((ushort)h.c) >= 0x100) { u = (short)(0xFFFF - (ushort)h.c); } else { u = (int)(0xFFFFFFFF - (uint)h.c); } h.index = u; h.hasIndex = true; } else { CalcIndex(h.e0); CalcIndex(h.e1); if (h.e0.hasIndex && h.e1.hasIndex) { h.index = NodeList.Count / 2; h.hasIndex = true; NodeList.Add(h.e0.index); NodeList.Add(h.e1.index); } } }
// Return the code corresponding to character ch. // (The parameter is an int to accomodate EOF). // If code is not found, return an array of length 0. public byte[] GetCode(int ch) { HuffNode current = theNodes[ch]; if (current == null) { return(null); } string v = ""; HuffNode par = current.parent; while (par != null) { if (par.left == current) { v = "0" + v; } else { v = "1" + v; } current = current.parent; par = current.parent; } byte[] result = new byte[v.Length]; for (int i = 0; i < result.Length; i++) { result[i] = (byte)(v[i] == '0' ? 0 : 1); } return(result); }
void WriteHuffTree(HuffNode root, System.IO.Stream stream) { if (root.zero != null) { WriteBits(1, 1, stream); WriteHuffTree(root.zero, stream); if (root.one != null) { WriteHuffTree(root.one, stream); } else { throw new Exception(); } } else { if (root.one == null) { WriteBits(0, 1, stream); WriteBits(root.content, 8, stream); } else { throw new Exception(); } } }
void EncodeByte(HuffNode root, byte val, out int res, out int bits) { List <HuffNode> opend = new List <HuffNode>(); opend.Add(root); HuffNode found = null; while (opend.Count > 0) { HuffNode node = opend[0]; opend.Remove(node); if (node.content == val && node.zero == null && node.one == null) { found = node; break; } if (node.zero != null) { opend.Add(node.zero); } if (node.one != null) { opend.Add(node.one); } } if (found == null) { throw new Exception(); } res = found.code; bits = found.bits; }
public HuffNode(char chr, long weight) { e0 = e1 = null; c = chr; w = weight; hasIndex = false; }
public void CalcIndex(HuffNode h) { if (h.e0 == null && h.e1 == null && !h.hasIndex) { int u; if (((ushort)h.c) < 0x100) u = (short)(0xFFFF - (short)h.c); else u = (int)(0xFFFFFFFF - (uint)h.c); h.index = u; h.hasIndex = true; } else { CalcIndex(h.e0); CalcIndex(h.e1); if (h.e0.hasIndex && h.e1.hasIndex) { h.index = NodeList.Count / 2; h.hasIndex = true; NodeList.Add(h.e0.index); NodeList.Add(h.e1.index); } } }
void WriteContent(HuffNode root, System.IO.Stream stream) { foreach (byte i in src) { int code; int bits; EncodeByte(root, i, out code, out bits); WriteBits(code, bits, stream, false); } }
HuffNode[] nodelist = new HuffNode[515]; // 515 because StuffIt Classic needs more than the needed 511 int gethuffbyte(HuffNode l_nodelist) { HuffNode np; np = l_nodelist; while (np.flag == 0) { np = get_bit() != 0 ? np.one : np.zero; } return(np.Byte); }
public void Compress() { HuffNode root = BuildHuffTree(); System.IO.MemoryStream ms = new System.IO.MemoryStream(); bits = 0; curChar = 0; WriteHuffTree(root, ms); WriteContent(root, ms); buffer = ms.ToArray(); bufferLen = buffer.Length; }
//生成Huffman树 private HuffmanTree Build() { while (nodes.Count > 1) { HuffNode firstNode = this.RemoveFirst(); HuffNode secondNode = this.RemoveFirst(); int newWeight = firstNode.weight + secondNode.weight; nodes.Add(new InternalNode(firstNode, secondNode, newWeight)); } return(new HuffmanTree(nodes[0])); }
private void testTree(HuffNode node) { if (node is LeafNode) { Console.Write(Convert.ToInt16(((LeafNode)node).E)); Console.Write("//"); return; } if (node is InternalNode) { Console.Write("_"); testTree(((InternalNode)node).leftChild); testTree(((InternalNode)node).rightChild); } }
//private void QuickSortTrees(int left, int right) //{ // if (left >= right) // return; // //快排实现 // HuffmanTree privot = nodes[left]; // int curr_left = left++; // int curr_right = right; // while(curr_left <= curr_right) // { // if (nodes[curr_left].Weight() < privot.Weight()) // curr_left++; // if (nodes[curr_right].Weight() > privot.Weight()) // curr_right--; // } // if(curr_left < curr_right) // Swap(ref nodes[curr_left], ref nodes[curr_right]); // if(privot.Weight() < nodes[curr_left].Weight()) // Swap(ref nodes[curr_left], ref privot); // QuickSortTrees(left, (left + right) / 2); // QuickSortTrees((left + right) / 2+1, right); //} private HuffNode RemoveFirst() { if (nodes.Count > 0) { nodes.Sort(Compare); HuffNode temp = nodes[0]; nodes.RemoveAt(0); return(temp); } else { return(null); } }
public AlphaEntry[] GetAlphabet(HuffNode h, List <bool> list) { List <AlphaEntry> result = new List <AlphaEntry>(); if (h.e0.e0 == null) { AlphaEntry e = new AlphaEntry(); e.c = h.e0.c; List <bool> t = new List <bool>(); t.AddRange(list); t.Add(false); e.list = t.ToArray(); result.Add(e); } else { List <bool> t = new List <bool>(); t.AddRange(list); t.Add(false); result.AddRange(GetAlphabet(h.e0, t)); } if (h.e1.e0 == null) { AlphaEntry e = new AlphaEntry(); e.c = h.e1.c; List <bool> t = new List <bool>(); t.AddRange(list); t.Add(true); e.list = t.ToArray(); result.Add(e); } else { List <bool> t = new List <bool>(); t.AddRange(list); t.Add(true); result.AddRange(GetAlphabet(h.e1, t)); } return(result.ToArray()); }
public AlphaEntry[] GetAlphabet(HuffNode h, List<bool> list) { List<AlphaEntry> result = new List<AlphaEntry>(); if (h.e0.e0 == null) { AlphaEntry e = new AlphaEntry(); e.c = h.e0.c; List<bool> t = new List<bool>(); t.AddRange(list); t.Add(false); e.list = t.ToArray(); result.Add(e); } else { List<bool> t = new List<bool>(); t.AddRange(list); t.Add(false); result.AddRange(GetAlphabet(h.e0, t)); } if (h.e1.e0 == null) { AlphaEntry e = new AlphaEntry(); e.c = h.e1.c; List<bool> t = new List<bool>(); t.AddRange(list); t.Add(true); e.list = t.ToArray(); result.Add(e); } else { List<bool> t = new List<bool>(); t.AddRange(list); t.Add(true); result.AddRange(GetAlphabet(h.e1, t)); } return result.ToArray(); }
private byte[] ReadData(HuffmanTree huffTree, char[] bitArray, int lastByteOffset) { string data = ""; for (int i = 0; i < bitArray.Length - lastByteOffset;) { HuffNode currentNode = huffTree.root; while (true) { if (bitArray[i] == '0') { currentNode = ((InternalNode)currentNode).leftChild; } else if (bitArray[i] == '1') { currentNode = ((InternalNode)currentNode).rightChild; } i++; if (currentNode is LeafNode) { data += ((LeafNode)currentNode).E; Console.Write(Convert.ToInt32(((LeafNode)currentNode).E) + " "); break; } } } char[] ca = data.ToCharArray(); byte[] result = new byte[data.Length]; for (int i = 0; i < result.Length; i++) { result[i] = (byte)ca[i]; } return(result); }
// Get the character corresponding to code. public int GetChar(string code) { HuffNode p = root; for (int i = 0; p != null && i < code.Length; i++) { if (code[i] == '0') { p = p.left; } else { p = p.right; } } if (p == null) { return(ERROR); } return(p.value); }
public TreeNode GenTree(TreeNode t, HuffNode h) { if (h.e0 == null && h.e1 == null) { t.Nodes.Add("'" + h.c + "'"); } else { if (h.e0 != null) { TreeNode t1 = new TreeNode("0"); t1 = GenTree(t1, h.e0); t.Nodes.Add(t1); } if (h.e1 != null) { TreeNode t2 = new TreeNode("1"); t2 = GenTree(t2, h.e1); t.Nodes.Add(t2); } } return(t); }
public void Save(Stream s) { long[] weights = new long[256 * 256]; foreach (STR line in Strings) { weights[0]++; //string terminator for line foreach (char c in line.Value) weights[(ushort)c]++; } Dictionary<char, long> weighttable = new Dictionary<char, long>(); for (int i = 0; i < 256 * 256; i++) if (weights[i] > 0) weighttable.Add((char)i, weights[i]); List<HuffNode> nodes = new List<HuffNode>(); foreach (KeyValuePair<char, long> w in weighttable) nodes.Add(new HuffNode(w.Key, w.Value)); while (nodes.Count > 1) { bool run = true; while (run) { run = false; for (int i = 0; i < nodes.Count - 1; i++) if (nodes[i].w > nodes[i + 1].w) { run = true; HuffNode t = nodes[i]; nodes[i] = nodes[i + 1]; nodes[i + 1] = t; } } HuffNode e0 = nodes[0]; HuffNode e1 = nodes[1]; HuffNode combine = new HuffNode(' ', e0.w + e1.w); combine.e0 = e0; combine.e1 = e1; nodes.RemoveAt(1); nodes.RemoveAt(0); nodes.Add(combine); } HuffNode root = nodes[0]; NodeList = new List<int>(); while (!root.hasIndex) CalcIndex(root); AlphaEntry[] alphabet = GetAlphabet(root, new List<bool>()); BitStream = new List<uint>(); StringList = new List<StringID>(); uint curr = 0; uint index = 0; byte shift = 0; foreach (STR str in Strings) { StringID t = new StringID(); t.ID = str.ID; t.offset = index << 5; t.offset += shift; string line = str.Value + "\0"; foreach (char c in line) { AlphaEntry alpha = null; foreach (AlphaEntry a in alphabet) if (a.c == c) alpha = a; foreach (bool step in alpha.list) { byte b = 0; if (step) b = 1; if (shift < 32) { curr += (uint)(b << shift); shift++; } if (shift == 32) { BitStream.Add(curr); index++; shift = 0; curr = 0; } } } StringList.Add(t); } BitStream.Add(curr); Helpers.WriteInt(s, (int)magic); Helpers.WriteInt(s, (int)unk01); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); Helpers.WriteInt(s, (int)unk02); Helpers.WriteInt(s, (int)unk03); Helpers.WriteInt(s, (int)unk04); Helpers.WriteInt(s, NodeList.Count); Helpers.WriteInt(s, 0x38); Helpers.WriteInt(s, StringList.Count); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4); Helpers.WriteInt(s, 0); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); Helpers.WriteInt(s, 0); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); foreach (int i in NodeList) Helpers.WriteInt(s, i); foreach (StringID sid in StringList) { Helpers.WriteInt(s, (int)sid.ID); Helpers.WriteInt(s, (int)sid.offset); } foreach (int i in BitStream) Helpers.WriteInt(s, i); }
void EncodeByte(HuffNode root, byte val, out int res, out int bits) { List<HuffNode> opend = new List<HuffNode>(); opend.Add(root); HuffNode found = null; while (opend.Count > 0) { HuffNode node = opend[0]; opend.Remove(node); if (node.content == val && node.zero == null && node.one == null) { found = node; break; } if (node.zero != null) opend.Add(node.zero); if (node.one != null) opend.Add(node.one); } if (found == null) throw new Exception(); res = found.code; bits = found.bits; }
public void Generate() { long[] weights = new long[256]; foreach (STR line in talk.Strings) { weights[0]++; //string terminator for line foreach (char c in line.Value) { weights[(byte)c]++; } } Dictionary <char, long> weighttable = new Dictionary <char, long>(); for (int i = 0; i < 256; i++) { if (weights[i] > 0) { weighttable.Add((char)i, weights[i]); } } List <HuffNode> nodes = new List <HuffNode>(); foreach (KeyValuePair <char, long> w in weighttable) { nodes.Add(new HuffNode(w.Key, w.Value)); } while (nodes.Count > 1) { bool run = true; while (run) { run = false; for (int i = 0; i < nodes.Count - 1; i++) { if (nodes[i].w > nodes[i + 1].w) { run = true; HuffNode t = nodes[i]; nodes[i] = nodes[i + 1]; nodes[i + 1] = t; } } } HuffNode e0 = nodes[0]; HuffNode e1 = nodes[1]; HuffNode combine = new HuffNode(' ', e0.w + e1.w); combine.e0 = e0; combine.e1 = e1; nodes.RemoveAt(1); nodes.RemoveAt(0); nodes.Add(combine); } treeView2.Nodes.Clear(); HuffNode h = nodes[0]; TreeNode root = new TreeNode("root (generated from weights)"); root = GenTree(root, h); treeView2.Nodes.Add(root); NodeList = new List <int>(); while (!h.hasIndex) { CalcIndex(h); } listBox5.Items.Clear(); int count = 0; foreach (int i in NodeList) { listBox5.Items.Add((count++) + " : " + i.ToString("X4")); } TreeNode root2 = new TreeNode("root (generated from flattening)"); root2 = MakeTree2(root2, NodeList.Count / 2 - 1); root2.ExpandAll(); treeView2.Nodes.Add(root2); AlphaEntry[] alphabet = GetAlphabet(h, new List <bool>()); listBox6.Items.Clear(); foreach (AlphaEntry a in alphabet) { StringBuilder sb = new StringBuilder(); sb.Append("'"); if ((byte)a.c != 0) { sb.Append(a.c); } else { sb.Append("/0"); } sb.Append("' = "); foreach (bool b in a.list) { if (b) { sb.Append("1"); } else { sb.Append("0"); } } listBox6.Items.Add(sb.ToString()); } BitStream = new List <uint>(); StringList = new List <StringID>(); uint curr = 0; uint index = 0; byte shift = 0; foreach (STR str in talk.Strings) { StringID t = new StringID(); t.ID = str.ID; t.offset = index << 5; t.offset += shift; string s = str.Value + "\0"; foreach (char c in s) { AlphaEntry alpha = null; foreach (AlphaEntry a in alphabet) { if ((byte)a.c == (byte)c) { alpha = a; } } foreach (bool step in alpha.list) { byte b = 0; if (step) { b = 1; } if (shift < 32) { curr += (uint)(b << shift); shift++; } if (shift == 32) { BitStream.Add(curr); index++; shift = 0; curr = 0; } } } StringList.Add(t); } BitStream.Add(curr); listBox7.Items.Clear(); listBox8.Items.Clear(); count = 0; for (int i = 0; i < StringList.Count; i++) { listBox7.Items.Add((count++).ToString("d4") + ". ID : 0x" + (StringList[i].ID).ToString("X8") + " Offset : 0x" + StringList[i].offset.ToString("X8")); } count = 0; foreach (uint u in BitStream) { listBox8.Items.Add((count++).ToString("d4") + ". : " + uint2String(u)); } }
public TreeNode GenTree(TreeNode t, HuffNode h) { if (h.e0 == null && h.e1 == null) t.Nodes.Add("'" + h.c + "'"); else { if (h.e0 != null) { TreeNode t1 = new TreeNode("0"); t1 = GenTree(t1, h.e0); t.Nodes.Add(t1); } if (h.e1 != null) { TreeNode t2 = new TreeNode("1"); t2 = GenTree(t2, h.e1); t.Nodes.Add(t2); } } return t; }
/* See routine LoadTree. The parameter tree (actually an array and two integers) are only used locally in this version and hence locally declared. The parameter nodes has been renamed Hufftree.... */ private void cpt_readHuff(int size, HuffNode[] Hufftree) { sf_entry[] tree_entry = new sf_entry[256 + SLACK]; // maximal number of elements int tree_entries; int tree_MaxLength; // finishes local declaration of tree int len; // declarations from ReadLengths int j; int codelen, lvlstart, next, parents; int[] tree_count = new int[32]; // next paraphrased from ReadLengths with adaption for Compactor. int treeBytes = cpt_data[cpt_char++]; if (size < treeBytes * 2) // too many entries, something is wrong! throw new ApplicationException(string.Format("Bytes is: {0}, expected: {1}.", treeBytes, size / 2)); tree_MaxLength = 0; tree_entries = 0; int i = 0; while (treeBytes-- > 0) { // adaption for Compactor len = cpt_data[cpt_char] >> 4; if (len != 0) { // only if length unequal zero if (len > tree_MaxLength) { tree_MaxLength = len; } tree_count[len]++; tree_entry[tree_entries].Value = i; tree_entry[tree_entries++].BitLength = (uint)len; } i++; const int NIBBLEMASK = 0x0F; len = cpt_data[cpt_char++] & NIBBLEMASK; if (len != 0) { // only if length unequal zero if (len > tree_MaxLength) { tree_MaxLength = len; } tree_count[len]++; tree_entry[tree_entries].Value = i; tree_entry[tree_entries++].BitLength = (uint)len; } i++; } // Compactor allows unused trailing codes in its Huffman tree! j = 0; for (i = 0; i <= tree_MaxLength; i++) { j = (j << 1) + tree_count[i]; } j = (1 << tree_MaxLength) - j; // Insert the unused entries for sorting purposes. for (i = 0; i < j; i++) { tree_entry[tree_entries].Value = size; tree_entry[tree_entries++].BitLength = (uint)tree_MaxLength; } // adaption from SortLengths SortEntries(tree_entry, tree_entries); // Adapted from GenerateTrees i = tree_entries - 1; // starting at the upper end (and reversing loop) because of Compactor lvlstart = next = size * 2 + SLACK - 1; // slight adaption because of different node format used for (codelen = tree_MaxLength; codelen >= 1; --codelen) { while ((i >= 0) && (tree_entry[i].BitLength == codelen)) { Hufftree[next] = new HuffNode(); Hufftree[next].Byte = tree_entry[i].Value; Hufftree[next].flag = 1; next--; i--; } parents = next; if (codelen > 1) { // reversed loop for (j = lvlstart; j > parents + 1; j -= 2) { Hufftree[next] = new HuffNode(); Hufftree[next].one = Hufftree[j]; Hufftree[next].zero = Hufftree[j - 1]; Hufftree[next].flag = 0; next--; } } lvlstart = parents; } Hufftree[0] = new HuffNode(); Hufftree[0].one = Hufftree[next + 2]; Hufftree[0].zero = Hufftree[next + 1]; Hufftree[0].flag = 0; }
HuffNode[] nodelist = new HuffNode[515]; // 515 because StuffIt Classic needs more than the needed 511 int gethuffbyte(HuffNode l_nodelist) { HuffNode np; np = l_nodelist; while (np.flag == 0) { np = get_bit() != 0 ? np.one : np.zero; } return np.Byte; }
/* See routine LoadTree. The parameter tree (actually an array and * two integers) are only used locally in this version and hence locally * declared. The parameter nodes has been renamed Hufftree.... */ private void cpt_readHuff(int size, HuffNode[] Hufftree) { sf_entry[] tree_entry = new sf_entry[256 + SLACK]; // maximal number of elements int tree_entries; int tree_MaxLength; // finishes local declaration of tree int len; // declarations from ReadLengths int j; int codelen, lvlstart, next, parents; int[] tree_count = new int[32]; // next paraphrased from ReadLengths with adaption for Compactor. int treeBytes = cpt_data[cpt_char++]; if (size < treeBytes * 2) // too many entries, something is wrong! { throw new ApplicationException(string.Format("Bytes is: {0}, expected: {1}.", treeBytes, size / 2)); } tree_MaxLength = 0; tree_entries = 0; int i = 0; while (treeBytes-- > 0) { // adaption for Compactor len = cpt_data[cpt_char] >> 4; if (len != 0) { // only if length unequal zero if (len > tree_MaxLength) { tree_MaxLength = len; } tree_count[len]++; tree_entry[tree_entries].Value = i; tree_entry[tree_entries++].BitLength = (uint)len; } i++; const int NIBBLEMASK = 0x0F; len = cpt_data[cpt_char++] & NIBBLEMASK; if (len != 0) { // only if length unequal zero if (len > tree_MaxLength) { tree_MaxLength = len; } tree_count[len]++; tree_entry[tree_entries].Value = i; tree_entry[tree_entries++].BitLength = (uint)len; } i++; } // Compactor allows unused trailing codes in its Huffman tree! j = 0; for (i = 0; i <= tree_MaxLength; i++) { j = (j << 1) + tree_count[i]; } j = (1 << tree_MaxLength) - j; // Insert the unused entries for sorting purposes. for (i = 0; i < j; i++) { tree_entry[tree_entries].Value = size; tree_entry[tree_entries++].BitLength = (uint)tree_MaxLength; } // adaption from SortLengths SortEntries(tree_entry, tree_entries); // Adapted from GenerateTrees i = tree_entries - 1; // starting at the upper end (and reversing loop) because of Compactor lvlstart = next = size * 2 + SLACK - 1; // slight adaption because of different node format used for (codelen = tree_MaxLength; codelen >= 1; --codelen) { while ((i >= 0) && (tree_entry[i].BitLength == codelen)) { Hufftree[next] = new HuffNode(); Hufftree[next].Byte = tree_entry[i].Value; Hufftree[next].flag = 1; next--; i--; } parents = next; if (codelen > 1) { // reversed loop for (j = lvlstart; j > parents + 1; j -= 2) { Hufftree[next] = new HuffNode(); Hufftree[next].one = Hufftree[j]; Hufftree[next].zero = Hufftree[j - 1]; Hufftree[next].flag = 0; next--; } } lvlstart = parents; } Hufftree[0] = new HuffNode(); Hufftree[0].one = Hufftree[next + 2]; Hufftree[0].zero = Hufftree[next + 1]; Hufftree[0].flag = 0; }
public HuffNode(char chr, long weight) { e0 = e1 = null; c = chr; w = weight; hasIndex = false; }
public void Save(Stream s) { long[] weights = new long[256 * 256]; foreach (STR line in Strings) { weights[0]++; foreach (char c in line.Value) { weights[(ushort)c]++; } } Dictionary <char, long> weighttable = new Dictionary <char, long>(); for (int i = 0; i < 256 * 256; i++) { if (weights[i] > 0) { weighttable.Add((char)i, weights[i]); } } List <HuffNode> nodes = new List <HuffNode>(); foreach (KeyValuePair <char, long> w in weighttable) { nodes.Add(new HuffNode(w.Key, w.Value)); } while (nodes.Count > 1) { bool run = true; while (run) { run = false; for (int i = 0; i < nodes.Count - 1; i++) { if (nodes[i].w > nodes[i + 1].w) { run = true; HuffNode t = nodes[i]; nodes[i] = nodes[i + 1]; nodes[i + 1] = t; } } } HuffNode e0 = nodes[0]; HuffNode e1 = nodes[1]; HuffNode combine = new HuffNode(' ', e0.w + e1.w); combine.e0 = e0; combine.e1 = e1; nodes.RemoveAt(1); nodes.RemoveAt(0); nodes.Add(combine); } HuffNode root = nodes[0]; NodeList = new List <int>(); while (!root.hasIndex) { CalcIndex(root); } AlphaEntry[] alphabet = GetAlphabet(root, new List <bool>()); BitStream = new List <uint>(); StringList = new List <StringID>(); uint curr = 0; uint index = 0; byte shift = 0; foreach (STR str in Strings) { StringID t = new StringID(); t.ID = str.ID; t.offset = index << 5; t.offset += shift; string line = str.Value + "\0"; foreach (char c in line) { AlphaEntry alpha = null; foreach (AlphaEntry a in alphabet) { if (a.c == c) { alpha = a; } } foreach (bool step in alpha.list) { byte b = 0; if (step) { b = 1; } if (shift < 32) { curr += (uint)(b << shift); shift++; } if (shift == 32) { BitStream.Add(curr); index++; shift = 0; curr = 0; } } } StringList.Add(t); } BitStream.Add(curr); Helpers.WriteInt(s, (int)magic); Helpers.WriteInt(s, (int)unk01); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); Helpers.WriteUShort(s, 4); Helpers.WriteUShort(s, unk03); Helpers.WriteInt(s, (int)unk04); Helpers.WriteInt(s, (int)unk05); Helpers.WriteInt(s, NodeList.Count); Helpers.WriteInt(s, 0x38); Helpers.WriteInt(s, StringList.Count); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4); Helpers.WriteInt(s, 0); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); Helpers.WriteInt(s, 0); Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8); foreach (int i in NodeList) { Helpers.WriteInt(s, i); } foreach (StringID sid in StringList) { Helpers.WriteInt(s, (int)sid.ID); Helpers.WriteInt(s, (int)sid.offset); } foreach (int i in BitStream) { Helpers.WriteInt(s, i); } }
public void Generate() { long[] weights = new long[256]; foreach (STR line in talk.Strings) { weights[0]++; //string terminator for line foreach (char c in line.Value) weights[(byte)c]++; } Dictionary<char, long> weighttable = new Dictionary<char, long>(); for (int i = 0; i < 256; i++) if (weights[i] > 0) weighttable.Add((char)i, weights[i]); List<HuffNode> nodes = new List<HuffNode>(); foreach (KeyValuePair<char, long> w in weighttable) nodes.Add(new HuffNode(w.Key, w.Value)); while (nodes.Count > 1) { bool run = true; while (run) { run = false; for (int i = 0; i < nodes.Count - 1; i++) if (nodes[i].w > nodes[i + 1].w) { run = true; HuffNode t = nodes[i]; nodes[i] = nodes[i + 1]; nodes[i + 1] = t; } } HuffNode e0 = nodes[0]; HuffNode e1 = nodes[1]; HuffNode combine = new HuffNode(' ', e0.w + e1.w); combine.e0 = e0; combine.e1 = e1; nodes.RemoveAt(1); nodes.RemoveAt(0); nodes.Add(combine); } treeView2.Nodes.Clear(); HuffNode h = nodes[0]; TreeNode root = new TreeNode("root (generated from weights)"); root = GenTree(root, h); treeView2.Nodes.Add(root); NodeList = new List<int>(); while (!h.hasIndex) CalcIndex(h); listBox5.Items.Clear(); int count = 0; foreach (int i in NodeList) listBox5.Items.Add((count++) + " : " + i.ToString("X4")); TreeNode root2 = new TreeNode("root (generated from flattening)"); root2 = MakeTree2(root2, NodeList.Count / 2 - 1); root2.ExpandAll(); treeView2.Nodes.Add(root2); AlphaEntry[] alphabet = GetAlphabet(h, new List<bool>()); listBox6.Items.Clear(); foreach (AlphaEntry a in alphabet) { StringBuilder sb = new StringBuilder(); sb.Append("'"); if ((byte)a.c != 0) sb.Append(a.c); else sb.Append("/0"); sb.Append("' = "); foreach (bool b in a.list) if (b) sb.Append("1"); else sb.Append("0"); listBox6.Items.Add(sb.ToString()); } BitStream = new List<uint>(); StringList = new List<StringID>(); uint curr = 0; uint index = 0; byte shift = 0; foreach (STR str in talk.Strings) { StringID t = new StringID(); t.ID = str.ID; t.offset = index << 5; t.offset += shift; string s = str.Value + "\0"; foreach (char c in s) { AlphaEntry alpha = null; foreach (AlphaEntry a in alphabet) if ((byte)a.c == (byte)c) alpha = a; foreach (bool step in alpha.list) { byte b = 0; if (step) b = 1; if (shift < 32) { curr += (uint)(b << shift); shift++; } if (shift == 32) { BitStream.Add(curr); index++; shift = 0; curr = 0; } } } StringList.Add(t); } BitStream.Add(curr); listBox7.Items.Clear(); listBox8.Items.Clear(); count = 0; for (int i = 0; i < StringList.Count; i++) listBox7.Items.Add((count++).ToString("d4") + ". ID : 0x" + (StringList[i].ID).ToString("X8") + " Offset : 0x" + StringList[i].offset.ToString("X8")); count = 0; foreach (uint u in BitStream) listBox8.Items.Add((count++).ToString("d4") + ". : " + uint2String(u)); }
HuffNode BuildHuffTree() { Dictionary <byte, int> frequency = new Dictionary <byte, int>(); foreach (byte i in src) { if (!frequency.ContainsKey(i)) { frequency.Add(i, 0); } frequency[i]++; } var tmp = from t in frequency where true orderby t.Value select t.Key; List <byte> ordered = tmp.ToList(); List <HuffNode> nodes = new List <HuffNode>(); HuffNode one; HuffNode zero; HuffNode root; int index = 0; while (index < ordered.Count) { var tmp2 = from t in nodes where t.top && (t.frequency < frequency[ordered[index]] || t.frequency < frequency[ordered[index + 1]]) orderby t.frequency select t; List <HuffNode> finished = tmp2.ToList(); int rest = 2 - finished.Count; for (int i = 0; i < rest; i++) { HuffNode node = new HuffNode(); node.content = ordered[index++]; node.frequency = frequency[node.content]; node.top = true; nodes.Add(node); finished.Add(node); } zero = finished[0]; one = finished[1]; HuffNode top = new HuffNode(); top.zero = zero; top.one = one; top.top = true; top.CalcFreq(); zero.top = false; one.top = false; nodes.Add(top); } { root = nodes[nodes.Count - 1]; if (root.frequency == src.Length) { List <HuffNode> opend = new List <HuffNode>(); opend.Add(root); while (opend.Count > 0) { HuffNode node = opend[0]; opend.Remove(node); if (node.zero != null) { node.zero.bits = (byte)(node.bits + 1); node.zero.code = (int)(node.code | (0 << node.zero.bits)); opend.Add(node.zero); } if (node.one != null) { node.one.bits = (byte)(node.bits + 1); node.one.code = (int)(node.code | ((1 << (node.one.bits - 1)))); opend.Add(node.one); } } return(root); } } return(null); }
//private void Swap(ref HuffmanTree l, ref HuffmanTree r) //{ // HuffmanTree temp = l; // l = r; // r = temp; //} public int Compare(HuffNode l, HuffNode r) { return(l.weight.CompareTo(r.weight)); }
HuffNode BuildHuffTree() { Dictionary<byte, int> frequency = new Dictionary<byte, int>(); foreach (byte i in src) { if (!frequency.ContainsKey(i)) frequency.Add(i, 0); frequency[i]++; } var tmp = from t in frequency where true orderby t.Value select t.Key; List<byte> ordered = tmp.ToList(); List<HuffNode> nodes = new List<HuffNode>(); HuffNode one; HuffNode zero; HuffNode root; int index = 0; while (index < ordered.Count) { var tmp2 = from t in nodes where t.top && (t.frequency < frequency[ordered[index]] || t.frequency < frequency[ordered[index + 1]]) orderby t.frequency select t; List<HuffNode> finished = tmp2.ToList(); int rest = 2 - finished.Count; for (int i = 0; i < rest; i++) { HuffNode node = new HuffNode(); node.content = ordered[index++]; node.frequency = frequency[node.content]; node.top = true; nodes.Add(node); finished.Add(node); } zero = finished[0]; one = finished[1]; HuffNode top = new HuffNode(); top.zero = zero; top.one = one; top.top = true; top.CalcFreq(); zero.top = false; one.top = false; nodes.Add(top); } { root = nodes[nodes.Count - 1]; if (root.frequency == src.Length) { List<HuffNode> opend = new List<HuffNode>(); opend.Add(root); while (opend.Count > 0) { HuffNode node = opend[0]; opend.Remove(node); if (node.zero != null) { node.zero.bits = (byte)(node.bits + 1); node.zero.code = (int)(node.code | (0 << node.zero.bits)); opend.Add(node.zero); } if (node.one != null) { node.one.bits = (byte)(node.bits + 1); node.one.code = (int)(node.code | ((1 << (node.one.bits - 1)))); opend.Add(node.one); } } return root; } } return null; }
void WriteHuffTree(HuffNode root, System.IO.Stream stream) { if (root.zero != null) { WriteBits(1, 1, stream); WriteHuffTree(root.zero, stream); if (root.one != null) { WriteHuffTree(root.one, stream); } else throw new Exception(); } else { if (root.one == null) { WriteBits(0, 1, stream); WriteBits(root.content, 8, stream); } else throw new Exception(); } }
void WriteContent(HuffNode root,System.IO.Stream stream) { foreach (byte i in src) { int code; int bits; EncodeByte(root, i, out code, out bits); WriteBits(code, bits, stream, false); } }