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(); }
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 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); } }