Deflate() 공개 메소드

Deflate drives actual compression of data
public Deflate ( bool flush, bool finish ) : bool
flush bool True to flush input buffers
finish bool Finish deflation with the current input.
리턴 bool
예제 #1
0
파일: Deflater.cs 프로젝트: zzwwqqq/mono
        /// <summary>
        /// Deflates the current input block to the given array.  It returns
        /// the number of bytes compressed, or 0 if either
        /// needsInput() or finished() returns true or length is zero.
        /// </summary>
        /// <param name="output">
        /// the buffer where to write the compressed data.
        /// </param>
        /// <param name="offset">
        /// the offset into the output array.
        /// </param>
        /// <param name="length">
        /// the maximum number of bytes that may be written.
        /// </param>
        /// <exception cref="System.InvalidOperationException">
        /// if end() was called.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// if offset and/or length don't match the array length.
        /// </exception>
        public int Deflate(byte[] output, int offset, int length)
        {
            int origLength = length;

            if (state == CLOSED_STATE)
            {
                throw new InvalidOperationException("Deflater closed");
            }

            if (state < BUSY_STATE)
            {
                /* output header */
                int header = (DEFLATED +
                              ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
                int level_flags = (level - 1) >> 1;
                if (level_flags < 0 || level_flags > 3)
                {
                    level_flags = 3;
                }
                header |= level_flags << 6;
                if ((state & IS_SETDICT) != 0)
                {
                    /* Dictionary was set */
                    header |= DeflaterConstants.PRESET_DICT;
                }
                header += 31 - (header % 31);


                pending.WriteShortMSB(header);
                if ((state & IS_SETDICT) != 0)
                {
                    int chksum = engine.Adler;
                    engine.ResetAdler();
                    pending.WriteShortMSB(chksum >> 16);
                    pending.WriteShortMSB(chksum & 0xffff);
                }

                state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
            }

            for (;;)
            {
                int count = pending.Flush(output, offset, length);
                offset   += count;
                totalOut += count;
                length   -= count;

                if (length == 0 || state == FINISHED_STATE)
                {
                    break;
                }

                if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0))
                {
                    if (state == BUSY_STATE)
                    {
                        /* We need more input now */
                        return(origLength - length);
                    }
                    else if (state == FLUSHING_STATE)
                    {
                        if (level != NO_COMPRESSION)
                        {
                            /* We have to supply some lookahead.  8 bit lookahead
                             * are needed by the zlib inflater, and we must fill
                             * the next byte, so that all bits are flushed.
                             */
                            int neededbits = 8 + ((-pending.BitCount) & 7);
                            while (neededbits > 0)
                            {
                                /* write a static tree block consisting solely of
                                 * an EOF:
                                 */
                                pending.WriteBits(2, 10);
                                neededbits -= 10;
                            }
                        }
                        state = BUSY_STATE;
                    }
                    else if (state == FINISHING_STATE)
                    {
                        pending.AlignToByte();
                        /* We have completed the stream */
                        if (!noHeader)
                        {
                            int adler = engine.Adler;
                            pending.WriteShortMSB(adler >> 16);
                            pending.WriteShortMSB(adler & 0xffff);
                        }
                        state = FINISHED_STATE;
                    }
                }
            }
            return(origLength - length);
        }
예제 #2
0
        public int Deflate(byte[] output, int offset, int length)
        {
            int num = length;

            if (state == 127)
            {
                throw new InvalidOperationException("Deflater closed");
            }
            if (state < 16)
            {
                int num2 = 30720;
                int num3 = level - 1 >> 1;
                if (num3 < 0 || num3 > 3)
                {
                    num3 = 3;
                }
                num2 |= num3 << 6;
                if ((state & 1) != 0)
                {
                    num2 |= 0x20;
                }
                num2 += 31 - num2 % 31;
                pending.WriteShortMSB(num2);
                if ((state & 1) != 0)
                {
                    int adler = engine.Adler;
                    engine.ResetAdler();
                    pending.WriteShortMSB(adler >> 16);
                    pending.WriteShortMSB(adler & 0xFFFF);
                }
                state = (0x10 | (state & 0xC));
            }
            while (true)
            {
                int num4 = pending.Flush(output, offset, length);
                offset   += num4;
                totalOut += num4;
                length   -= num4;
                if (length == 0 || state == 30)
                {
                    break;
                }
                if (engine.Deflate((state & 4) != 0, (state & 8) != 0))
                {
                    continue;
                }
                if (state == 16)
                {
                    return(num - length);
                }
                if (state == 20)
                {
                    if (level != 0)
                    {
                        for (int num5 = 8 + (-pending.BitCount & 7); num5 > 0; num5 -= 10)
                        {
                            pending.WriteBits(2, 10);
                        }
                    }
                    state = 16;
                }
                else if (state == 28)
                {
                    pending.AlignToByte();
                    if (!noZlibHeaderOrFooter)
                    {
                        int adler2 = engine.Adler;
                        pending.WriteShortMSB(adler2 >> 16);
                        pending.WriteShortMSB(adler2 & 0xFFFF);
                    }
                    state = 30;
                }
            }
            return(num - length);
        }