Beispiel #1
0
        static void GetHistogram(ref byte[] pBufIn, int lenIn, out HistogramNode[] pHN, out int lenOut)
        {
            int i;

            HistogramNode[] pHFull = new HistogramNode[256];

            for (i = 0; i < 256; i++)
            {
                pHFull[i] = new HistogramNode(Convert.ToByte(i));
            }

            for (i = 0; i < lenIn; i++)
            {
                pHFull[pBufIn[i]].Inc();
            }

            lenOut = pHFull.Count(x => x.Frequency > 0);
            pHN    = new HistogramNode[lenOut];

            for (i = 0; i < lenOut; i++)
            {
                pHN[i] = new HistogramNode();
            }

            int index = -1;

            for (i = 0; i < 256; i++)
            {
                if (pHFull[i].Frequency > 0)
                {
                    index++;
                    pHN[index].Value     = pHFull[i].Value;
                    pHN[index].Frequency = pHFull[i].Frequency;
                }
            }
        }
Beispiel #2
0
        static void DecodeArray(ref byte[] pBufIn, out byte[] pBufOut)
        {
            int lenIn  = pBufIn.Length;
            int lenOut = 0;
            int offset = 1;

            // 0 === check for compressed or uncompressed ===
            if (pBufIn[0] == 0)
            {
                lenOut  = BitConverter.ToInt32(pBufIn, offset); offset += sizeof(int);
                pBufOut = new byte[lenOut];
                Array.Copy(pBufIn, offset, pBufOut, 0, lenOut);

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

            // 1 === Get Huffman table ===
            int i;
            int nHaffmanTableSize = BitConverter.ToInt32(pBufIn, offset);

            offset += sizeof(int);

            if (nHaffmanTableSize == 1)
            {
                int uncompressed = BitConverter.ToInt32(pBufIn, offset);
                offset += sizeof(int);

                byte Value = pBufIn[offset];

                lenOut  = uncompressed;
                pBufOut = new byte[lenOut];

                for (i = 0; i < lenOut; i++)
                {
                    pBufOut[i] = Value;
                }

                return;
            }

            // === extract histogram ===
            HistogramNode[] pHN = new HistogramNode[nHaffmanTableSize];

            for (i = 0; i < nHaffmanTableSize; i++)
            {
                pHN[i] = new HistogramNode();
                offset = pHN[i].FromArray(ref pBufIn, offset);
            }
            // =========================

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

            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;
            CHNode        pRoot = null;

            while (lCur > 1)
            {
                int index1 = 0;
                int index2 = 0;

                CHNode emptyNode = null;
                CHNode pHaffman  = null;
                int    min       = 0xFFFFFFF;
                nTreeSize = arCHTree.Count;

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

                    if (pHaffman.Mark)
                    {
                        continue;
                    }

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

                min = 0xFFFFFFF;

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

                    if (pHaffman.Mark)
                    {
                        continue;
                    }

                    if (i == index1)
                    {
                        continue;
                    }

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

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

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

                arCHTree.Add(pNewNode);

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

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

                lCur--;
            }

            // === end: tree from encode ====

            // 2 == get output size ===
            lenOut  = BitConverter.ToInt32(pBufIn, offset); offset += sizeof(int);
            pBufOut = new byte[lenOut];
            Array.Clear(pBufOut, 0, lenOut);
            // ========================

            // 3 === decoding ===
            int    offsetOut = 0;
            int    nBits     = 8;
            byte   Digit;
            CHNode pHaffman1;

            while (offsetOut < lenOut)
            {
                pHaffman1 = pRoot;

                while (true)
                {
                    Digit = Convert.ToByte(pBufIn[offset] & (1 << (nBits - 1)));
                    Digit = Convert.ToByte(Digit >> (nBits - 1));
                    nBits--;

                    // === fast search huffman table index ===
                    pHaffman1 = (Digit == 0) ? pHaffman1.GetLeft() : pHaffman1.GetRight();
                    // =======================================

                    if (nBits == 0)
                    {
                        offset++;
                        nBits = 8;
                    }

                    if (pHaffman1.GetRight() == null)
                    {
                        break;
                    }
                }

                if (pHaffman1.GetRight() == null)
                {
                    pBufOut[offsetOut++] = pHaffman1.Value;
                }
                else
                {
                    break;
                }
            }
        }