Example #1
0
            public int getChar(BitStream s)
            {
                HuffNode n = root;
                long     bit;
                int      ch;

                // find the leaf node:
                while (n.character == innode)
                {
                    bit = s.ReadBits(1);
                    n   = ((bit & 1) != 0) ? n.right : n.left;
                }

                if (n.character == NYT)
                {
                    // if the leaf is NYT, read the next character:
                    ch = (int)s.ReadBits(codeSize);
                    splitNYT(ch);
                    n = leaves[ch].parent;
                }
                else
                {
                    ch = n.character;
                }

                // update the tree:
                rearrangeTree(n);

                return(ch);
            }
Example #2
0
            private void splitNYT(int character)
            {
                HuffNode n1, n2;

                n1 = new HuffNode(NYT);
                n2 = new HuffNode(character);
                leaves[NYT].character = innode;
                leaves[NYT].freq      = 1;

                // siblings:
                n1.next          = n2;
                n2.next          = leaves[NYT];
                n2.prev          = n1;
                leaves[NYT].prev = n2;

                // tree links:
                n1.parent         = leaves[NYT];
                n2.parent         = leaves[NYT];
                leaves[NYT].left  = n1;
                leaves[NYT].right = n2;

                // update leaf node:
                leaves[NYT]       = n1;
                leaves[character] = n2;
            }
Example #3
0
            public void init(int maxSymbol)
            {
                if (wordCount != maxSymbol + 2)
                {
                    wordCount = maxSymbol + 2; // including NYT
                    NYT       = maxSymbol + 1;
                    innode    = maxSymbol + 2;

                    // compute code-word size:
                    codeSize = 1;
                    int size = 2;
                    while (size < NYT)
                    {
                        size += size;
                        codeSize++;
                    }

                    // array of leaves:
                    leaves = new HuffNode[wordCount];
                }
                else
                {
                    for (int i = 0; i < wordCount;)
                    {
                        leaves[i] = null;
                    }
                }

                // root item:
                root        = new HuffNode(NYT);
                leaves[NYT] = root;
            }
Example #4
0
            private void writeCode(HuffNode node, BitStream s)
            {
                if (node == root)
                {
                    return;
                }

                writeCode(node.parent, s);
                s.WriteBits((node.parent.left == node) ? 0 : 1, 1);
            }
Example #5
0
 private void rearrangeTree(HuffNode node)
 {
     while (node != root)
     {
         node = swapLast(node);
         node.freq++;
         node = node.parent;
     }
     node.freq++;
 }
