Exemple #1
0
        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());
        }
Exemple #2
0
 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();
 }
Exemple #3
0
        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);
            }
        }