public void CalcBLFreq(CompressorHuffmanTree blTree)
        {
            int max_count;
            int min_count;
            int count;
            int curlen = -1;

            int i = 0;
            while (i < m_CodeCount)
            {
                count = 1;
                int nextlen = m_CodeLengths[i];
                if (nextlen == 0)
                {
                    max_count = 138;
                    min_count = 3;
                }
                else
                {
                    max_count = 6;
                    min_count = 3;
                    if (curlen != nextlen)
                    {
                        blTree.m_CodeFrequences[nextlen]++;
                        count = 0;
                    }
                }
                curlen = nextlen;
                i++;

                while (i < m_CodeCount && curlen == m_CodeLengths[i])
                {
                    i++;
                    if (++count >= max_count)
                    {
                        break;
                    }
                }

                if (count < min_count)
                {
                    blTree.m_CodeFrequences[curlen] += (short)count;
                }
                else if (curlen != 0)
                {
                    blTree.m_CodeFrequences[16]++;
                }
                else if (count <= 10)
                {
                    blTree.m_CodeFrequences[17]++;
                }
                else
                {
                    blTree.m_CodeFrequences[18]++;
                }
            }
        }
        public void WriteTree(CompressorHuffmanTree blTree)
        {
            int iMaxRepeatCount;
            int iMinRepeatCount;
            int iCurrentRepeatCount;
            int iCurrentCodeLength = -1;

            int i = 0;
            while (i < m_CodeCount)
            {
                iCurrentRepeatCount = 1;
                int nextlen = m_CodeLengths[i];

                if (nextlen == 0)
                {
                    iMaxRepeatCount = 138;
                    iMinRepeatCount = 3;
                }
                else
                {
                    iMaxRepeatCount = 6;
                    iMinRepeatCount = 3;

                    if (iCurrentCodeLength != nextlen)
                    {
                        blTree.WriteCodeToStream(nextlen);
                        iCurrentRepeatCount = 0;
                    }
                }

                iCurrentCodeLength = nextlen;
                i++;

                while (i < m_CodeCount && iCurrentCodeLength == m_CodeLengths[i])
                {
                    i++;

                    if (++iCurrentRepeatCount >= iMaxRepeatCount)
                    {
                        break;
                    }
                }

                if (iCurrentRepeatCount < iMinRepeatCount)
                {
                    while (iCurrentRepeatCount-- > 0)
                    {
                        blTree.WriteCodeToStream(iCurrentCodeLength);
                    }
                }
                else if (iCurrentCodeLength != 0)
                {
                    blTree.WriteCodeToStream(16);
                    m_Writer.PendingBufferWriteBits(iCurrentRepeatCount - 3, 2);
                }
                else if (iCurrentRepeatCount <= 10)
                {
                    blTree.WriteCodeToStream(17);
                    m_Writer.PendingBufferWriteBits(iCurrentRepeatCount - 3, 3);
                }
                else
                {
                    blTree.WriteCodeToStream(18);
                    m_Writer.PendingBufferWriteBits(iCurrentRepeatCount - 11, 7);
                }
            }
        }
        public CompressedStreamWriter(Stream outputStream, bool bNoWrap, CompressionLevel level, bool bCloseStream)
        {
            if (outputStream == null)
                throw new ArgumentNullException("outputStream");

            if (!outputStream.CanWrite)
                throw new ArgumentException("Output stream does not support writing.", "outputStream");

            m_treeLiteral = new CompressorHuffmanTree(this, DEF_HUFFMAN_LITERAL_ALPHABET_LENGTH, 257, 15);
            m_treeDistances = new CompressorHuffmanTree(this, DEF_HUFFMAN_DISTANCES_ALPHABET_LENGTH, 1, 15);
            m_treeCodeLengths = new CompressorHuffmanTree(this, DEF_HUFFMAN_BITLEN_TREE_LENGTH, 4, 7);

            m_arrDistancesBuffer = new short[DEF_HUFFMAN_BUFFER_SIZE];
            m_arrLiteralsBuffer = new byte[DEF_HUFFMAN_BUFFER_SIZE];

            m_stream = outputStream;
            m_Level = level;
            m_bNoWrap = bNoWrap;
            m_bCloseStream = bCloseStream;

            m_DataWindow = new byte[2 * WSIZE];
            m_HashHead = new short[HASH_SIZE];
            m_HashPrevious = new short[WSIZE];
            m_BlockStart = m_StringStart = 1;

            m_GoodLength = GOOD_LENGTH[(int)level];
            m_MaximumLazySearch = MAX_LAZY[(int)level];
            m_NiceLength = NICE_LENGTH[(int)level];
            m_MaximumChainLength = MAX_CHAIN[(int)level];
            m_CompressionFunction = COMPR_FUNC[(int)level];

            if (!bNoWrap)
            {
                WriteZLIBHeader();
            }
        }