Example #6
0
            private void printTreeInner(HuffNode node)
            {
                if (node == null)
                {
                    return;
                }

                printTreeInner(node.left);
                printTreeInner(node.right);
            }
        /// <summary>
        /// Builds tree.
        /// </summary>
        /// <param name="source"></param>
        public void Build(byte[] source)
        {
            Frequencies = new Dictionary <byte, int>();
            for (int i = 0; i < source.Length; i++)
            {
                if (!Frequencies.ContainsKey(source[i]))
                {
                    //table.Add(source[i], 0);
                    Frequencies.Add(source[i], 0);
                    //ary.Add(new KeyValuePair<byte, int>(source[i],0));
                }
                Frequencies[source[i]]++;
                //int temp = ary.ElementAt(i).Value;
                //ary.RemoveAt(i);
                //ary.Insert(i, new KeyValuePair<byte, int>(source[i],++temp));
                //int temp = (int)table[source[i]];
                //table.Remove(source[i]);
                //table.Add(source[i], +temp);
            }

            foreach (KeyValuePair <byte, int> symbol in Frequencies)
            {
                nodes.Add(new HuffNode()
                {
                    Symbol = symbol.Key, Frequency = symbol.Value
                });
            }

            while (nodes.Count > 1)
            {
                List <HuffNode> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList <HuffNode>();

                if (orderedNodes.Count >= 2)
                {
                    // Take first two items
                    List <HuffNode> taken = orderedNodes.Take(2).ToList <HuffNode>();

                    // Create a parent node by combining the frequencies
                    HuffNode parent = new HuffNode()
                    {
                        Symbol    = (byte)'*',
                        Frequency = taken[0].Frequency + taken[1].Frequency,
                        Left      = taken[0],
                        Right     = taken[1]
                    };

                    nodes.Remove(taken[0]);
                    nodes.Remove(taken[1]);
                    nodes.Add(parent);
                }

                this.Root = nodes.FirstOrDefault();
            }
        }
        public byte[] Decode(BitArray bits)
        {
            int[] size = { 0 };
            ExtractFront(bits, sizeof(int) * 8).CopyTo(size, 0);
            bits = ExtractEnd(bits, bits.Length - sizeof(int) * 8);//bits is bits - size
            MemoryStream ms = new MemoryStream();

            Frequencies = new Dictionary <byte, int>();
            for (int i = 0; i < size[0]; i++)
            {
                BitArray freq = ExtractFront(bits, sizeof(byte) * 8);//
                byte[]   key  = { 0 };
                freq.CopyTo(key, 0);
                bits = ExtractEnd(bits, bits.Length - sizeof(byte) * 8);
                freq = ExtractFront(bits, sizeof(int) * 8);
                int[] value = { 0 };
                freq.CopyTo(value, 0);
                bits = ExtractEnd(bits, bits.Length - sizeof(int) * 8);
                Frequencies.Add(key[0], value[0]);
            }

            Build();
            //Frequencies = (Dictionary<byte, int>)bs.Deserialize(ms);
            HuffNode    current = this.Root;
            List <byte> decoded = new List <byte>();

            foreach (bool bit in bits)
            {
                if (bit)
                {
                    if (current.Right != null)
                    {
                        current = current.Right;
                    }
                }
                else
                {
                    if (current.Left != null)
                    {
                        current = current.Left;
                    }
                }

                if (IsLeaf(current))
                {
                    decoded.Add(current.Symbol);
                    current = this.Root;
                }
            }

            return(decoded.ToArray());
        }
        /// <summary>
        /// Builds tree with already constructed frequencies table.
        /// </summary>
        public void Build()
        {
            foreach (KeyValuePair <byte, int> symbol in Frequencies)
            {
                nodes.Add(new HuffNode()
                {
                    Symbol    = symbol.Key,
                    Frequency = symbol.Value
                });
            }

            while (nodes.Count > 1)
            {
                List <HuffNode> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList <HuffNode>();

                if (orderedNodes.Count >= 2)
                {
                    // Take first two items
                    List <HuffNode> taken = orderedNodes.Take(2).ToList <HuffNode>();

                    // Create a parent node by combining the frequencies
                    HuffNode parent = new HuffNode()
                    {
                        Symbol    = (byte)'*',
                        Frequency = taken[0].Frequency + taken[1].Frequency,
                        Left      = taken[0],
                        Right     = taken[1]
                    };

                    nodes.Remove(taken[0]);
                    nodes.Remove(taken[1]);
                    nodes.Add(parent);
                }

                this.Root = nodes.FirstOrDefault();
            }
        }
Example #10
0
 /// <summary>
 /// Check if node is a leaf node.
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public bool IsLeaf(HuffNode node)
 {
     return(node.Left == null && node.Right == null);
 }
Example #11
0
            private HuffNode swapLast(HuffNode node)
            {
                HuffNode n;

                // find the last node with the same frequency..
                n = node;
                while (n.next != null &&
                       n.next != root &&
                       n.next.freq == node.freq)
                {
                    n = n.next;
                }

                // it's me and my parent => dont swap
                if (n == node)
                {
                    return(node);
                }

                // swap data:
                int d = node.character;

                node.character = n.character;
                n.character    = d;
                long f = node.freq;

                node.freq = n.freq;
                n.freq    = f;

                // swap children:
                HuffNode h;

                h          = node.left;
                node.left  = n.left;
                n.left     = h;
                h          = node.right;
                node.right = n.right;
                n.right    = h;
                if (node.character == innode)
                {
                    node.left.parent  = node;
                    node.right.parent = node;
                }
                if (n.character == innode)
                {
                    n.left.parent  = n;
                    n.right.parent = n;
                }

                // update list of leaves:
                if (node.character != innode)
                {
                    leaves[node.character] = node;
                }
                if (n.character != innode)
                {
                    leaves[n.character] = n;
                }

                return(n);
            }