コード例 #1
0
        // 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();
        }
コード例 #2
0
 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);
         }
     }
 }
コード例 #3
0
        // 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);
        }
コード例 #4
0
 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();
         }
     }
 }
コード例 #5
0
        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;
        }
コード例 #6
0
 public HuffNode(char chr, long weight)
 {
     e0       = e1 = null;
     c        = chr;
     w        = weight;
     hasIndex = false;
 }
コード例 #7
0
ファイル: Talktable.cs プロジェクト: tirnoney/DAIToolsWV
 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);
         }
     }
 }
コード例 #8
0
 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);
     }
 }
コード例 #9
0
ファイル: CptCompressor.cs プロジェクト: mmyydd/reko
        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);
        }
コード例 #10
0
        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;
        }
コード例 #11
0
        //生成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]));
        }
コード例 #12
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);
     }
 }
コード例 #13
0
        //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);
            }
        }
コード例 #14
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());
        }
コード例 #15
0
ファイル: Talktable.cs プロジェクト: tirnoney/DAIToolsWV
 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();
 }
コード例 #16
0
        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);
        }
コード例 #17
0
        // 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);
        }
コード例 #18
0
 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);
 }
コード例 #19
0
ファイル: Talktable.cs プロジェクト: tirnoney/DAIToolsWV
 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);
 }
コード例 #20
0
 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;
 }
コード例 #21
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));
            }
        }
コード例 #22
0
ファイル: TalktableTool.cs プロジェクト: tirnoney/DAIToolsWV
 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;
 }
コード例 #23
0
ファイル: CptCompressor.cs プロジェクト: gitter-badger/reko
        /* 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;
        }
コード例 #24
0
ファイル: CptCompressor.cs プロジェクト: gitter-badger/reko
        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;
        }
コード例 #25
0
ファイル: CptCompressor.cs プロジェクト: mmyydd/reko
        /* 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;
        }
コード例 #26
0
ファイル: TalktableTool.cs プロジェクト: tirnoney/DAIToolsWV
 public HuffNode(char chr, long weight)
 {
     e0 = e1 = null;
     c = chr;
     w = weight;
     hasIndex = false;
 }
コード例 #27
0
        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);
            }
        }
コード例 #28
0
ファイル: TalktableTool.cs プロジェクト: tirnoney/DAIToolsWV
        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));
        }
コード例 #29
0
        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);
        }
コード例 #30
0
        //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));
        }
コード例 #31
0
 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;
 }
コード例 #32
0
 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();
     }
 }
コード例 #33
0
 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);
     }
 }