예제 #1
0
 private bool TallyTree(int dist, int lc)
 {
     this.pendingBuffer[this.d_buf + this.lastLit * 2]     = (byte)Utils.ShiftRight(dist, 8);
     this.pendingBuffer[this.d_buf + this.lastLit * 2 + 1] = (byte)dist;
     this.pendingBuffer[this.litBuf + this.lastLit]        = (byte)lc;
     ++this.lastLit;
     if (dist == 0)
     {
         ++this.dyn_ltree[lc * 2];
     }
     else
     {
         ++this.matches;
         --dist;
         ++this.dyn_ltree[((int)TreeConstants.LengthCode[lc] + 256 + 1) * 2];
         ++this.dyn_dtree[CompressionTree.GetDistanceCode(dist) * 2];
     }
     if ((this.lastLit & 8191) == 0 && this.level > 2)
     {
         int number = this.lastLit * 8;
         int num1   = this.strstart - this.blockStart;
         for (int index = 0; index < 30; ++index)
         {
             number = (int)((long)number + (long)this.dyn_dtree[index * 2] * (5L + (long)TreeConstants.ExtraDBits[index]));
         }
         int num2 = Utils.ShiftRight(number, 3);
         if (this.matches < this.lastLit / 2 && num2 < num1 / 2)
         {
             return(true);
         }
     }
     return(this.lastLit == this.litBufsize - 1);
 }
예제 #2
0
        private static void GenerateCodes(short[] tree, int maxCode, short[] blCount)
        {
            short[] numArray = new short[16];
            short   num      = 0;

            for (int index = 1; index <= 15; ++index)
            {
                numArray[index] = num = (short)((int)num + (int)blCount[index - 1] << 1);
            }
            for (int index = 0; index <= maxCode; ++index)
            {
                int len = (int)tree[index * 2 + 1];
                if (len != 0)
                {
                    tree[index * 2] = (short)CompressionTree.ReverseBits((int)numArray[len]++, len);
                }
            }
        }
예제 #3
0
        private void CompressBlock(short[] ltree, short[] dtree)
        {
            int num1 = 0;

            if (this.lastLit != 0)
            {
                do
                {
                    int num2 = (int)this.pendingBuffer[this.d_buf + num1 * 2] << 8 & 65280 | (int)this.pendingBuffer[this.d_buf + num1 * 2 + 1] & (int)byte.MaxValue;
                    int c    = (int)this.pendingBuffer[this.litBuf + num1] & (int)byte.MaxValue;
                    ++num1;
                    if (num2 == 0)
                    {
                        this.SendCode(c, ltree);
                    }
                    else
                    {
                        int index = (int)TreeConstants.LengthCode[c];
                        this.SendCode(index + 256 + 1, ltree);
                        int extraLbit = TreeConstants.ExtraLBits[index];
                        if (extraLbit != 0)
                        {
                            this.SendBits(c - TreeConstants.BaseLength[index], extraLbit);
                        }
                        int distance     = num2 - 1;
                        int distanceCode = CompressionTree.GetDistanceCode(distance);
                        this.SendCode(distanceCode, dtree);
                        int extraDbit = TreeConstants.ExtraDBits[distanceCode];
                        if (extraDbit != 0)
                        {
                            this.SendBits(distance - TreeConstants.BaseDistance[distanceCode], extraDbit);
                        }
                    }
                }while (num1 < this.lastLit);
            }
            this.SendCode(256, ltree);
            this.last_eob_len = (int)ltree[513];
        }
예제 #4
0
        public void BuildTree(Deflater deflater)
        {
            short[] dynamicTree    = this.dynamicTree;
            short[] staticTreeData = this.staticTree.StaticTreeData;
            int     maxElements    = this.staticTree.MaxElements;
            int     maxCode        = -1;

            deflater.heapLen = 0;
            deflater.heapMax = TreeConstants.HeapSize;
            for (int index = 0; index < maxElements; ++index)
            {
                if (dynamicTree[index * 2] != (short)0)
                {
                    deflater.heap[++deflater.heapLen] = maxCode = index;
                    deflater.depth[index]             = (byte)0;
                }
                else
                {
                    dynamicTree[index * 2 + 1] = (short)0;
                }
            }
            while (deflater.heapLen < 2)
            {
                int[] heap   = deflater.heap;
                int   index1 = ++deflater.heapLen;
                int   num1;
                if (maxCode >= 2)
                {
                    num1 = 0;
                }
                else
                {
                    maxCode = num1 = maxCode + 1;
                }
                int num2 = num1;
                heap[index1] = num1;
                int index2 = num2;
                dynamicTree[index2 * 2] = (short)1;
                deflater.depth[index2]  = (byte)0;
                --deflater.opt_len;
                if (staticTreeData != null)
                {
                    deflater.static_len -= (int)staticTreeData[index2 * 2 + 1];
                }
            }
            this.maxCode = maxCode;
            for (int k = deflater.heapLen / 2; k >= 1; --k)
            {
                deflater.RestoreHeapDown(dynamicTree, k);
            }
            int index3 = maxElements;

            do
            {
                int index1 = deflater.heap[1];
                deflater.heap[1] = deflater.heap[deflater.heapLen--];
                deflater.RestoreHeapDown(dynamicTree, 1);
                int index2 = deflater.heap[1];
                deflater.heap[--deflater.heapMax] = index1;
                deflater.heap[--deflater.heapMax] = index2;
                dynamicTree[index3 * 2]           = (short)((int)dynamicTree[index1 * 2] + (int)dynamicTree[index2 * 2]);
                deflater.depth[index3]            = (byte)((uint)Math.Max(deflater.depth[index1], deflater.depth[index2]) + 1U);
                dynamicTree[index1 * 2 + 1]       = dynamicTree[index2 * 2 + 1] = (short)index3;
                deflater.heap[1] = index3++;
                deflater.RestoreHeapDown(dynamicTree, 1);
            }while (deflater.heapLen >= 2);
            deflater.heap[--deflater.heapMax] = deflater.heap[1];
            this.GenerateBitLengths(deflater);
            CompressionTree.GenerateCodes(dynamicTree, maxCode, deflater.bl_count);
        }