示例#1
0
        public override bool Equals(object ob)
        {
            if (!(ob is HuffmanTableNode))
            {
                return(false);
            }

            HuffmanTableNode Node2 = ob as HuffmanTableNode;

            if (m_len != Node2.m_len)
            {
                return(false);
            }

            bool result = true;

            for (int i = 0; i < m_Size; i++)
            {
                if (m_Code[i] != Node2.m_Code[i])
                {
                    result = false;
                    break;
                }
            }

            return(result);
        }
示例#2
0
        static void EncodeArray(ref byte[] pBufIn, out byte[] pBufOut)
        {
            int lenIn  = pBufIn.Length;
            int lenOut = 0;

            if (lenIn <= 1024)
            {
                Store(ref pBufIn, lenIn, out pBufOut, out lenOut);
                return;
            }

            HistogramNode[] pHN = null;
            int             lHOut;
            int             offset = 0;
            int             nHuffmanTableSize;

            // 1 === create histogram ===
            GetHistogram(ref pBufIn, lenIn, out pHN, out lHOut);
            // ==========================

            // 1.1 === there is only 1 (one) value ===
            if (lHOut == 1)
            {
                lenOut = 0;

                lenOut++;              // compress or uncompress
                lenOut += sizeof(int); // lenght of huffman table
                lenOut += sizeof(int); // uncompressed size
                lenOut++;              // value

                pBufOut = new byte[lenOut];
                byte Value = pHN[0].Value;

                nHuffmanTableSize = 1;

                pBufOut[0] = 1; offset++;
                byte[] ar1 = BitConverter.GetBytes(nHuffmanTableSize);
                byte[] ar2 = BitConverter.GetBytes(lenIn);

                ar1.CopyTo(pBufOut, offset); offset += sizeof(int);
                ar2.CopyTo(pBufOut, offset); offset += sizeof(int);

                pBufOut[offset] = Value;

                return;
            }
            // ========================================

            // 2 === create zero level of tree ===
            List <CHNode> arCHZeroLevel = new List <CHNode>();
            int           i;

            for (i = 0; i < lHOut; i++)
            {
                arCHZeroLevel.Add(new CHNode(pHN[i].Value, pHN[i].Frequency));
            }
            // ===================================

            // 3 === create tree ===
            List <CHNode> arCHTree = new List <CHNode>(arCHZeroLevel);
            int           lCur     = lHOut;
            int           nTreeSize;

            while (lCur > 1)
            {
                int    index1 = 0;
                int    index2 = 0;
                CHNode pHuffman;
                int    min = 0xFFFFFFF;
                nTreeSize = arCHTree.Count;

                for (i = 0; i < nTreeSize; i++)
                {
                    pHuffman = arCHTree[i];

                    if (pHuffman.Mark)
                    {
                        continue;
                    }

                    if (pHuffman.Weight < min)
                    {
                        index1 = i;
                        min    = pHuffman.Weight;
                    }
                }

                min = 0xFFFFFFF;

                for (i = 0; i < nTreeSize; i++)
                {
                    pHuffman = arCHTree[i];

                    if (pHuffman.Mark)
                    {
                        continue;
                    }

                    if (i == index1)
                    {
                        continue;
                    }

                    if (pHuffman.Weight < min)
                    {
                        index2 = i;
                        min    = pHuffman.Weight;
                    }
                }

                CHNode p1        = arCHTree[index1];
                CHNode p2        = arCHTree[index2];
                CHNode pNewNode  = new CHNode();
                CHNode emptyNode = null;

                pNewNode.Weight = p1.Weight + p2.Weight;
                pNewNode.SetLeft(ref p1);
                pNewNode.SetRight(ref p2);
                pNewNode.SetRoot(ref emptyNode);

                arCHTree.Add(pNewNode);

                p1.SetRoot(ref pNewNode);
                p1.SetLeftType();
                p1.Mark = true;

                p2.SetRoot(ref pNewNode);
                p2.SetRightType();
                p2.Mark = true;

                lCur--;
            }
            // =====================================

            // 4 === compute size for compressed data ===
            int nCompressedDataSize = 0;

            nHuffmanTableSize = 0;
            HuffmanTableNode[] pHuffmanNode = new HuffmanTableNode[arCHZeroLevel.Count];

            for (i = 0; i < arCHZeroLevel.Count; i++)
            {
                pHuffmanNode[i] = new HuffmanTableNode();
            }

            for (i = 0; i < arCHZeroLevel.Count; i++)
            {
                CHNode pNode = arCHZeroLevel[i];

                while (pNode.GetRoot() != null)
                {
                    if (pNode.IsRightType)
                    {
                        pHuffmanNode[i].AddBitOne(); // 1
                    }
                    else
                    {
                        pHuffmanNode[i].AddBitZero(); // 0
                    }

                    pNode = pNode.GetRoot();
                }

                pNode = arCHZeroLevel[i];
                pHuffmanNode[i].Value = pNode.Value;
                pHuffmanNode[i].Invert();

                nCompressedDataSize += (pHuffmanNode[i].Len * pNode.Weight); // measured in bits
            }

            if (nCompressedDataSize % 8 == 0)
            {
                nCompressedDataSize /= 8; // measured in bytes
            }
            else
            {
                nCompressedDataSize = nCompressedDataSize / 8 + 1; // measured in bytes
            }
            // ==========================================

            // 5 === compute total memory ===
            lenOut = 0;

            lenOut++;                             // compress or uncompress
            lenOut += sizeof(int);                // lenght of huffman table
            lenOut += lHOut * HistogramNode.Size; // histogram size
            lenOut += sizeof(int);                // uncompressed size
            lenOut += nCompressedDataSize;
            // ==============================

            // 6 === Check for total size ===
            if (lenOut > lenIn)
            {
                Store(ref pBufIn, lenIn, out pBufOut, out lenOut);
                return;
            }
            // ================================

            // 7 === Encoding ===
            pBufOut = new byte[lenOut];
            byte[] p = pBufOut;
            Array.Clear(p, 0, p.Length);

            offset = 0;
            int  index, j;
            int  nBits = 8;
            byte Code, CodeForWriting;
            int  CodeLen;
            int  nZeroLevel = arCHZeroLevel.Count;

            byte[] arInt = null;

            p[0]  = 1; offset++;
            arInt = BitConverter.GetBytes(nZeroLevel);
            arInt.CopyTo(p, offset); offset += sizeof(int);

            // === store histogram ===
            for (i = 0; i < nZeroLevel; i++)
            {
                offset = pHN[i].ToArray(ref p, offset);
            }
            // ======================

            arInt = BitConverter.GetBytes(lenIn);
            arInt.CopyTo(p, offset);
            offset += sizeof(int);

            byte[] pIndex = new byte[256];

            for (i = 0; i < 256; i++)
            {
                for (j = 0; j < nZeroLevel; j++)
                {
                    if (i == pHuffmanNode[j].Value)
                    {
                        pIndex[i] = Convert.ToByte(j);
                        break;
                    }
                }
            }

            for (i = 0; i < lenIn; i++)
            {
                index   = pIndex[pBufIn[i]];
                CodeLen = pHuffmanNode[index].Len;

                for (j = 0; j < CodeLen; j++)
                {
                    if (nBits == 0)
                    {
                        nBits = 8;
                        offset++;
                    }

                    Code           = pHuffmanNode[index].GetBit(j);
                    CodeForWriting = Convert.ToByte(Code << (nBits - 1));
                    p[offset]     |= CodeForWriting;

                    nBits--;
                }
            }
        }