コード例 #1
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateResetKeep(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state         = strm.state;
            strm.total_in = strm.total_out = state.total = 0;
            strm.msg      = null;
            if (state.wrap != 0)                    /* to support ill-conceived Java test suite */
            {
                strm.adler = (ulong)(state.wrap & 1);
            }
            state.mode           = inflate_mode.HEAD;
            state.last           = 0;
            state.havedict       = 0;
            state.dmax           = 32768U;
            state.head           = null;
            state.hold           = 0;
            state.bits           = 0;
            state.next           = 0;
            state.lencode_array  = state.codes;
            state.distcode_array = state.codes;
            state.lencode_index  = 0;
            state.distcode_index = 0;
            state.sane           = 1;
            state.back           = -1;
            //Tracev((stderr, "inflate: reset\n"));
            return(zlib.Z_OK);
        }
コード例 #2
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflatePrime(
            z_stream strm,
            int bits,
            int value)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if (bits < 0)
            {
                state.hold = 0;
                state.bits = 0;
                return(zlib.Z_OK);
            }
            if (bits > 16 || state.bits + (uint)bits > 32)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            value      &= (int)((1L << bits) - 1);
            state.hold += (uint)value << (int)state.bits;
            state.bits += (uint)bits;
            return(zlib.Z_OK);
        }
コード例 #3
0
ファイル: compress.cs プロジェクト: woiwoz/CASCHost
        //   The following utility functions are implemented on top of the
        // basic stream-oriented functions. To simplify the interface, some
        // default options are assumed (compression level and memory usage,
        // standard memory allocation functions). The source code of these
        // utility functions can easily be modified if you need special options.

        // ===========================================================================
        // Compresses the source buffer into the destination buffer. The level
        // parameter has the same meaning as in deflateInit.  sourceLen is the byte
        // length of the source buffer. Upon entry, destLen is the total size of the
        // destination buffer, which must be at least 0.1% larger than sourceLen plus
        // 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
        //
        // compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
        // memory, Z_BUF_ERROR if there was not enough room in the output buffer,
        // Z_STREAM_ERROR if the level parameter is invalid.

        public static int compress2(byte[] dest, ref uint destLen, byte[] source, uint sourceLen, int level)
        {
            z_stream stream = new z_stream()
            {
                next_in   = 0,
                in_buf    = source,
                avail_in  = sourceLen,
                next_out  = 0,
                out_buf   = dest,
                avail_out = destLen
            };

            if (stream.avail_out != destLen)
            {
                return(Z_BUF_ERROR);
            }

            int err = deflateInit(stream, level);

            if (err != Z_OK)
            {
                return(err);
            }

            err = deflate(stream, Z_FINISH);
            if (err != Z_STREAM_END)
            {
                deflateEnd(stream);
                return(err == Z_OK ? Z_BUF_ERROR : err);
            }
            destLen = stream.total_out;

            err = deflateEnd(stream);
            return(err);
        }
コード例 #4
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateGetDictionary(
            z_stream strm,
            byte[] dictionary,
            ref uint dictLength)
        {
            inflate_state state;

            /* check state */
            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;

            /* copy dictionary */
            if (state.whave != 0 && dictionary != null)
            {
                zutil.zmemcpy(dictionary, 0, state.window, state.wnext,
                              state.whave - state.wnext);
                zutil.zmemcpy(dictionary, state.whave - state.wnext,
                              state.window, 0, state.wnext);
            }
            //if (dictLength != null)
            dictLength = state.whave;
            return(zlib.Z_OK);
        }
コード例 #5
0
ファイル: uncompr.cs プロジェクト: JoshDullen/zlib.net
		//   The following utility functions are implemented on top of the
		// basic stream-oriented functions. To simplify the interface, some
		// default options are assumed (compression level and memory usage,
		// standard memory allocation functions). The source code of these
		// utility functions can easily be modified if you need special options.

		// ===========================================================================
		//   Decompresses the source buffer into the destination buffer.  sourceLen is
		// the byte length of the source buffer. Upon entry, destLen is the total
		// size of the destination buffer, which must be large enough to hold the
		// entire uncompressed data. (The size of the uncompressed data must have
		// been saved previously by the compressor and transmitted to the decompressor
		// by some mechanism outside the scope of this compression library.)
		// Upon exit, destLen is the actual size of the compressed buffer.
		//
		//   uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
		// enough memory, Z_BUF_ERROR if there was not enough room in the output
		// buffer, or Z_DATA_ERROR if the input data was corrupted.

		public static int uncompress(byte[] dest, ref uint destLen, byte[] source, uint sourceLen, uint sourceOffset=0, uint destOffset=0)
		{
			z_stream stream=new z_stream();

			stream.in_buf=source;
			stream.next_in=sourceOffset;
			stream.avail_in=sourceLen;
			// Check for source > 64K on 16-bit machine:
			if(stream.avail_in!=sourceLen) return Z_BUF_ERROR;

			stream.out_buf=dest;
			stream.next_out=(int)destOffset;
			stream.avail_out=destLen;
			if(stream.avail_out!=destLen) return Z_BUF_ERROR;

			int err=inflateInit(stream);
			if(err!=Z_OK) return err;

			err=inflate(stream, Z_FINISH);
			if(err!=Z_STREAM_END)
			{
				inflateEnd(stream);
				if(err==Z_NEED_DICT||(err==Z_BUF_ERROR&&stream.avail_in==0)) return Z_DATA_ERROR;
				return err;
			}
			destLen=stream.total_out;

			err=inflateEnd(stream);
			return err;
		}
コード例 #6
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateInit_(
            z_stream strm,
            string version,
            int stream_size)
        {
            const int DEF_WBITS = 15;

            return(inflateInit2_(strm, DEF_WBITS, version, stream_size));
        }
コード例 #7
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateCopy(
            z_stream dest,
            z_stream source)
        {
            inflate_state state;
            inflate_state copy;

            byte[] window;
            uint   wsize;

            /* check input */
            if (inflateStateCheck(source) != 0 || dest == null)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = source.state;

            /* allocate space */
            copy = new inflate_state();
            if (copy == null)
            {
                return(zlib.Z_MEM_ERROR);
            }
            window = null;
            if (state.window != null)
            {
                window = new byte[1U << (int)state.wbits];
                if (window == null)
                {
                    copy = null;
                    return(zlib.Z_MEM_ERROR);
                }
            }

            /* copy state */
            zutil.zmemcpy(dest, source);
            zutil.zmemcpy(copy, state);
            copy.strm = dest;
            if (state.lencode_array == state.codes)
            {
                copy.lencode_array  = copy.codes;
                copy.lencode_index  = state.lencode_index;
                copy.distcode_array = copy.codes;
                copy.distcode_index = state.distcode_index;
            }
            copy.next = state.next;
            if (window != null)
            {
                wsize = 1U << (int)state.wbits;
                zutil.zmemcpy(window, 0, state.window, 0, wsize);
            }
            copy.window = window;
            dest.state  = copy;
            return(zlib.Z_OK);
        }
コード例 #8
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateSync(
            z_stream strm)
        {
            uint  len;                        /* number of bytes to look at or looked at */
            ulong @in, @out;                  /* temporary to save total_in and total_out */

            byte[]        buf = new byte[4];  /* to restore bit buffer to byte string */
            inflate_state state;

            /* check parameters */
            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if (strm.avail_in == 0 && state.bits < 8)
            {
                return(zlib.Z_BUF_ERROR);
            }

            /* if first time, start search in bit buffer */
            if (state.mode != inflate_mode.SYNC)
            {
                state.mode   = inflate_mode.SYNC;
                state.hold <<= (int)(state.bits & 7);
                state.bits  -= state.bits & 7;
                len          = 0;
                while (state.bits >= 8)
                {
                    buf[len++]   = (byte)(state.hold);
                    state.hold >>= 8;
                    state.bits  -= 8;
                }
                state.have = 0;
                syncsearch(ref state.have, buf, 0, len);
            }

            /* search available input */
            len            = syncsearch(ref state.have, strm.input_buffer, strm.next_in, strm.avail_in);
            strm.avail_in -= len;
            strm.next_in  += len;
            strm.total_in += len;

            /* return no joy or set up to restart inflate() on a new block */
            if (state.have != 4)
            {
                return(zlib.Z_DATA_ERROR);
            }
            @in = strm.total_in; @out = strm.total_out;
            inflateReset(strm);
            strm.total_in = @in; strm.total_out = @out;
            state.mode    = inflate_mode.TYPE;
            return(zlib.Z_OK);
        }
コード例 #9
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        /*
         * Returns true if inflate is currently at the end of a block generated by
         * Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
         * implementation to provide an additional safety check. PPP uses
         * Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
         * block. When decompressing, PPP checks that at the end of input packet,
         * inflate is waiting for these length bytes.
         */
        public static int inflateSyncPoint(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            return((state.mode == inflate_mode.STORED && state.bits == 0) ? 1 : 0);
        }
コード例 #10
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static ulong inflateCodesUsed(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(ulong.MaxValue);
            }
            state = strm.state;
            return((ulong)(state.next));
        }
コード例 #11
0
            public uint adler;                  // adler32 value of the uncompressed data

            public void CopyTo(z_stream s)
            {
                s.adler     = adler;
                s.avail_in  = avail_in;
                s.avail_out = avail_out;
                s.in_buf    = in_buf;
                s.msg       = msg;
                s.next_in   = next_in;
                s.next_out  = next_out;
                s.out_buf   = out_buf;
                s.state     = state;
                s.total_in  = total_in;
                s.total_out = total_out;
            }
コード例 #12
0
ファイル: zlib.cs プロジェクト: JoshDullen/zlib.net
			public uint adler;		// adler32 value of the uncompressed data

			public void CopyTo(z_stream s)
			{
				s.adler=adler;
				s.avail_in=avail_in;
				s.avail_out=avail_out;
				s.in_buf=in_buf;
				s.msg=msg;
				s.next_in=next_in;
				s.next_out=next_out;
				s.out_buf=out_buf;
				s.state=state;
				s.total_in=total_in;
				s.total_out=total_out;
			}
コード例 #13
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static long inflateMark(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(-(1L << 16));
            }
            state = strm.state;
            return((long)(((ulong)((long)state.back)) << 16) +
                   (state.mode == inflate_mode.COPY ? state.length :
                    (state.mode == inflate_mode.MATCH ? state.was - state.length : 0)));
        }
コード例 #14
0
ファイル: compress.cs プロジェクト: AdmiralCurtiss/zlib-sharp
/* compress.c -- compress a memory buffer
 * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
 * For conditions of distribution and use, see copyright notice in zlib.h
 */

/* ===========================================================================
 *   Compresses the source buffer into the destination buffer. The level
 * parameter has the same meaning as in deflateInit.  sourceLen is the byte
 * length of the source buffer. Upon entry, destLen is the total size of the
 * destination buffer, which must be at least 0.1% larger than sourceLen plus
 * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
 *
 *   compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
 * memory, Z_BUF_ERROR if there was not enough room in the output buffer,
 * Z_STREAM_ERROR if the level parameter is invalid.
 */
        public static int compress2(
            byte[] dest_array,
            long dest_index,
            ref ulong destLen,
            byte[] source_array,
            long source_index,
            ulong sourceLen,
            int level)
        {
            z_stream   stream = new z_stream();
            int        err;
            const uint max = uint.MaxValue;
            ulong      left;

            left    = destLen;
            destLen = 0;

            err = deflate.deflateInit_(stream, level, zlib.ZLIB_VERSION, z_stream._sizeof);
            if (err != zlib.Z_OK)
            {
                return(err);
            }

            stream.output_buffer = dest_array;
            stream.next_out      = dest_index;
            stream.avail_out     = 0;
            stream.input_buffer  = source_array;
            stream.next_in       = source_index;
            stream.avail_in      = 0;

            do
            {
                if (stream.avail_out == 0)
                {
                    stream.avail_out = left > (ulong)max ? max : (uint)left;
                    left            -= stream.avail_out;
                }
                if (stream.avail_in == 0)
                {
                    stream.avail_in = sourceLen > (ulong)max ? max : (uint)sourceLen;
                    sourceLen      -= stream.avail_in;
                }
                err = deflate.deflate_(stream, sourceLen != 0 ? zlib.Z_NO_FLUSH : zlib.Z_FINISH);
            } while (err == zlib.Z_OK);

            destLen = stream.total_out;
            deflate.deflateEnd(stream);
            return(err == zlib.Z_STREAM_END ? zlib.Z_OK : err);
        }
コード例 #15
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateReset(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state       = strm.state;
            state.wsize = 0;
            state.whave = 0;
            state.wnext = 0;
            return(inflateResetKeep(strm));
        }
コード例 #16
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        private static int inflateStateCheck(
            z_stream strm)
        {
            inflate_state state;

            if (strm == null)
            {
                return(1);
            }
            state = strm.state;
            if (state == null || state.strm != strm ||
                state.mode < inflate_mode.HEAD || state.mode > inflate_mode.SYNC)
            {
                return(1);
            }
            return(0);
        }
コード例 #17
0
        //   The following utility functions are implemented on top of the
        // basic stream-oriented functions. To simplify the interface, some
        // default options are assumed (compression level and memory usage,
        // standard memory allocation functions). The source code of these
        // utility functions can easily be modified if you need special options.

        // ===========================================================================
        //   Decompresses the source buffer into the destination buffer.  sourceLen is
        // the byte length of the source buffer. Upon entry, destLen is the total
        // size of the destination buffer, which must be large enough to hold the
        // entire uncompressed data. (The size of the uncompressed data must have
        // been saved previously by the compressor and transmitted to the decompressor
        // by some mechanism outside the scope of this compression library.)
        // Upon exit, destLen is the actual size of the compressed buffer.
        //
        //   uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
        // enough memory, Z_BUF_ERROR if there was not enough room in the output
        // buffer, or Z_DATA_ERROR if the input data was corrupted.

        public static int Uncompress(byte[] dest, ref uint destLen, byte[] source, uint sourceLen, uint sourceOffset = 0, uint destOffset = 0)
        {
            z_stream stream = new z_stream
            {
                in_buf   = source,
                next_in  = sourceOffset,
                avail_in = sourceLen
            };

            // Check for source > 64K on 16-bit machine:
            if (stream.avail_in != sourceLen)
            {
                return(Z_BUF_ERROR);
            }

            stream.out_buf   = dest;
            stream.next_out  = (int)destOffset;
            stream.avail_out = destLen;
            if (stream.avail_out != destLen)
            {
                return(Z_BUF_ERROR);
            }

            int err = inflateInit(stream);

            if (err != Z_OK)
            {
                return(err);
            }

            err = inflate(stream, Z_FINISH);
            if (err != Z_STREAM_END)
            {
                inflateEnd(stream);
                if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
                {
                    return(Z_DATA_ERROR);
                }
                return(err);
            }
            destLen = stream.total_out;

            err = inflateEnd(stream);
            return(err);
        }
コード例 #18
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateEnd(
            z_stream strm)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if (state.window != null)
            {
                state.window = null;
            }
            strm.state = null;
            //Tracev((stderr, "inflate: end\n"));
            return(zlib.Z_OK);
        }
コード例 #19
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateReset2(
            z_stream strm,
            int windowBits)
        {
            int           wrap;
            inflate_state state;

            /* get the state */
            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;

            /* extract wrap request from windowBits parameter */
            if (windowBits < 0)
            {
                wrap       = 0;
                windowBits = -windowBits;
            }
            else
            {
                wrap = (windowBits >> 4) + 5;
                if (windowBits < 48)
                {
                    windowBits &= 15;
                }
            }

            /* set number of window bits, free window if different */
            if (windowBits != 0 && (windowBits < 8 || windowBits > 15))
            {
                return(zlib.Z_STREAM_ERROR);
            }
            if (state.window != null && state.wbits != (uint)windowBits)
            {
                state.window = null;
            }

            /* update state and reset the rest of it */
            state.wrap  = wrap;
            state.wbits = (uint)windowBits;
            return(inflateReset(strm));
        }
コード例 #20
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateUndermine(
            z_stream strm,
            int subvert)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
            //    state.sane = !subvert;
            //    return zlib.Z_OK;
            //#else
            state.sane = 1;
            return(zlib.Z_DATA_ERROR);
            //#endif
        }
コード例 #21
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateSetDictionary(
            z_stream strm,
            byte[] dictionary,
            uint dictLength)
        {
            inflate_state state;
            ulong         dictid;
            int           ret;

            /* check state */
            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if (state.wrap != 0 && state.mode != inflate_mode.DICT)
            {
                return(zlib.Z_STREAM_ERROR);
            }

            /* check for correct dictionary identifier */
            if (state.mode == inflate_mode.DICT)
            {
                dictid = adler32.adler32_(0L, null, 0, 0);
                dictid = adler32.adler32_(dictid, dictionary, 0, dictLength);
                if (dictid != state.check)
                {
                    return(zlib.Z_DATA_ERROR);
                }
            }

            /* copy dictionary to window using updatewindow(), which will amend the
             * existing dictionary if appropriate */
            ret = updatewindow(strm, dictionary, dictLength, dictLength);
            if (ret != 0)
            {
                state.mode = inflate_mode.MEM;
                return(zlib.Z_MEM_ERROR);
            }
            state.havedict = 1;
            //Tracev((stderr, "inflate:   dictionary set\n"));
            return(zlib.Z_OK);
        }
コード例 #22
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateValidate(
            z_stream strm,
            int check)
        {
            inflate_state state;

            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if (check != 0)
            {
                state.wrap |= 4;
            }
            else
            {
                state.wrap &= ~4;
            }
            return(zlib.Z_OK);
        }
コード例 #23
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateGetHeader(
            z_stream strm,
            gz_header head)
        {
            inflate_state state;

            /* check state */
            if (inflateStateCheck(strm) != 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            state = strm.state;
            if ((state.wrap & 2) == 0)
            {
                return(zlib.Z_STREAM_ERROR);
            }

            /* save header structure */
            state.head = head;
            head.done  = 0;
            return(zlib.Z_OK);
        }
コード例 #24
0
ファイル: zutil.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        internal static void zmemcpy(z_stream target, z_stream source)
        {
            target.input_buffer  = source.input_buffer;
            target.output_buffer = source.output_buffer;

            target.next_in  = source.next_in;
            target.avail_in = source.avail_in;
            target.total_in = source.total_in;

            target.next_out  = source.next_out;
            target.avail_out = source.avail_out;
            target.total_out = source.total_out;

            target.msg    = source.msg;
            target.state  = source.state;
            target.dstate = source.dstate;

            target.data_type = source.data_type;

            target.adler    = source.adler;
            target.reserved = source.reserved;
        }
コード例 #25
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        public static int inflateInit2_(
            z_stream strm,
            int windowBits,
            string version,
            int stream_size)
        {
            int           ret;
            inflate_state state;

            if (version == null || version.Length == 0 || version[0] != zlib.ZLIB_VERSION[0] ||
                stream_size != (int)z_stream._sizeof)
            {
                return(zlib.Z_VERSION_ERROR);
            }
            if (strm == null)
            {
                return(zlib.Z_STREAM_ERROR);
            }
            strm.msg = null;                             /* in case we return an error */
            state    = new inflate_state();
            if (state == null)
            {
                return(zlib.Z_MEM_ERROR);
            }
            //Tracev((stderr, "inflate: allocated\n"));
            strm.state   = state;
            state.strm   = strm;
            state.window = null;
            state.mode   = inflate_mode.HEAD;               /* to pass state test in inflateReset2() */
            ret          = inflateReset2(strm, windowBits);
            if (ret != zlib.Z_OK)
            {
                state      = null;
                strm.state = null;
            }
            return(ret);
        }
コード例 #26
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//    This function inserts bits in the inflate input stream.  The intent is
		// that this function is used to start inflating at a bit position in the
		// middle of a byte.  The provided bits will be used before any bytes are used
		// from next_in.  This function should only be used with raw inflate, and
		// should be used before the first inflate() call after inflateInit2() or
		// inflateReset().  bits must be less than or equal to 16, and that many of the
		// least significant bits of value will be inserted in the input.

		//    inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
		// stream state was inconsistent.

		public static int inflatePrime(z_stream strm, int bits, int value)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			inflate_state state=(inflate_state)strm.state;
			if(bits<0)
			{
				state.hold=0;
				state.bits=0;
				return Z_OK;
			}
			if(bits>16||state.bits+bits>32) return Z_STREAM_ERROR;
			value&=(1<<(int)bits)-1;
			state.hold+=(uint)(value<<(int)state.bits);
			state.bits+=(uint)bits;
			return Z_OK;
		}
コード例 #27
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		const int PRESET_DICT=0x20; // preset dictionary flag in zlib header

		#region deflate
		// =========================================================================
		//   deflate compresses as much data as possible, and stops when the input
		// buffer becomes empty or the output buffer becomes full. It may introduce some
		// output latency (reading input without producing any output) except when
		// forced to flush.

		//   The detailed semantics are as follows. deflate performs one or both of the
		// following actions:

		// - Compress more input starting at next_in and update next_in and avail_in
		//   accordingly. If not all input can be processed (because there is not
		//   enough room in the output buffer), next_in and avail_in are updated and
		//   processing will resume at this point for the next call of deflate().

		// - Provide more output starting at next_out and update next_out and avail_out
		//   accordingly. This action is forced if the parameter flush is non zero.
		//   Forcing flush frequently degrades the compression ratio, so this parameter
		//   should be set only when necessary (in interactive applications).
		//   Some output may be provided even if flush is not set.

		// Before the call of deflate(), the application should ensure that at least
		// one of the actions is possible, by providing more input and/or consuming
		// more output, and updating avail_in or avail_out accordingly; avail_out
		// should never be zero before the call. The application can consume the
		// compressed output when it wants, for example when the output buffer is full
		// (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
		// and with zero avail_out, it must be called again after making room in the
		// output buffer because there might be more output pending.

		//   Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
		// decide how much data to accumualte before producing output, in order to
		// maximize compression.

		//   If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
		// flushed to the output buffer and the output is aligned on a byte boundary, so
		// that the decompressor can get all input data available so far. (In particular
		// avail_in is zero after the call if enough output space has been provided
		// before the call.)  Flushing may degrade compression for some compression
		// algorithms and so it should be used only when necessary.

		//   If flush is set to Z_FULL_FLUSH, all output is flushed as with
		// Z_SYNC_FLUSH, and the compression state is reset so that decompression can
		// restart from this point if previous compressed data has been damaged or if
		// random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
		// compression.

		//   If deflate returns with avail_out == 0, this function must be called again
		// with the same value of the flush parameter and more output space (updated
		// avail_out), until the flush is complete (deflate returns with non-zero
		// avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
		// avail_out is greater than six to avoid repeated flush markers due to
		// avail_out == 0 on return.

		//   If the parameter flush is set to Z_FINISH, pending input is processed,
		// pending output is flushed and deflate returns with Z_STREAM_END if there
		// was enough output space; if deflate returns with Z_OK, this function must be
		// called again with Z_FINISH and more output space (updated avail_out) but no
		// more input data, until it returns with Z_STREAM_END or an error. After
		// deflate has returned Z_STREAM_END, the only possible operations on the
		// stream are deflateReset or deflateEnd.

		//   Z_FINISH can be used immediately after deflateInit if all the compression
		// is to be done in a single step. In this case, avail_out must be at least
		// the value returned by deflateBound (see below). If deflate does not return
		// Z_STREAM_END, then it must be called again as described above.

		//   deflate() sets strm.adler to the adler32 checksum of all input read
		// so far (that is, total_in bytes).

		//   deflate() returns Z_OK if some progress has been made (more input
		// processed or more output produced), Z_STREAM_END if all input has been
		// consumed and all output has been produced (only when flush is set to
		// Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
		// if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
		// (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
		// fatal, and deflate() can be called again with more input and more output
		// space to continue compressing.

		public static int deflate(z_stream strm, int flush)
		{
			int old_flush; // value of flush param for previous deflate call

			if(strm==null||strm.state==null||flush>Z_BLOCK||flush<0) return Z_STREAM_ERROR;
			deflate_state s=(deflate_state)strm.state;

			if(strm.out_buf==null||(strm.in_buf==null&&strm.avail_in!=0)||(s.status==FINISH_STATE&&flush!=Z_FINISH))
			{
				strm.msg=zError(Z_STREAM_ERROR);
				return Z_STREAM_ERROR;
			}

			if(strm.avail_out==0)
			{
				strm.msg=zError(Z_BUF_ERROR);
				return Z_BUF_ERROR;
			}

			s.strm=strm; // just in case
			old_flush=s.last_flush;
			s.last_flush=flush;

			// Write the header
			if(s.status==INIT_STATE)
			{
				if(s.wrap==2)
				{
					strm.adler=crc32(0, null, 0);
					s.pending_buf[s.pending++]=31;
					s.pending_buf[s.pending++]=139;
					s.pending_buf[s.pending++]=8;
					if(s.gzhead==null)
					{
						s.pending_buf[s.pending++]=0;

						s.pending_buf[s.pending++]=0;
						s.pending_buf[s.pending++]=0;
						s.pending_buf[s.pending++]=0;
						s.pending_buf[s.pending++]=0;

						s.pending_buf[s.pending++]=(byte)(s.level==9?2:(s.strategy>=Z_HUFFMAN_ONLY||s.level<2?4:0));
						s.pending_buf[s.pending++]=OS_CODE;
						s.status=BUSY_STATE;
					}
					else
					{
						s.pending_buf[s.pending++]=(byte)((s.gzhead.text!=0?1:0)+(s.gzhead.hcrc!=0?2:0)+(s.gzhead.extra==null?0:4)+
									(s.gzhead.name==null?0:8)+(s.gzhead.comment==null?0:16));
						s.pending_buf[s.pending++]=(byte)(s.gzhead.time&0xff);
						s.pending_buf[s.pending++]=(byte)((s.gzhead.time>>8)&0xff);
						s.pending_buf[s.pending++]=(byte)((s.gzhead.time>>16)&0xff);
						s.pending_buf[s.pending++]=(byte)((s.gzhead.time>>24)&0xff);
						s.pending_buf[s.pending++]=(byte)(s.level==9?2:(s.strategy>=Z_HUFFMAN_ONLY||s.level<2?4:0));
						s.pending_buf[s.pending++]=(byte)(s.gzhead.os&0xff);
						if(s.gzhead.extra!=null)
						{
							s.pending_buf[s.pending++]=(byte)(s.gzhead.extra_len&0xff);
							s.pending_buf[s.pending++]=(byte)((s.gzhead.extra_len>>8)&0xff);
						}
						if(s.gzhead.hcrc!=0) strm.adler=crc32(strm.adler, s.pending_buf, s.pending);
						s.gzindex=0;
						s.status=EXTRA_STATE;
					}
				}
				else
				{
					uint header=(Z_DEFLATED+((s.w_bits-8)<<4))<<8;
					uint level_flags;

					if(s.strategy>=Z_HUFFMAN_ONLY||s.level<2) level_flags=0;
					else if(s.level<6) level_flags=1;
					else if(s.level==6) level_flags=2;
					else level_flags=3;

					header|=(level_flags<<6);
					if(s.strstart!=0) header|=PRESET_DICT;
					header+=31-(header%31);

					s.status=BUSY_STATE;
					putShortMSB(s, header);

					// Save the adler32 of the preset dictionary:
					if(s.strstart!=0)
					{
						putShortMSB(s, (uint)(strm.adler>>16));
						putShortMSB(s, (uint)(strm.adler&0xffff));
					}
					strm.adler=adler32(0, null, 0);
				}
			}
			if(s.status==EXTRA_STATE)
			{
				if(s.gzhead.extra!=null)
				{
					uint beg=s.pending;  // start of bytes to update crc

					while(s.gzindex<(s.gzhead.extra_len&0xffff))
					{
						if(s.pending==s.pending_buf_size)
						{
							if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
							flush_pending(strm);
							beg=s.pending;
							if(s.pending==s.pending_buf_size) break;
						}
						s.pending_buf[s.pending++]=s.gzhead.extra[s.gzindex];
						s.gzindex++;
					}
					if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
					if(s.gzindex==s.gzhead.extra_len)
					{
						s.gzindex=0;
						s.status=NAME_STATE;
					}
				}
				else s.status=NAME_STATE;
			}
			if(s.status==NAME_STATE)
			{
				if(s.gzhead.name!=null)
				{
					uint beg=s.pending;  // start of bytes to update crc
					byte val;

					do
					{
						if(s.pending==s.pending_buf_size)
						{
							if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
							flush_pending(strm);
							beg=s.pending;
							if(s.pending==s.pending_buf_size)
							{
								val=1;
								break;
							}
						}
						val=s.gzhead.name[s.gzindex++];
						s.pending_buf[s.pending++]=val;
					} while(val!=0);
					if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
					if(val==0)
					{
						s.gzindex=0;
						s.status=COMMENT_STATE;
					}
				}
				else s.status=COMMENT_STATE;
			}
			if(s.status==COMMENT_STATE)
			{
				if(s.gzhead.comment!=null)
				{
					uint beg=s.pending;  // start of bytes to update crc
					byte val;

					do
					{
						if(s.pending==s.pending_buf_size)
						{
							if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
							flush_pending(strm);
							beg=s.pending;
							if(s.pending==s.pending_buf_size)
							{
								val=1;
								break;
							}
						}
						val=s.gzhead.comment[s.gzindex++];
						s.pending_buf[s.pending++]=val;
					} while(val!=0);
					if(s.gzhead.hcrc!=0&&s.pending>beg) strm.adler=crc32(strm.adler, s.pending_buf, beg, s.pending-beg);
					if(val==0) s.status=HCRC_STATE;
				}
				else s.status=HCRC_STATE;
			}
			if(s.status==HCRC_STATE)
			{
				if(s.gzhead.hcrc!=0)
				{
					if(s.pending+2>s.pending_buf_size) flush_pending(strm);
					if(s.pending+2<=s.pending_buf_size)
					{
						s.pending_buf[s.pending++]=(byte)(strm.adler&0xff);
						s.pending_buf[s.pending++]=(byte)((strm.adler>>8)&0xff);
						strm.adler=crc32(0, null, 0);
						s.status=BUSY_STATE;
					}
				}
				else s.status=BUSY_STATE;
			}

			// Flush as much pending output as possible
			if(s.pending!=0)
			{
				flush_pending(strm);
				if(strm.avail_out==0)
				{
					// Since avail_out is 0, deflate will be called again with
					// more output space, but possibly with both pending and
					// avail_in equal to zero. There won't be anything to do,
					// but this is not an error situation so make sure we
					// return OK instead of BUF_ERROR at next call of deflate:
					s.last_flush=-1;
					return Z_OK;
				}

				// Make sure there is something to do and avoid duplicate consecutive
				// flushes. For repeated and useless calls with Z_FINISH, we keep
				// returning Z_STREAM_END instead of Z_BUF_ERROR.
			}
			else if(strm.avail_in==0&&flush<=old_flush&&flush!=Z_FINISH)
			{
				strm.msg=zError(Z_BUF_ERROR);
				return Z_BUF_ERROR;
			}

			// User must not provide more input after the first FINISH:
			if(s.status==FINISH_STATE&&strm.avail_in!=0)
			{
				strm.msg=zError(Z_BUF_ERROR);
				return Z_BUF_ERROR;
			}

			// Start a new block or continue the current one.
			if(strm.avail_in!=0||s.lookahead!=0||(flush!=Z_NO_FLUSH&&s.status!=FINISH_STATE))
			{
				block_state bstate=s.strategy==Z_HUFFMAN_ONLY?deflate_huff(s, flush):(s.strategy==Z_RLE?deflate_rle(s, flush):configuration_table[s.level].func(s, flush));

				if(bstate==block_state.finish_started||bstate==block_state.finish_done) s.status=FINISH_STATE;
				if(bstate==block_state.need_more||bstate==block_state.finish_started)
				{
					if(strm.avail_out==0) s.last_flush=-1; // avoid BUF_ERROR next call, see above
					return Z_OK;
					// If flush != Z_NO_FLUSH && avail_out == 0, the next call
					// of deflate should use the same flush parameter to make sure
					// that the flush is complete. So we don't have to output an
					// empty block here, this will be done at next call. This also
					// ensures that for a very small output buffer, we emit at most
					// one empty block.
				}
				if(bstate==block_state.block_done)
				{
					if(flush==Z_PARTIAL_FLUSH) _tr_align(s);
					else if(flush!=Z_BLOCK)
					{ // FULL_FLUSH or SYNC_FLUSH
						_tr_stored_block(s, null, 0, 0);
						// For a full flush, this empty block will be recognized
						// as a special marker by inflate_sync().
						if(flush==Z_FULL_FLUSH)
						{
							s.head[s.hash_size-1]=NIL; // forget history

							//was memset((byte*)s.head, 0, (uint)(s.hash_size-1)*sizeof(*s.head));
							for(int i=0; i<s.hash_size-1; i++) s.head[i]=0;

							if(s.lookahead==0)
							{
								s.strstart=0;
								s.block_start=0;
							}
						}
					}
					flush_pending(strm);
					if(strm.avail_out==0)
					{
						s.last_flush=-1; // avoid BUF_ERROR at next call, see above
						return Z_OK;
					}
				}
			}
			//Assert(strm.avail_out>0, "bug2");

			if(flush!=Z_FINISH) return Z_OK;
			if(s.wrap<=0) return Z_STREAM_END;

			// Write the trailer
			if(s.wrap==2)
			{
				s.pending_buf[s.pending++]=(byte)(strm.adler&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.adler>>8)&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.adler>>16)&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.adler>>24)&0xff);
				s.pending_buf[s.pending++]=(byte)(strm.total_in&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.total_in>>8)&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.total_in>>16)&0xff);
				s.pending_buf[s.pending++]=(byte)((strm.total_in>>24)&0xff);
			}
			else
			{
				putShortMSB(s, (uint)(strm.adler>>16));
				putShortMSB(s, (uint)(strm.adler&0xffff));
			}

			flush_pending(strm);
			// If avail_out is zero, the application will call deflate again
			// to flush the rest.
			if(s.wrap>0) s.wrap=-s.wrap; // write the trailer only once!
			return s.pending!=0?Z_OK:Z_STREAM_END;
		}
コード例 #28
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   All dynamically allocated data structures for this stream are freed.
		// This function discards any unprocessed input and does not flush any
		// pending output.

		//   deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
		// stream state was inconsistent, Z_DATA_ERROR if the stream was freed
		// prematurely (some input or output was discarded). In the error case,
		// msg may be set but then points to a static string (which must not be
		// deallocated).

		public static int deflateEnd(z_stream strm)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;

			deflate_state s=(deflate_state)strm.state;
			int status=s.status;
			if(status!=INIT_STATE&& status!=EXTRA_STATE&& status!=NAME_STATE&& status!=COMMENT_STATE&&
				status!=HCRC_STATE&& status!=BUSY_STATE&&status!=FINISH_STATE) return Z_STREAM_ERROR;

			// Deallocate in reverse order of allocations:
			//if(s.pending_buf!=null) free(s.pending_buf);
			//if(s.l_buf!=null) free(s.l_buf);
			//if(s.d_buf!=null) free(s.d_buf);
			//if(s.head!=null) free(s.head);
			//if(s.prev!=null) free(s.prev);
			//if(s.window!=null) free(s.window);
			s.pending_buf=s.l_buf=s.window=null;
			s.d_buf=s.head=s.prev=null;

			//free(strm.state);
			strm.state=s=null;

			return status==BUSY_STATE?Z_DATA_ERROR:Z_OK;
		}
コード例 #29
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
		// For deflate_fast() (levels <= 3) good is ignored and lazy has a different
		// meaning.

		// ===========================================================================
		// Update a hash value with the given input byte
		// IN  assertion: all calls to to UPDATE_HASH are made with consecutive
		//    input characters, so that a running hash key can be computed from the
		//    previous key instead of complete recalculation each time.
		//#define UPDATE_HASH(s,h,c) h = ((h<<s.hash_shift) ^ c) & s.hash_mask

		// ===========================================================================
		// Insert string str in the dictionary and set match_head to the previous head
		// of the hash chain (the most recent string with same hash key). Return
		// the previous length of the hash chain.
		// If this file is compiled with -DFASTEST, the compression level is forced
		// to 1, and no hash chains are maintained.
		// IN  assertion: all calls to to INSERT_STRING are made with consecutive
		//    input characters and the first MIN_MATCH bytes of str are valid
		//    (except for the last MIN_MATCH-1 bytes of the input file).
		//#define INSERT_STRING(s, str, match_head) \
		//		s.ins_h = ((s.ins_h<<(int)s.hash_shift) ^ s.window[(str) + (MIN_MATCH-1)]) & s.hash_mask; \
		//		match_head = s.prev[(str) & s.w_mask] = s.head[s.ins_h]; \
		//		s.head[s.ins_h] = (unsigned short)str

		// ===========================================================================
		// Initialize the hash table (avoiding 64K overflow for 16 bit systems).
		// prev[] will be initialized on the fly.

		// =========================================================================
		//   Initializes the internal stream state for compression. The fields
		// zalloc, zfree and opaque must be initialized before by the caller.
		// If zalloc and zfree are set to Z_NULL, deflateInit updates them to
		// use default allocation functions.

		//   The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
		// 1 gives best speed, 9 gives best compression, 0 gives no compression at
		// all (the input data is simply copied a block at a time).
		// Z_DEFAULT_COMPRESSION requests a default compromise between speed and
		// compression (currently equivalent to level 6).

		//   deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
		// enough memory, Z_STREAM_ERROR if level is not a valid compression level,
		// Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
		// with the version assumed by the caller (ZLIB_VERSION).
		// msg is set to null if there is no error message.  deflateInit does not
		// perform any compression: this will be done by deflate().
		public static int deflateInit(z_stream strm, int level)
		{
			return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
			// Todo: ignore strm.next_in if we use it as window
		}
コード例 #30
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   This function is equivalent to deflateEnd followed by deflateInit,
		// but does not free and reallocate all the internal compression state.
		// The stream will keep the same compression level and any other attributes
		// that may have been set by deflateInit2.

		//    deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
		// stream state was inconsistent (such as zalloc or state being NULL).
		public static int deflateReset(z_stream strm)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;

			strm.total_in=strm.total_out=0;
			strm.msg=null;

			deflate_state s=(deflate_state)strm.state;
			s.pending=0;
			s.pending_out=0;

			if(s.wrap<0) s.wrap=-s.wrap; // was made negative by deflate(..., Z_FINISH);

			s.status=s.wrap!=0?INIT_STATE:BUSY_STATE;
			strm.adler=s.wrap==2?crc32(0, null, 0):adler32(0, null, 0);
			s.last_flush=Z_NO_FLUSH;

			_tr_init(s);
			lm_init(s);

			return Z_OK;
		}
コード例 #31
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//   inflate decompresses as much data as possible, and stops when the input
		// buffer becomes empty or the output buffer becomes full. It may introduce
		// some output latency (reading input without producing any output) except when
		// forced to flush.

		// The detailed semantics are as follows. inflate performs one or both of the
		// following actions:

		// - Decompress more input starting at next_in and update next_in and avail_in
		//   accordingly. If not all input can be processed (because there is not
		//   enough room in the output buffer), next_in is updated and processing
		//   will resume at this point for the next call of inflate().

		// - Provide more output starting at next_out and update next_out and avail_out
		//   accordingly.  inflate() provides as much output as possible, until there
		//   is no more input data or no more space in the output buffer (see below
		//   about the flush parameter).

		// Before the call of inflate(), the application should ensure that at least
		// one of the actions is possible, by providing more input and/or consuming
		// more output, and updating the next_* and avail_* values accordingly.
		// The application can consume the uncompressed output when it wants, for
		// example when the output buffer is full (avail_out == 0), or after each
		// call of inflate(). If inflate returns Z_OK and with zero avail_out, it
		// must be called again after making room in the output buffer because there
		// might be more output pending.

		//   The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
		// Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
		// output as possible to the output buffer. Z_BLOCK requests that inflate() stop
		// if and when it gets to the next deflate block boundary. When decoding the
		// zlib or gzip format, this will cause inflate() to return immediately after
		// the header and before the first block. When doing a raw inflate, inflate()
		// will go ahead and process the first block, and will return when it gets to
		// the end of that block, or when it runs out of data.

		//   The Z_BLOCK option assists in appending to or combining deflate streams.
		// Also to assist in this, on return inflate() will set strm.data_type to the
		// number of unused bits in the last byte taken from strm.next_in, plus 64
		// if inflate() is currently decoding the last block in the deflate stream,
		// plus 128 if inflate() returned immediately after decoding an end-of-block
		// code or decoding the complete header up to just before the first byte of the
		// deflate stream. The end-of-block will not be indicated until all of the
		// uncompressed data from that block has been written to strm.next_out.  The
		// number of unused bits may in general be greater than seven, except when
		// bit 7 of data_type is set, in which case the number of unused bits will be
		// less than eight.

		//   inflate() should normally be called until it returns Z_STREAM_END or an
		// error. However if all decompression is to be performed in a single step
		// (a single call of inflate), the parameter flush should be set to
		// Z_FINISH. In this case all pending input is processed and all pending
		// output is flushed; avail_out must be large enough to hold all the
		// uncompressed data. (The size of the uncompressed data may have been saved
		// by the compressor for this purpose.) The next operation on this stream must
		// be inflateEnd to deallocate the decompression state. The use of Z_FINISH
		// is never required, but can be used to inform inflate that a faster approach
		// may be used for the single inflate() call.

		//    In this implementation, inflate() always flushes as much output as
		// possible to the output buffer, and always uses the faster approach on the
		// first call. So the only effect of the flush parameter in this implementation
		// is on the return value of inflate(), as noted below, or when it returns early
		// because Z_BLOCK is used.

		//    If a preset dictionary is needed after this call (see inflateSetDictionary
		// below), inflate sets strm.adler to the adler32 checksum of the dictionary
		// chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
		// strm.adler to the adler32 checksum of all output produced so far (that is,
		// total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
		// below. At the end of the stream, inflate() checks that its computed adler32
		// checksum is equal to that saved by the compressor and returns Z_STREAM_END
		// only if the checksum is correct.

		//   inflate() will decompress and check either zlib-wrapped or gzip-wrapped
		// deflate data.  The header type is detected automatically.  Any information
		// contained in the gzip header is not retained, so applications that need that
		// information should instead use raw inflate, see inflateInit2() below, or
		// inflateBack() and perform their own processing of the gzip header and
		// trailer.

		//   inflate() returns Z_OK if some progress has been made (more input processed
		// or more output produced), Z_STREAM_END if the end of the compressed data has
		// been reached and all uncompressed output has been produced, Z_NEED_DICT if a
		// preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
		// corrupted (input stream not conforming to the zlib format or incorrect check
		// value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
		// if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
		// Z_BUF_ERROR if no progress is possible or if there was not enough room in the
		// output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
		// inflate() can be called again with more input and more output space to
		// continue decompressing. If Z_DATA_ERROR is returned, the application may then
		// call inflateSync() to look for a good compression block if a partial recovery
		// of the data is desired.

		public static int inflate(z_stream strm, int flush)
		{
			inflate_state state;
			uint next;				// next input
			int put;				// next output
			uint have, left;		// available input and output
			uint hold;				// bit buffer
			uint bits;				// bits in bit buffer
			uint _in, _out;			// save starting available input and output
			uint copy;				// number of stored or match bytes to copy
			byte[] from;			// where to copy match bytes from
			int from_ind;			// where to copy match bytes from
			code here;				// current decoding table entry
			code last;				// parent table entry
			uint len;				// length to copy for repeats, bits to drop
			int ret;				// return code
			byte[] hbuf=new byte[4];// buffer for gzip header crc calculation

			if(strm==null||strm.state==null||strm.out_buf==null||(strm.in_buf==null&&strm.avail_in!=0))
				return Z_STREAM_ERROR;

			byte[] in_buf=strm.in_buf;
			byte[] out_buf=strm.out_buf;

			state=(inflate_state)strm.state;
			if(state.mode==inflate_mode.TYPE) state.mode=inflate_mode.TYPEDO; // skip check

			//was LOAD();
			put=strm.next_out;
			left=strm.avail_out;
			next=strm.next_in;
			have=strm.avail_in;
			hold=state.hold;
			bits=state.bits;

			_in=have;
			_out=left;
			ret=Z_OK;

			for(; ; )
			{
				switch(state.mode)
				{
					case inflate_mode.HEAD:
						if(state.wrap==0)
						{
							state.mode=inflate_mode.TYPEDO;
							break;
						}
						//was NEEDBITS(16);
						while(bits<16)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						if((state.wrap&2)!=0&&hold==0x8b1f)
						{  // gzip header
							state.check=crc32(0, null, 0);

							//was CRC2(state.check, hold);
							hbuf[0]=(byte)hold;
							hbuf[1]=(byte)(hold>>8);
							state.check=crc32(state.check, hbuf, 2);

							//was INITBITS();
							hold=bits=0;

							state.mode=inflate_mode.FLAGS;
							break;
						}

						state.flags=0;					// expect zlib header
						if(state.head!=null) state.head.done=-1;

						//was if(!(state.wrap & 1) ||	// check if zlib header allowed
						// ((BITS(8)<<8)+(hold>>8))%31)
						if((state.wrap&1)==0||			// check if zlib header allowed
							((((hold&0xFF)<<8)+(hold>>8))%31)!=0)
						{
							strm.msg="incorrect header check";
							state.mode=inflate_mode.BAD;
							break;
						}

						//was if(BITS(4)!=Z_DEFLATED)
						if((hold&0x0F)!=Z_DEFLATED)
						{
							strm.msg="unknown compression method";
							state.mode=inflate_mode.BAD;
							break;
						}

						//was DROPBITS(4);
						hold>>=4;
						bits-=4;

						//was len=BITS(4)+8;
						len=(hold&0x0F)+8;

						if(state.wbits==0)
							state.wbits=len;
						else if(len>state.wbits)
						{
							strm.msg="invalid window size";
							state.mode=inflate_mode.BAD;
							break;
						}

						state.dmax=1U<<(int)len;
						//Tracev((stderr, "inflate:   zlib header ok\n"));

						strm.adler=state.check=adler32(0, null, 0);
						state.mode=(hold&0x200)!=0?inflate_mode.DICTID:inflate_mode.TYPE;

						//was INITBITS();
						hold=bits=0;

						break;
					case inflate_mode.FLAGS:
						//was NEEDBITS(16);
						while(bits<16)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						state.flags=(int)hold;
						if((state.flags&0xff)!=Z_DEFLATED)
						{
							strm.msg="unknown compression method";
							state.mode=inflate_mode.BAD;
							break;
						}
						if((state.flags&0xe000)!=0)
						{
							strm.msg="unknown header flags set";
							state.mode=inflate_mode.BAD;
							break;
						}
						if(state.head!=null) state.head.text=(int)((hold>>8)&1);
						if((state.flags&0x0200)!=0)
						{
							//was CRC2(state.check, hold);
							hbuf[0]=(byte)hold;
							hbuf[1]=(byte)(hold>>8);
							state.check=crc32(state.check, hbuf, 2);
						}

						//was INITBITS();
						hold=bits=0;

						state.mode=inflate_mode.TIME;
						break; // no fall through
					case inflate_mode.TIME:
						//was NEEDBITS(32);
						while(bits<32)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						if(state.head!=null) state.head.time=hold;
						if((state.flags&0x0200)!=0)
						{
							//was CRC4(state.check, hold);
							hbuf[0]=(byte)hold;
							hbuf[1]=(byte)(hold>>8);
							hbuf[2]=(byte)(hold>>16);
							hbuf[3]=(byte)(hold>>24);
							state.check=crc32(state.check, hbuf, 4);
						}

						//was INITBITS();
						hold=bits=0;

						state.mode=inflate_mode.OS;
						break; // no fall through
					case inflate_mode.OS:
						//was NEEDBITS(16);
						while(bits<16)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						if(state.head!=null)
						{
							state.head.xflags=(int)(hold&0xff);
							state.head.os=(int)(hold>>8);
						}
						if((state.flags&0x0200)!=0)
						{
							//was CRC2(state.check, hold);
							hbuf[0]=(byte)hold;
							hbuf[1]=(byte)(hold>>8);
							state.check=crc32(state.check, hbuf, 2);
						}

						//was INITBITS();
						hold=bits=0;

						state.mode=inflate_mode.EXLEN;
						break; // no fall through
					case inflate_mode.EXLEN:
						if((state.flags&0x0400)!=0)
						{
							//was NEEDBITS(16);
							while(bits<16)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							state.length=hold;
							if(state.head!=null) state.head.extra_len=hold;
							if((state.flags&0x0200)!=0)
							{
								//was CRC2(state.check, hold);
								hbuf[0]=(byte)hold;
								hbuf[1]=(byte)(hold>>8);
								state.check=crc32(state.check, hbuf, 2);
							}

							//was INITBITS();
							hold=bits=0;
						}
						else if(state.head!=null) state.head.extra=null;

						state.mode=inflate_mode.EXTRA;
						break; // no fall through
					case inflate_mode.EXTRA:
						if((state.flags&0x0400)!=0)
						{
							copy=state.length;
							if(copy>have) copy=have;
							if(copy!=0)
							{
								if(state.head!=null&&state.head.extra!=null)
								{
									len=state.head.extra_len-state.length; // should be always zero!!!
									//was zmemcpy(state.head.extra+len, next, (len+copy>state.head.extra_max)?state.head.extra_max-len:copy);
									Array.Copy(in_buf, next, state.head.extra, len, (len+copy>state.head.extra_max)?state.head.extra_max-len:copy);
								}
								if((state.flags&0x0200)!=0) state.check=crc32(state.check, in_buf, (uint)next, copy);
								have-=copy;
								next+=copy;
								state.length-=copy;
							}
							if(state.length!=0) goto inf_leave;
						}
						state.length=0;
						state.mode=inflate_mode.NAME;
						break; // no fall through
					case inflate_mode.NAME:
						if((state.flags&0x0800)!=0)
						{
							if(have==0) goto inf_leave;
							copy=0;
							do
							{
								//was len=next[copy++];
								len=in_buf[next+copy++];
								if(state.head!=null&&state.head.name!=null&&state.length<state.head.name_max)
									state.head.name[state.length++]=(byte)len;
							} while(len!=0&&copy<have);

							if((state.flags&0x0200)!=0) state.check=crc32(state.check, in_buf, (uint)next, copy);
							have-=copy;
							next+=copy;
							if(len!=0) goto inf_leave;
						}
						else if(state.head!=null) state.head.name=null;
						state.length=0;
						state.mode=inflate_mode.COMMENT;
						break; // no fall through
					case inflate_mode.COMMENT:
						if((state.flags&0x1000)!=0)
						{
							if(have==0) goto inf_leave;
							copy=0;
							do
							{
								//was len=next[copy++];
								len=in_buf[next+copy++];
								if(state.head!=null&&state.head.comment!=null&&state.length<state.head.comm_max)
									state.head.comment[state.length++]=(byte)len;
							} while(len!=0&&copy<have);
							if((state.flags&0x0200)!=0) state.check=crc32(state.check, in_buf, (uint)next, copy);
							have-=copy;
							next+=copy;
							if(len!=0) goto inf_leave;
						}
						else if(state.head!=null) state.head.comment=null;
						state.mode=inflate_mode.HCRC;
						break; // no fall through
					case inflate_mode.HCRC:
						if((state.flags&0x0200)!=0)
						{
							//was NEEDBITS(16);
							while(bits<16)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							if(hold!=(state.check&0xffff))
							{
								strm.msg="header crc mismatch";
								state.mode=inflate_mode.BAD;
								break;
							}

							//was INITBITS();
							hold=bits=0;
						}
						if(state.head!=null)
						{
							state.head.hcrc=(int)((state.flags>>9)&1);
							state.head.done=1;
						}
						strm.adler=state.check=crc32(0, null, 0);
						state.mode=inflate_mode.TYPE;
						break;
					case inflate_mode.DICTID:
						//was NEEDBITS(32);
						while(bits<32)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						//was strm.adler=state.check=REVERSE(hold);
						strm.adler=state.check=((hold>>24)&0xff)+((hold>>8)&0xff00)+((hold&0xff00)<<8)+((hold&0xff)<<24);

						//was INITBITS();
						hold=bits=0;

						state.mode=inflate_mode.DICT;
						break; // no fall through
					case inflate_mode.DICT:
						if(state.havedict==0)
						{
							//was RESTORE();
							strm.next_out=put;
							strm.avail_out=left;
							strm.next_in=next;
							strm.avail_in=have;
							state.hold=hold;
							state.bits=bits;

							return Z_NEED_DICT;
						}
						strm.adler=state.check=adler32(0, null, 0);
						state.mode=inflate_mode.TYPE;
						break; // no fall through
					case inflate_mode.TYPE:
						if(flush==Z_BLOCK||flush==Z_TREES) goto inf_leave;

						state.mode=inflate_mode.TYPEDO;
						break; // no fall through
					case inflate_mode.TYPEDO:
						if(state.last!=0)
						{
							//was BYTEBITS();
							hold>>=(int)(bits&7);
							bits-=bits&7;

							state.mode=inflate_mode.CHECK;
							break;
						}

						//was NEEDBITS(3);
						while(bits<3)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						//was state.last=BITS(1);
						state.last=(int)(hold&0x01);

						//was DROPBITS(1);
						hold>>=1;
						bits-=1;

						//was switch(BITS(2))
						switch(hold&0x03)
						{
							case 0: // stored block
								//Tracev((stderr, "inflate:     stored block%s\n", state.last ? " (last)" : ""));
								state.mode=inflate_mode.STORED;
								break;
							case 1: // fixed block
								fixedtables(state);
								//Tracev((stderr, "inflate:     fixed codes block%s\n", state.last ? " (last)" : ""));
								state.mode=inflate_mode.LEN_;              // decode codes
								if(flush==Z_TREES)
								{
									//was DROPBITS(2);
									hold>>=2;
									bits-=2;
									goto inf_leave;
								}
								break;
							case 2: // dynamic block
								//Tracev((stderr, "inflate:     dynamic codes block%s\n", state.last ? " (last)" : ""));
								state.mode=inflate_mode.TABLE;
								break;
							case 3:
								strm.msg="invalid block type";
								state.mode=inflate_mode.BAD;
								break;
						}

						//was DROPBITS(2);
						hold>>=2;
						bits-=2;

						break;
					case inflate_mode.STORED:
						//was BYTEBITS(); // go to byte boundary
						hold>>=(int)(bits&7);
						bits-=bits&7;

						//was NEEDBITS(32);
						while(bits<32)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						if((hold&0xffff)!=((hold>>16)^0xffff))
						{
							strm.msg="invalid stored block lengths";
							state.mode=inflate_mode.BAD;
							break;
						}
						state.length=hold&0xffff;
						//Tracev((stderr, "inflate:       stored length %u\n", state.length));

						//was INITBITS();
						hold=bits=0;

						state.mode=inflate_mode.COPY_;
						if(flush==Z_TREES) goto inf_leave;
						break; // no fall through
					case inflate_mode.COPY_:
						state.mode=inflate_mode.COPY;
						break; // no fall through
					case inflate_mode.COPY:
						copy=state.length;
						if(copy!=0)
						{
							if(copy>have) copy=have;
							if(copy>left) copy=left;
							if(copy==0) goto inf_leave;

							//was memcpy(put, next, copy);
							Array.Copy(in_buf, next, out_buf, put, copy);

							have-=copy;
							next+=copy;
							left-=copy;
							put+=(int)copy;
							state.length-=copy;
							break;
						}
						//Tracev((stderr, "inflate:       stored end\n"));
						state.mode=inflate_mode.TYPE;
						break;
					case inflate_mode.TABLE:
						//was NEEDBITS(14);
						while(bits<14)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						//was state.nlen=BITS(5)+257;
						state.nlen=(hold&0x1f)+257;

						//was DROPBITS(5);
						hold>>=5;
						bits-=5;

						//was state.ndist=BITS(5)+1;
						state.ndist=(hold&0x1f)+1;

						//was DROPBITS(5);
						hold>>=5;
						bits-=5;

						//was state.ncode=BITS(4)+4;
						state.ncode=(hold&0x0f)+4;

						//was DROPBITS(4);
						hold>>=4;
						bits-=4;

						if(state.nlen>286||state.ndist>30)
						{
							strm.msg="too many length or distance symbols";
							state.mode=inflate_mode.BAD;
							break;
						}
						//Tracev((stderr, "inflate:       table sizes ok\n"));
						state.have=0;
						state.mode=inflate_mode.LENLENS;
						break; // no fall through
					case inflate_mode.LENLENS:
						while(state.have<state.ncode)
						{
							//was NEEDBITS(3);
							while(bits<3)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							//was state.lens[order[state.have++]]=(ushort)BITS(3);
							state.lens[order[state.have++]]=(ushort)(hold&0x07);

							//was DROPBITS(3);
							hold>>=3;
							bits-=3;
						}
						while(state.have<19) state.lens[order[state.have++]]=0;
						state.next=0;
						state.lencode=state.codes;
						state.lenbits=7;

						//was ret=inflate_table(codetype.CODES, state.lens, 19, &(state.next), &(state.lenbits), state.work);
						ret=inflate_table(codetype.CODES, state.lens, 0, 19, state.codes, ref state.next, ref state.lenbits, state.work);

						if(ret!=0)
						{
							strm.msg="invalid code lengths set";
							state.mode=inflate_mode.BAD;
							break;
						}
						//Tracev((stderr, "inflate:       code lengths ok\n"));
						state.have=0;
						state.mode=inflate_mode.CODELENS;
						break; // no fall through
					case inflate_mode.CODELENS:
						while(state.have<(state.nlen+state.ndist))
						{
							for(; ; )
							{
								//was _this=state.lencode[BITS(state.lenbits)];
								here=state.lencode[hold&((1<<(int)state.lenbits)-1)];

								if(here.bits<=bits) break;

								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							if(here.val<16)
							{
								//was NEEDBITS(_this.bits);
								while(bits<here.bits)
								{
									//was PULLBYTE();
									if(have==0) goto inf_leave;
									have--;
									hold+=(uint)in_buf[next++]<<(int)bits;
									bits+=8;
								}

								//was DROPBITS(_this.bits);
								hold>>=here.bits;
								bits-=here.bits;

								state.lens[state.have++]=here.val;
							}
							else
							{
								if(here.val==16)
								{
									//was NEEDBITS(_this.bits+2);
									while(bits<here.bits+2)
									{
										//was PULLBYTE();
										if(have==0) goto inf_leave;
										have--;
										hold+=(uint)in_buf[next++]<<(int)bits;
										bits+=8;
									}

									//was DROPBITS(_this.bits);
									hold>>=here.bits;
									bits-=here.bits;

									if(state.have==0)
									{
										strm.msg="invalid bit length repeat";
										state.mode=inflate_mode.BAD;
										break;
									}
									len=state.lens[state.have-1];

									//was copy=3+BITS(2);
									copy=3+(hold&0x03);

									//was DROPBITS(2);
									hold>>=2;
									bits-=2;
								}
								else if(here.val==17)
								{
									//was NEEDBITS(_this.bits+3);
									while(bits<here.bits+3)
									{
										//was PULLBYTE();
										if(have==0) goto inf_leave;
										have--;
										hold+=(uint)in_buf[next++]<<(int)bits;
										bits+=8;
									}

									//was DROPBITS(_this.bits);
									hold>>=here.bits;
									bits-=here.bits;

									len=0;

									//was copy=3+BITS(3);
									copy=3+(hold&0x07);

									//was DROPBITS(3);
									hold>>=3;
									bits-=3;
								}
								else
								{
									//was NEEDBITS(_this.bits+7);
									while(bits<here.bits+7)
									{
										//was PULLBYTE();
										if(have==0) goto inf_leave;
										have--;
										hold+=(uint)in_buf[next++]<<(int)bits;
										bits+=8;
									}

									//was DROPBITS(_this.bits);
									hold>>=here.bits;
									bits-=here.bits;

									len=0;

									//was copy=11+BITS(7);
									copy=11+(hold&0x7F);

									//was DROPBITS(7);
									hold>>=7;
									bits-=7;
								}

								if(state.have+copy>state.nlen+state.ndist)
								{
									strm.msg="invalid bit length repeat";
									state.mode=inflate_mode.BAD;
									break;
								}

								while((copy--)!=0) state.lens[state.have++]=(ushort)len;
							}
						}

						// handle error breaks in while
						if(state.mode==inflate_mode.BAD) break;

						// check for end-of-block code (better have one)
						if(state.lens[256]==0)
						{
							strm.msg="invalid code -- missing end-of-block";
							state.mode=inflate_mode.BAD;
							break;
						}

						// build code tables -- note: do not change the lenbits or distbits
						// values here (9 and 6) without reading the comments in inftrees.h
						// concerning the ENOUGH constants, which depend on those values

						state.next=0;
						state.lencode=state.codes;
						state.lenbits=9;

						//was ret=inflate_table(codetype.LENS, state.lens, state.nlen, &(state.next), &(state.lenbits), state.work);
						ret=inflate_table(codetype.LENS, state.lens, 0, state.nlen, state.codes, ref state.next, ref state.lenbits, state.work);

						if(ret!=0)
						{
							strm.msg="invalid literal/lengths set";
							state.mode=inflate_mode.BAD;
							break;
						}

						//was state.distcode = (code const *)(state.next);
						state.distcode=state.codes;
						state.distcode_ind=state.next;

						state.distbits=6;

						//was ret=inflate_table(codetype.DISTS, state.lens+state.nlen, state.ndist, &(state.next), &(state.distbits), state.work);
						ret=inflate_table(codetype.DISTS, state.lens, (int)state.nlen, state.ndist, state.codes, ref state.next, ref state.distbits, state.work);

						if(ret!=0)
						{
							strm.msg="invalid distances set";
							state.mode=inflate_mode.BAD;
							break;
						}

						//Tracev((stderr, "inflate:       codes ok\n"));
						state.mode=inflate_mode.LEN_;
						if(flush==Z_TREES) goto inf_leave;
						break; // no fall through
					case inflate_mode.LEN_:
						state.mode=inflate_mode.LEN;
						break; // no fall through
					case inflate_mode.LEN:
						if(have>=6&&left>=258)
						{
							//was RESTORE();
							strm.next_out=put;
							strm.avail_out=left;
							strm.next_in=next;
							strm.avail_in=have;
							state.hold=hold;
							state.bits=bits;

							inflate_fast(strm, _out);

							//was LOAD();
							put=strm.next_out;
							left=strm.avail_out;
							next=strm.next_in;
							have=strm.avail_in;
							hold=state.hold;
							bits=state.bits;
							if(state.mode==inflate_mode.TYPE)
								state.back=-1;
							break;
						}
						state.back=0;
						for(; ; )
						{
							//was _this=state.lencode[BITS(state.lenbits)];
							here=state.lencode[hold&((1<<(int)state.lenbits)-1)];
							if(here.bits<=bits) break;

							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}
						if(here.op!=0&&(here.op&0xf0)==0)
						{
							last=here;
							for(; ; )
							{
								//was _this=state.lencode[last.val+(BITS(last.bits+last.op)>>last.bits)];
								here=state.lencode[last.val+((hold&((1<<(int)(last.bits+last.op))-1))>>last.bits)];
								if((last.bits+here.bits)<=bits) break;

								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							//was DROPBITS(last.bits);
							hold>>=last.bits;
							bits-=last.bits;
							state.back+=last.bits;
						}

						//was DROPBITS(here.bits);
						hold>>=here.bits;
						bits-=here.bits;

						state.back+=here.bits;
						state.length=here.val;
						if(here.op==0)
						{
							//Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate:         literal '%c'\n" : "inflate:         literal 0x%02x\n", this.val));
							state.mode=inflate_mode.LIT;
							break;
						}
						if((here.op&32)!=0)
						{
							//Tracevv((stderr, "inflate:         end of block\n"));
							state.back=-1;
							state.mode=inflate_mode.TYPE;
							break;
						}
						if((here.op&64)!=0)
						{
							strm.msg="invalid literal/length code";
							state.mode=inflate_mode.BAD;
							break;
						}
						state.extra=(uint)(here.op&15);
						state.mode=inflate_mode.LENEXT;
						break; // no fall through
					case inflate_mode.LENEXT:
						if(state.extra!=0)
						{
							//was NEEDBITS(state.extra);
							while(bits<state.extra)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							//was state.length+=BITS(state.extra);
							state.length+=(uint)(hold&((1<<(int)state.extra)-1));

							//was DROPBITS(state.extra);
							hold>>=(int)state.extra;
							bits-=state.extra;
							state.back+=(int)state.extra;
						}
						//Tracevv((stderr, "inflate:         length %u\n", state.length));
						state.was=state.length;
						state.mode=inflate_mode.DIST;
						break; // no fall through
					case inflate_mode.DIST:
						for(; ; )
						{
							//was _this=state.distcode[BITS(state.distbits)];
							here=state.distcode[state.distcode_ind+(hold&((1<<(int)state.distbits)-1))];
							if(here.bits<=bits) break;

							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}
						if((here.op&0xf0)==0)
						{
							last=here;
							for(; ; )
							{
								//was _this=state.distcode[last.val+(BITS(last.bits+last.op)>>last.bits)];
								here=state.distcode[state.distcode_ind+last.val+((hold&((1<<(int)(last.bits+last.op))-1))>>last.bits)];
								if((last.bits+here.bits)<=bits) break;

								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							//was DROPBITS(last.bits);
							hold>>=last.bits;
							bits-=last.bits;
							state.back+=last.bits;
						}

						//was DROPBITS(_this.bits);
						hold>>=here.bits;
						bits-=here.bits;
						state.back+=here.bits;

						if((here.op&64)!=0)
						{
							strm.msg="invalid distance code";
							state.mode=inflate_mode.BAD;
							break;
						}
						state.offset=here.val;
						state.extra=(uint)(here.op&15);
						state.mode=inflate_mode.DISTEXT;
						break; // no fall through
					case inflate_mode.DISTEXT:
						if(state.extra!=0)
						{
							//was NEEDBITS(state.extra);
							while(bits<state.extra)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							//was state.offset+=BITS(state.extra);
							state.offset+=(uint)(hold&((1<<(int)state.extra)-1));

							//was DROPBITS(state.extra);
							hold>>=(int)state.extra;
							bits-=state.extra;
							state.back+=(int)state.extra;
						}

						if(state.offset>state.dmax)
						{
							strm.msg="invalid distance too far back (STRICT)";
							state.mode=inflate_mode.BAD;
							break;
						}

						//Tracevv((stderr, "inflate:         distance %u\n", state.offset));
						state.mode=inflate_mode.MATCH;
						break; // no fall through
					case inflate_mode.MATCH:
						if(left==0) goto inf_leave;

						copy=_out-left;
						if(state.offset>copy)
						{ // copy from window
							copy=state.offset-copy;
							if(copy>state.whave)
							{
								if(state.sane)
								{
									strm.msg="invalid distance too far back";
									state.mode=inflate_mode.BAD;
									break;
								}
#if INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
								//Trace((stderr, "inflate.c too far\n"));
								copy-=state.whave;
								if(copy>state.length) copy=state.length;
								if(copy>left) copy=left;
								left-=copy;
								state.length-=copy;
								do
								{
									out_buf[put++]=0;
								} while(--copy!=0);
								if(state.length==0) state.mode=inflate_mode.LEN;
								break;
#endif
							}
							if(copy>state.wnext)
							{
								copy-=state.wnext;
								from=state.window;
								from_ind=(int)(state.wsize-copy);
							}
							else
							{
								from=state.window;
								from_ind=(int)(state.wnext-copy);
							}
							if(copy>state.length) copy=state.length;
						}
						else
						{ // copy from output
							from=out_buf;
							from_ind=(int)(put-state.offset);
							copy=state.length;
						}
						if(copy>left) copy=left;
						left-=copy;
						state.length-=copy;
						do
						{
							out_buf[put++]=from[from_ind++];
						} while(--copy!=0);
						if(state.length==0) state.mode=inflate_mode.LEN;
						break;
					case inflate_mode.LIT:
						if(left==0) goto inf_leave;
						out_buf[put++]=(byte)(state.length);
						left--;
						state.mode=inflate_mode.LEN;
						break;
					case inflate_mode.CHECK:
						if(state.wrap!=0)
						{
							//was NEEDBITS(32);
							while(bits<32)
							{
								//was PULLBYTE();
								if(have==0) goto inf_leave;
								have--;
								hold+=(uint)in_buf[next++]<<(int)bits;
								bits+=8;
							}

							_out-=left;
							strm.total_out+=_out;
							state.total+=_out;
							if(out_buf!=null) strm.adler=state.check=(state.flags!=0?crc32(state.check, out_buf, (uint)(put-_out), _out):adler32(state.check, out_buf, (uint)(put-_out), _out));

							_out=left;
							//was if((state.flags ? hold :REVERSE(hold))!=state.check)
							if((state.flags!=0?hold:((hold>>24)&0xff)+((hold>>8)&0xff00)+((hold&0xff00)<<8)+((hold&0xff)<<24))!=state.check)
							{
								strm.msg="incorrect data check";
								state.mode=inflate_mode.BAD;
								break;
							}

							//was INITBITS();
							hold=bits=0;

							//Tracev((stderr, "inflate:   check matches trailer\n"));
						}

						state.mode=(state.wrap!=0&&state.flags!=0?inflate_mode.LENGTH:inflate_mode.DONE);

						break; // no fall through
					case inflate_mode.LENGTH:
						//was NEEDBITS(32);
						while(bits<32)
						{
							//was PULLBYTE();
							if(have==0) goto inf_leave;
							have--;
							hold+=(uint)in_buf[next++]<<(int)bits;
							bits+=8;
						}

						if(hold!=(state.total&0xffffffffU))
						{
							strm.msg="incorrect length check";
							state.mode=inflate_mode.BAD;
							break;
						}

						//was INITBITS();
						hold=bits=0;

						//Tracev((stderr, "inflate:   length matches trailer\n"));

						state.mode=inflate_mode.DONE;
						break; // no fall through
					case inflate_mode.DONE:
						ret=Z_STREAM_END;
						goto inf_leave;
					case inflate_mode.BAD:
						ret=Z_DATA_ERROR;
						goto inf_leave;
					case inflate_mode.MEM: return Z_MEM_ERROR;
					case inflate_mode.SYNC: return Z_STREAM_ERROR;
					default: return Z_STREAM_ERROR;
				} // switch(state.mode)
			} // for(; ; )

// Return from inflate(), updating the total counts and the check value.
// If there was no progress during the inflate() call, return a buffer
// error.  Call updatewindow() to create and/or update the window state.
// Note: a memory error from inflate() is non-recoverable.

inf_leave:
			//was RESTORE();
			strm.next_out=put;
			strm.avail_out=left;
			strm.next_in=next;
			strm.avail_in=have;
			state.hold=hold;
			state.bits=bits;

			if(state.wsize!=0||(state.mode<inflate_mode.CHECK&&_out!=strm.avail_out))
			{
				if(updatewindow(strm, _out)!=0)
				{
					state.mode=inflate_mode.MEM;
					return Z_MEM_ERROR;
				}
			}
			_in-=strm.avail_in;
			_out-=strm.avail_out;
			strm.total_in+=_in;
			strm.total_out+=_out;
			state.total+=_out;
			if(state.wrap!=0&&_out!=0) strm.adler=state.check=(state.flags!=0?crc32(state.check, out_buf, (uint)(strm.next_out-_out), _out):adler32(state.check, out_buf, (uint)(strm.next_out-_out), _out));

			//??? strm.data_type=state.bits+(state.last!=0?64:0)+(state.mode==inflate_mode.TYPE?128:0);

			if(((_in==0&&_out==0)||flush==Z_FINISH)&&ret==Z_OK) ret=Z_BUF_ERROR;

			return ret;
		}
コード例 #32
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   This is another version of deflateInit with more compression options. The
		// fields next_in, zalloc, zfree and opaque must be initialized before by
		// the caller.

		//   The method parameter is the compression method. It must be Z_DEFLATED in
		// this version of the library.

		//   The windowBits parameter is the base two logarithm of the window size
		// (the size of the history buffer). It should be in the range 8..15 for this
		// version of the library. Larger values of this parameter result in better
		// compression at the expense of memory usage. The default value is 15 if
		// deflateInit is used instead.

		//   windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
		// determines the window size. deflate() will then generate raw deflate data
		// with no zlib header or trailer, and will not compute an adler32 check value.

		//   windowBits can also be greater than 15 for optional gzip encoding. Add
		// 16 to windowBits to write a simple gzip header and trailer around the
		// compressed data instead of a zlib wrapper. The gzip header will have no
		// file name, no extra data, no comment, no modification time (set to zero),
		// no header crc, and the operating system will be set to 255 (unknown).  If a
		// gzip stream is being written, strm.adler is a crc32 instead of an adler32.

		//   The memLevel parameter specifies how much memory should be allocated
		// for the internal compression state. memLevel=1 uses minimum memory but
		// is slow and reduces compression ratio; memLevel=9 uses maximum memory
		// for optimal speed. The default value is 8. See zconf.h for total memory
		// usage as a function of windowBits and memLevel.

		//   The strategy parameter is used to tune the compression algorithm. Use the
		// value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
		// filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
		// string match), or Z_RLE to limit match distances to one (run-length
		// encoding). Filtered data consists mostly of small values with a somewhat
		// random distribution. In this case, the compression algorithm is tuned to
		// compress them better. The effect of Z_FILTERED is to force more Huffman
		// coding and less string matching; it is somewhat intermediate between
		// Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
		// Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
		// parameter only affects the compression ratio but not the correctness of the
		// compressed output even if it is not set appropriately.  Z_FIXED prevents the
		// use of dynamic Huffman codes, allowing for a simpler decoder for special
		// applications.

		//    deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
		// memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
		// method). msg is set to null if there is no error message.  deflateInit2 does
		// not perform any compression: this will be done by deflate().

		public static int deflateInit2(z_stream strm, int level, int method, int windowBits, int memLevel, int strategy)
		{
			if(strm==null) return Z_STREAM_ERROR;
			strm.msg=null;

			if(level==Z_DEFAULT_COMPRESSION) level=6;

			int wrap=1;

			if(windowBits<0)
			{ // suppress zlib wrapper
				wrap=0;
				windowBits=-windowBits;
			}
			else if(windowBits>15)
			{
				wrap=2;       // write gzip wrapper instead
				windowBits-=16;
			}

			if(memLevel<1||memLevel>MAX_MEM_LEVEL||method!=Z_DEFLATED||windowBits<8||windowBits>15||level<0||level>9||
				strategy<0||strategy>Z_FIXED) return Z_STREAM_ERROR;

			if(windowBits==8) windowBits=9;  // until 256-byte window bug fixed

			deflate_state s;
			try
			{
				s=new deflate_state();
			}
			catch(Exception)
			{
				return Z_MEM_ERROR;
			}

			strm.state=s;
			s.strm=strm;

			s.wrap=wrap;
			s.w_bits=(uint)windowBits;
			s.w_size=1U<<(int)s.w_bits;
			s.w_mask=s.w_size-1;

			s.hash_bits=(uint)memLevel+7;
			s.hash_size=1U<<(int)s.hash_bits;
			s.hash_mask=s.hash_size-1;
			s.hash_shift=(s.hash_bits+MIN_MATCH-1)/MIN_MATCH;

			try
			{
				s.window=new byte[s.w_size*2];
				s.prev=new ushort[s.w_size];
				s.head=new ushort[s.hash_size];
				s.high_water=0; // nothing written to s->window yet

				s.lit_bufsize=1U<<(memLevel+6); // 16K elements by default

				s.pending_buf=new byte[s.lit_bufsize*4];
				s.pending_buf_size=s.lit_bufsize*4;

				s.d_buf=new ushort[s.lit_bufsize];
				s.l_buf=new byte[s.lit_bufsize];
			}
			catch(Exception)
			{
				s.status=FINISH_STATE;
				strm.msg=zError(Z_MEM_ERROR);
				deflateEnd(strm);
				return Z_MEM_ERROR;
			}

			s.level=level;
			s.strategy=strategy;
			s.method=(byte)method;

			return deflateReset(strm);
		}
コード例 #33
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		// Flush as much pending output as possible. All deflate() output goes
		// through this function so some applications may wish to modify it
		// to avoid allocating a large strm.next_out buffer and copying into it.
		// (See also read_buf()).
		static void flush_pending(z_stream strm)
		{
			deflate_state s=(deflate_state)strm.state;
			uint len=s.pending;

			if(len>strm.avail_out) len=strm.avail_out;
			if(len==0) return;

			//was memcpy(strm.next_out, s.pending_out, len);
			Array.Copy(s.pending_buf, s.pending_out, strm.out_buf, strm.next_out, len);

			strm.next_out+=(int)len;
			s.pending_out+=(int)len;
			strm.total_out+=len;
			strm.avail_out-=len;
			s.pending-=len;
			if(s.pending==0) s.pending_out=0;
		}
コード例 #34
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//   Skips invalid compressed data until a full flush point (see above the
		// description of deflate with Z_FULL_FLUSH) can be found, or until all
		// available input is skipped. No output is provided.

		//   inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
		// if no more input was provided, Z_DATA_ERROR if no flush point has been found,
		// or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
		// case, the application may save the current current value of total_in which
		// indicates where valid compressed data was found. In the error case, the
		// application may repeatedly call inflateSync, providing more input each time,
		// until success or end of the input data.

		public static int inflateSync(z_stream strm)
		{
			uint len;					// number of bytes to look at or looked at
			uint _in, _out;				// temporary to save total_in and total_out
			byte[] buf=new byte[4];		// to restore bit buffer to byte string

			// check parameters
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			inflate_state state=(inflate_state)strm.state;
			if(strm.avail_in==0&&state.bits<8) return Z_BUF_ERROR;

			// if first time, start search in bit buffer
			if(state.mode!=inflate_mode.SYNC)
			{
				state.mode=inflate_mode.SYNC;
				state.hold<<=(int)(state.bits&7);
				state.bits-=state.bits&7;
				len=0;
				while(state.bits>=8)
				{
					buf[len++]=(byte)state.hold;
					state.hold>>=8;
					state.bits-=8;
				}
				state.have=0;
				syncsearch(ref state.have, buf, 0, len);
			}

			// search available input
			len=syncsearch(ref state.have, strm.in_buf, strm.next_in, strm.avail_in);
			strm.avail_in-=len;
			strm.next_in+=len;
			strm.total_in+=len;

			// return no joy or set up to restart inflate() on a new block
			if(state.have!=4) return Z_DATA_ERROR;
			_in=strm.total_in; _out=strm.total_out;
			inflateReset(strm);
			strm.total_in=_in; strm.total_out=_out;
			state.mode=inflate_mode.TYPE;
			return Z_OK;
		}
コード例 #35
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   Dynamically update the compression level and compression strategy.  The
		// interpretation of level and strategy is as in deflateInit2.  This can be
		// used to switch between compression and straight copy of the input data, or
		// to switch to a different kind of input data requiring a different
		// strategy. If the compression level is changed, the input available so far
		// is compressed with the old level (and may be flushed); the new level will
		// take effect only at the next call of deflate().

		//   Before the call of deflateParams, the stream state must be set as for
		// a call of deflate(), since the currently available input may have to
		// be compressed and flushed. In particular, strm.avail_out must be non-zero.

		//   deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
		// stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
		// if strm.avail_out was zero.

		public static int deflateParams(z_stream strm, int level, int strategy)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			deflate_state s=(deflate_state)strm.state;

			if(level==Z_DEFAULT_COMPRESSION) level=6;
			if(level<0||level>9||strategy<0||strategy>Z_FIXED) return Z_STREAM_ERROR;

			compress_func func=configuration_table[s.level].func;
			int err=Z_OK;

			if((strategy!=s.strategy||func!=configuration_table[level].func)&&strm.total_in!=0) // Flush the last buffer:
				err=deflate(strm, Z_BLOCK);

			if(s.level!=level)
			{
				s.level=level;
				s.max_lazy_match=configuration_table[level].max_lazy;
				s.good_match=configuration_table[level].good_length;
				s.nice_match=configuration_table[level].nice_length;
				s.max_chain_length=configuration_table[level].max_chain;
			}

			s.strategy=strategy;
			return err;
		}
コード例 #36
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//    deflatePrime() inserts bits in the deflate output stream.  The intent
		// is that this function is used to start off the deflate output with the
		// bits leftover from a previous deflate stream when appending to it.  As such,
		// this function can only be used for raw deflate, and must be used before the
		// first deflate() call after a deflateInit2() or deflateReset().  bits must be
		// less than or equal to 16, and that many of the least significant bits of
		// value will be inserted in the output.

		//    deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
		// stream state was inconsistent.

		public static int deflatePrime(z_stream strm, int bits, int value)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			deflate_state s=(deflate_state)strm.state;
			s.bi_valid=bits;
			s.bi_buf=(ushort)(value&((1<<bits)-1));
			return Z_OK;
		}
コード例 #37
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//    deflateSetHeader() provides gzip header information for when a gzip
		// stream is requested by deflateInit2().  deflateSetHeader() may be called
		// after deflateInit2() or deflateReset() and before the first call of
		// deflate().  The text, time, os, extra field, name, and comment information
		// in the provided gz_header structure are written to the gzip header (xflag is
		// ignored -- the extra flags are set according to the compression level).  The
		// caller must assure that, if not Z_NULL, name and comment are terminated with
		// a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
		// available there.  If hcrc is true, a gzip header crc is included.  Note that
		// the current versions of the command-line version of gzip (up through version
		// 1.3.x) do not support header crc's, and will report that it is a "multi-part
		// gzip file" and give up.

		//    If deflateSetHeader is not used, the default gzip header has text false,
		// the time set to zero, and os set to 255, with no extra, name, or comment
		// fields.  The gzip header is returned to the default state by deflateReset().

		//    deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
		// stream state was inconsistent.

		public static int deflateSetHeader(z_stream strm, gz_header head)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			deflate_state s=(deflate_state)strm.state;
			if(s.wrap!=2) return Z_STREAM_ERROR;
			s.gzhead=head;
			return Z_OK;
		}
コード例 #38
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//   Initializes the internal stream state for decompression. The fields
		// next_in, avail_in, zalloc, zfree and opaque must be initialized before by
		// the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
		// value depends on the compression method), inflateInit determines the
		// compression method from the zlib header and allocates all data structures
		// accordingly; otherwise the allocation will be deferred to the first call of
		// inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
		// use default allocation functions.

		//   inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
		// memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
		// version assumed by the caller.  msg is set to null if there is no error
		// message. inflateInit does not perform any decompression apart from reading
		// the zlib header if present: this will be done by inflate().  (So next_in and
		// avail_in may be modified, but next_out and avail_out are unchanged.)
		public static int inflateInit(z_stream strm)
		{
			return inflateInit2(strm, DEF_WBITS);
		}
コード例 #39
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		public static long inflateMark(z_stream strm)
		{
			if(strm==null||strm.state==null) return -1L<<16;
			inflate_state state=(inflate_state)strm.state;
			return ((long)(state.back)<<16)+
				(state.mode==inflate_mode.COPY?state.length:(state.mode==inflate_mode.MATCH?state.was-state.length:0));
		}
コード例 #40
0
ファイル: inflate.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        /*
         * Update the window with the last wsize (normally 32K) bytes written before
         * returning.  If window does not exist yet, create it.  This is only called
         * when a window is already in use, or when output has been written during this
         * inflate call, but the end of the deflate stream has not been reached yet.
         * It is also called to create a window for dictionary data when a dictionary
         * is loaded.
         *
         * Providing output buffers larger than 32K to inflate() should provide a speed
         * advantage, since only the last 32K of output is copied to the sliding window
         * upon return from inflate(), and since all distances after the first 32K of
         * output will fall in the output data, making match copies simpler and faster.
         * The advantage may be dependent on the size of the processor's data caches.
         */
        private static int updatewindow(
            z_stream strm,
            byte[] end_array,
            long end_index,
            uint copy)
        {
            inflate_state state;
            uint          dist;

            state = strm.state;

            /* if it hasn't been done already, allocate space for the window */
            if (state.window == null)
            {
                state.window = new byte[1U << (int)state.wbits];
                if (state.window == null)
                {
                    return(1);
                }
            }

            /* if window not in use yet, initialize */
            if (state.wsize == 0)
            {
                state.wsize = 1U << (int)state.wbits;
                state.wnext = 0;
                state.whave = 0;
            }

            /* copy state.wsize or less output bytes into the circular window */
            if (copy >= state.wsize)
            {
                zutil.zmemcpy(state.window, 0, end_array, end_index - state.wsize, state.wsize);
                state.wnext = 0;
                state.whave = state.wsize;
            }
            else
            {
                dist = state.wsize - state.wnext;
                if (dist > copy)
                {
                    dist = copy;
                }
                zutil.zmemcpy(state.window, state.wnext, end_array, end_index - copy, dist);
                copy -= dist;
                if (copy != 0)
                {
                    zutil.zmemcpy(state.window, 0, end_array, end_index - copy, copy);
                    state.wnext = copy;
                    state.whave = state.wsize;
                }
                else
                {
                    state.wnext += dist;
                    if (state.wnext == state.wsize)
                    {
                        state.wnext = 0;
                    }
                    if (state.whave < state.wsize)
                    {
                        state.whave += dist;
                    }
                }
            }
            return(0);
        }
コード例 #41
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//   Sets the destination stream as a complete copy of the source stream.

		//   This function can be useful when randomly accessing a large stream.  The
		// first pass through the stream can periodically record the inflate state,
		// allowing restarting inflate at those points when randomly accessing the
		// stream.

		//   inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
		// enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
		// (such as zalloc being NULL). msg is left unchanged in both source and
		// destination.

		public static int inflateCopy(z_stream dest, z_stream source)
		{
			// check input
			if(dest==null||source==null||source.state==null) return Z_STREAM_ERROR;
			inflate_state state=(inflate_state)source.state;

			// allocate space
			inflate_state copy=null;

			try
			{
				copy=state.GetCopy();
			}
			catch(Exception)
			{
				copy=null;
				return Z_MEM_ERROR;
			}

			source.CopyTo(dest); // copy state
			dest.state=copy;
			return Z_OK;
		}
コード例 #42
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		//   This is another version of inflateInit with an extra parameter. The
		// fields next_in, avail_in, zalloc, zfree and opaque must be initialized
		// before by the caller.

		//   The windowBits parameter is the base two logarithm of the maximum window
		// size (the size of the history buffer).  It should be in the range 8..15 for
		// this version of the library. The default value is 15 if inflateInit is used
		// instead. windowBits must be greater than or equal to the windowBits value
		// provided to deflateInit2() while compressing, or it must be equal to 15 if
		// deflateInit2() was not used. If a compressed stream with a larger window
		// size is given as input, inflate() will return with the error code
		// Z_DATA_ERROR instead of trying to allocate a larger window.

		//   windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
		// determines the window size. inflate() will then process raw deflate data,
		// not looking for a zlib or gzip header, not generating a check value, and not
		// looking for any check values for comparison at the end of the stream. This
		// is for use with other formats that use the deflate compressed data format
		// such as zip.  Those formats provide their own check values. If a custom
		// format is developed using the raw deflate format for compressed data, it is
		// recommended that a check value such as an adler32 or a crc32 be applied to
		// the uncompressed data as is done in the zlib, gzip, and zip formats.  For
		// most applications, the zlib format should be used as is. Note that comments
		// above on the use in deflateInit2() applies to the magnitude of windowBits.

		//   windowBits can also be greater than 15 for optional gzip decoding. Add
		// 32 to windowBits to enable zlib and gzip decoding with automatic header
		// detection, or add 16 to decode only the gzip format (the zlib format will
		// return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm.adler is
		// a crc32 instead of an adler32.

		//   inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
		// memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
		// is set to null if there is no error message.  inflateInit2 does not perform
		// any decompression apart from reading the zlib header if present: this will
		// be done by inflate(). (So next_in and avail_in may be modified, but next_out
		// and avail_out are unchanged.)

		public static int inflateInit2(z_stream strm, int windowBits)
		{
			if(strm==null) return Z_STREAM_ERROR;
			strm.msg=null;                 // in case we return an error

			inflate_state state;
			try
			{
				state=new inflate_state();
			}
			catch(Exception)
			{
				return Z_MEM_ERROR;
			}

			//Tracev((stderr, "inflate: allocated\n"));
			strm.state=state;
			state.window=null;
			int ret=inflateReset2(strm, windowBits);
			if(ret!=Z_OK) strm.state=null;

			return ret;
		}
コード例 #43
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   Initializes the compression dictionary from the given byte sequence
		// without producing any compressed output. This function must be called
		// immediately after deflateInit, deflateInit2 or deflateReset, before any
		// call of deflate. The compressor and decompressor must use exactly the same
		// dictionary (see inflateSetDictionary).

		//   The dictionary should consist of strings (byte sequences) that are likely
		// to be encountered later in the data to be compressed, with the most commonly
		// used strings preferably put towards the end of the dictionary. Using a
		// dictionary is most useful when the data to be compressed is short and can be
		// predicted with good accuracy; the data can then be compressed better than
		// with the default empty dictionary.

		//   Depending on the size of the compression data structures selected by
		// deflateInit or deflateInit2, a part of the dictionary may in effect be
		// discarded, for example if the dictionary is larger than the window size in
		// deflate or deflate2. Thus the strings most likely to be useful should be
		// put at the end of the dictionary, not at the front. In addition, the
		// current implementation of deflate will use at most the window size minus
		// 262 bytes of the provided dictionary.

		//   Upon return of this function, strm.adler is set to the adler32 value
		// of the dictionary; the decompressor may later use this value to determine
		// which dictionary has been used by the compressor. (The adler32 value
		// applies to the whole dictionary even if only a subset of the dictionary is
		// actually used by the compressor.) If a raw deflate was requested, then the
		// adler32 value is not computed and strm.adler is not set.

		//   deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
		// parameter is invalid (such as NULL dictionary) or the stream state is
		// inconsistent (for example if deflate has already been called for this stream
		// or if the compression method is bsort). deflateSetDictionary does not
		// perform any compression: this will be done by deflate().

		public static int deflateSetDictionary(z_stream strm, byte[] dictionary, uint dictLength)
		{
			uint length=dictLength;
			uint n;
			uint hash_head=0;

			if(strm==null||strm.state==null||dictionary==null) return Z_STREAM_ERROR;

			deflate_state s=strm.state as deflate_state;
			if(s==null||s.wrap==2||(s.wrap==1&&s.status!=INIT_STATE))
				return Z_STREAM_ERROR;

			if(s.wrap!=0) strm.adler=adler32(strm.adler, dictionary, dictLength);

			if(length<MIN_MATCH) return Z_OK;

			int dictionary_ind=0;
			if(length>s.w_size)
			{
				length=s.w_size;
				dictionary_ind=(int)(dictLength-length); // use the tail of the dictionary
			}

			//was memcpy(s.window, dictionary+dictionary_ind, length);
			Array.Copy(dictionary, dictionary_ind, s.window, 0, length);

			s.strstart=length;
			s.block_start=(int)length;

			// Insert all strings in the hash table (except for the last two bytes).
			// s.lookahead stays null, so s.ins_h will be recomputed at the next
			// call of fill_window.
			s.ins_h=s.window[0];

			//was UPDATE_HASH(s, s.ins_h, s.window[1]);
			s.ins_h=((s.ins_h<<(int)s.hash_shift)^s.window[1])&s.hash_mask;

			for(n=0; n<=length-MIN_MATCH; n++)
			{
				//was INSERT_STRING(s, n, hash_head);
				s.ins_h=((s.ins_h<<(int)s.hash_shift)^s.window[n+(MIN_MATCH-1)])&s.hash_mask;
				hash_head=s.prev[n&s.w_mask]=s.head[s.ins_h];
				s.head[s.ins_h]=(ushort)n;
			}
			if(hash_head!=0) hash_head=0;  // to make compiler happy
			return Z_OK;
		}
コード例 #44
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// ===========================================================================
		// Read a new buffer from the current input stream, update the adler32
		// and total number of bytes read.  All deflate() input goes through
		// this function so some applications may wish to modify it to avoid
		// allocating a large strm.next_in buffer and copying from it.
		// (See also flush_pending()).
		static int read_buf(z_stream strm, byte[] buf, uint size)
		{
			return read_buf(strm, buf, 0, size);
		}
コード例 #45
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   Sets the destination stream as a complete copy of the source stream.

		//   This function can be useful when several compression strategies will be
		// tried, for example when there are several ways of pre-processing the input
		// data with a filter. The streams that will be discarded should then be freed
		// by calling deflateEnd.  Note that deflateCopy duplicates the internal
		// compression state which can be quite large, so this strategy is slow and
		// can consume lots of memory.

		//   deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
		// enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
		// (such as zalloc being NULL). msg is left unchanged in both source and
		// destination.

		// Copy the source state to the destination state.
		public static int deflateCopy(z_stream dest, z_stream source)
		{
			if(source==null||dest==null||source.state==null) return Z_STREAM_ERROR;

			deflate_state ss=(deflate_state)source.state;

			//was memcpy(dest, source, sizeof(z_stream));
			source.CopyTo(dest);

			deflate_state ds;
			try
			{
				ds=ss.Clone();
			}
			catch(Exception)
			{
				return Z_MEM_ERROR;
			}
			dest.state=ds;
			//(done above) memcpy(ds, ss, sizeof(deflate_state));
			ds.strm=dest;

			try
			{
				ds.window=new byte[ds.w_size*2];
				ds.prev=new ushort[ds.w_size];
				ds.head=new ushort[ds.hash_size];
				ds.pending_buf=new byte[ds.lit_bufsize*4];
				ds.d_buf=new ushort[ds.lit_bufsize];
				ds.l_buf=new byte[ds.lit_bufsize];
			}
			catch(Exception)
			{
				deflateEnd(dest);
				return Z_MEM_ERROR;
			}

			//was memcpy(ds.window, ss.window, ds.w_size*2*sizeof(byte));
			ss.window.CopyTo(ds.window, 0);

			//was memcpy(ds.prev, ss.prev, ds.w_size*sizeof(ushort));
			ss.prev.CopyTo(ds.prev, 0);
			
			//was memcpy(ds.head, ss.head, ds.hash_size*sizeof(ushort));
			ss.head.CopyTo(ds.head, 0);

			//was memcpy(ds.pending_buf, ss.pending_buf, (uint)ds.pending_buf_size);
			ss.pending_buf.CopyTo(ds.pending_buf, 0);
			ss.d_buf.CopyTo(ds.d_buf, 0);
			ss.l_buf.CopyTo(ds.l_buf, 0);

			ds.l_desc.dyn_tree=ds.dyn_ltree;
			ds.d_desc.dyn_tree=ds.dyn_dtree;
			ds.bl_desc.dyn_tree=ds.bl_tree;

			return Z_OK;
		}
コード例 #46
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		public static int inflateUndermine(z_stream strm, bool subvert)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			inflate_state state=(inflate_state)strm.state;
			state.sane=!subvert;
#if INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
			return Z_OK;
#else
			state.sane=true;
			return Z_DATA_ERROR;
#endif
		}
コード例 #47
0
        public int run(z_stream _strm, int _flush)
        {
            this.strm  = _strm;
            this.flush = _flush;
            if (inflateStateCheck(strm) != 0 || strm.output_buffer == null ||
                (strm.input_buffer == null && strm.avail_in != 0))
            {
                return(zlib.Z_STREAM_ERROR);
            }

            state = strm.state;
            if (state.mode == inflate_mode.TYPE)
            {
                state.mode = inflate_mode.TYPEDO;                               /* skip check */
            }
            LOAD();
            @in  = have;
            @out = left;
            ret  = zlib.Z_OK;
            for (;;)
            {
                switch (state.mode)
                {
                case inflate_mode.HEAD:
                    if (state.wrap == 0)
                    {
                        state.mode = inflate_mode.TYPEDO;
                        break;
                    }
                    if (NEEDBITS_(16))
                    {
                        goto inf_leave;
                    }
//#ifdef GUNZIP
                    if ((state.wrap & 2) != 0 && hold == 0x8b1f) /* gzip header */
                    {
                        if (state.wbits == 0)
                        {
                            state.wbits = 15;
                        }
                        state.check = crc32.crc32_(0L, null, 0, 0);
                        CRC2(state.check, hold);
                        INITBITS();
                        state.mode = inflate_mode.FLAGS;
                        break;
                    }
                    state.flags = 0;   /* expect zlib header */
                    if (state.head != null)
                    {
                        state.head.done = -1;
                    }
                    if (!((state.wrap & 1) != 0) || /* check if zlib header allowed */
//#else
//            if (
//#endif
                        (((BITS(8) << 8) + (hold >> 8)) % 31) != 0)
                    {
                        strm.msg   = "incorrect header check";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    if (BITS(4) != zlib.Z_DEFLATED)
                    {
                        strm.msg   = "unknown compression method";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    DROPBITS(4);
                    len = BITS(4) + 8;
                    if (state.wbits == 0)
                    {
                        state.wbits = len;
                    }
                    if (len > 15 || len > state.wbits)
                    {
                        strm.msg   = "invalid window size";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    state.dmax = 1U << (int)len;
                    //Tracev((stderr, "inflate:   zlib header ok\n"));
                    strm.adler = state.check = adler32.adler32_(0L, null, 0, 0);
                    state.mode = (hold & 0x200) != 0 ? inflate_mode.DICTID : inflate_mode.TYPE;
                    INITBITS();
                    break;

//#ifdef GUNZIP
                case inflate_mode.FLAGS:
                    if (NEEDBITS_(16))
                    {
                        goto inf_leave;
                    }
                    state.flags = (int)(hold);
                    if ((state.flags & 0xff) != zlib.Z_DEFLATED)
                    {
                        strm.msg   = "unknown compression method";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    if ((state.flags & 0xe000) != 0)
                    {
                        strm.msg   = "unknown header flags set";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    if (state.head != null)
                    {
                        state.head.text = (int)((hold >> 8) & 1);
                    }
                    if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                    {
                        CRC2(state.check, hold);
                    }
                    INITBITS();
                    state.mode = inflate_mode.TIME;
                    goto case inflate_mode.TIME;

                case inflate_mode.TIME:
                    if (NEEDBITS_(32))
                    {
                        goto inf_leave;
                    }
                    if (state.head != null)
                    {
                        state.head.time = hold;
                    }
                    if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                    {
                        CRC4(state.check, hold);
                    }
                    INITBITS();
                    state.mode = inflate_mode.OS;
                    goto case inflate_mode.OS;

                case inflate_mode.OS:
                    if (NEEDBITS_(16))
                    {
                        goto inf_leave;
                    }
                    if (state.head != null)
                    {
                        state.head.xflags = (int)(hold & 0xff);
                        state.head.os     = (int)(hold >> 8);
                    }
                    if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                    {
                        CRC2(state.check, hold);
                    }
                    INITBITS();
                    state.mode = inflate_mode.EXLEN;
                    goto case inflate_mode.EXLEN;

                case inflate_mode.EXLEN:
                    if ((state.flags & 0x0400) != 0)
                    {
                        if (NEEDBITS_(16))
                        {
                            goto inf_leave;
                        }
                        state.length = (uint)(hold);
                        if (state.head != null)
                        {
                            state.head.extra_len = (uint)hold;
                        }
                        if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                        {
                            CRC2(state.check, hold);
                        }
                        INITBITS();
                    }
                    else if (state.head != null)
                    {
                        state.head.extra = null;
                    }
                    state.mode = inflate_mode.EXTRA;
                    goto case inflate_mode.EXTRA;

                case inflate_mode.EXTRA:
                    if ((state.flags & 0x0400) != 0)
                    {
                        copy = state.length;
                        if (copy > have)
                        {
                            copy = have;
                        }
                        if (copy != 0)
                        {
                            if (state.head != null &&
                                state.head.extra != null)
                            {
                                len = state.head.extra_len - state.length;
                                zutil.zmemcpy(state.head.extra, len, next_buffer, next_index,
                                              len + copy > state.head.extra_max ?
                                              state.head.extra_max - len : copy);
                            }
                            if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                            {
                                state.check = crc32.crc32_(state.check, next_buffer, next_index, copy);
                            }
                            have         -= copy;
                            next_index   += copy;
                            state.length -= copy;
                        }
                        if (state.length != 0)
                        {
                            goto inf_leave;
                        }
                    }
                    state.length = 0;
                    state.mode   = inflate_mode.NAME;
                    goto case inflate_mode.NAME;

                case inflate_mode.NAME:
                    if ((state.flags & 0x0800) != 0)
                    {
                        if (have == 0)
                        {
                            goto inf_leave;
                        }
                        copy = 0;
                        do
                        {
                            len = (uint)(next_buffer[next_index + copy++]);
                            if (state.head != null &&
                                state.head.name != null &&
                                state.length < state.head.name_max)
                            {
                                state.head.name[state.length++] = (byte)len;
                            }
                        } while (len != 0 && copy < have);
                        if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                        {
                            state.check = crc32.crc32_(state.check, next_buffer, next_index, copy);
                        }
                        have       -= copy;
                        next_index += copy;
                        if (len != 0)
                        {
                            goto inf_leave;
                        }
                    }
                    else if (state.head != null)
                    {
                        state.head.name = null;
                    }
                    state.length = 0;
                    state.mode   = inflate_mode.COMMENT;
                    goto case inflate_mode.COMMENT;

                case inflate_mode.COMMENT:
                    if ((state.flags & 0x1000) != 0)
                    {
                        if (have == 0)
                        {
                            goto inf_leave;
                        }
                        copy = 0;
                        do
                        {
                            len = (uint)(next_buffer[next_index + copy++]);
                            if (state.head != null &&
                                state.head.comment != null &&
                                state.length < state.head.comm_max)
                            {
                                state.head.comment[state.length++] = (byte)len;
                            }
                        } while (len != 0 && copy < have);
                        if ((state.flags & 0x0200) != 0 && (state.wrap & 4) != 0)
                        {
                            state.check = crc32.crc32_(state.check, next_buffer, next_index, copy);
                        }
                        have       -= copy;
                        next_index += copy;
                        if (len != 0)
                        {
                            goto inf_leave;
                        }
                    }
                    else if (state.head != null)
                    {
                        state.head.comment = null;
                    }
                    state.mode = inflate_mode.HCRC;
                    goto case inflate_mode.HCRC;

                case inflate_mode.HCRC:
                    if ((state.flags & 0x0200) != 0)
                    {
                        if (NEEDBITS_(16))
                        {
                            goto inf_leave;
                        }
                        if ((state.wrap & 4) != 0 && hold != (state.check & 0xffff))
                        {
                            strm.msg   = "header crc mismatch";
                            state.mode = inflate_mode.BAD;
                            break;
                        }
                        INITBITS();
                    }
                    if (state.head != null)
                    {
                        state.head.hcrc = (int)((state.flags >> 9) & 1);
                        state.head.done = 1;
                    }
                    strm.adler = state.check = crc32.crc32_(0L, null, 0, 0);
                    state.mode = inflate_mode.TYPE;
                    break;

//#endif
                case inflate_mode.DICTID:
                    if (NEEDBITS_(32))
                    {
                        goto inf_leave;
                    }
                    strm.adler = state.check = zutil.ZSWAP32((uint)hold);
                    INITBITS();
                    state.mode = inflate_mode.DICT;
                    goto case inflate_mode.DICT;

                case inflate_mode.DICT:
                    if (state.havedict == 0)
                    {
                        RESTORE();
                        return(zlib.Z_NEED_DICT);
                    }
                    strm.adler = state.check = adler32.adler32_(0L, null, 0, 0);
                    state.mode = inflate_mode.TYPE;
                    goto case inflate_mode.TYPE;

                case inflate_mode.TYPE:
                    if (flush == zlib.Z_BLOCK || flush == zlib.Z_TREES)
                    {
                        goto inf_leave;
                    }
                    goto case inflate_mode.TYPEDO;

                case inflate_mode.TYPEDO:
                    if (state.last != 0)
                    {
                        BYTEBITS();
                        state.mode = inflate_mode.CHECK;
                        break;
                    }
                    if (NEEDBITS_(3))
                    {
                        goto inf_leave;
                    }
                    state.last = (int)BITS(1);
                    DROPBITS(1);
                    switch (BITS(2))
                    {
                    case 0:                     /* stored block */
                        //Tracev((stderr, "inflate:     stored block%s\n",
                        //        state.last ? " (last)" : ""));
                        state.mode = inflate_mode.STORED;
                        break;

                    case 1:                     /* fixed block */
                        fixedtables(state);
                        //Tracev((stderr, "inflate:     fixed codes block%s\n",
                        //        state.last ? " (last)" : ""));
                        state.mode = inflate_mode.LEN_;     /* decode codes */
                        if (flush == zlib.Z_TREES)
                        {
                            DROPBITS(2);
                            goto inf_leave;
                        }
                        break;

                    case 2:                     /* dynamic block */
                        //Tracev((stderr, "inflate:     dynamic codes block%s\n",
                        //        state.last ? " (last)" : ""));
                        state.mode = inflate_mode.TABLE;
                        break;

                    case 3:
                        strm.msg   = "invalid block type";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    DROPBITS(2);
                    break;

                case inflate_mode.STORED:
                    BYTEBITS();                 /* go to byte boundary */
                    if (NEEDBITS_(32))
                    {
                        goto inf_leave;
                    }
                    if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff))
                    {
                        strm.msg   = "invalid stored block lengths";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    state.length = (uint)hold & 0xffff;
                    //Tracev((stderr, "inflate:       stored length %u\n",
                    //        state.length));
                    INITBITS();
                    state.mode = inflate_mode.COPY_;
                    if (flush == zlib.Z_TREES)
                    {
                        goto inf_leave;
                    }
                    goto case inflate_mode.COPY_;

                case inflate_mode.COPY_:
                    state.mode = inflate_mode.COPY;
                    goto case inflate_mode.COPY;

                case inflate_mode.COPY:
                    copy = state.length;
                    if (copy != 0)
                    {
                        if (copy > have)
                        {
                            copy = have;
                        }
                        if (copy > left)
                        {
                            copy = left;
                        }
                        if (copy == 0)
                        {
                            goto inf_leave;
                        }
                        zutil.zmemcpy(put_buffer, put_index, next_buffer, next_index, copy);
                        have         -= copy;
                        next_index   += copy;
                        left         -= copy;
                        put_index    += copy;
                        state.length -= copy;
                        break;
                    }
                    //Tracev((stderr, "inflate:       stored end\n"));
                    state.mode = inflate_mode.TYPE;
                    break;

                case inflate_mode.TABLE:
                    if (NEEDBITS_(14))
                    {
                        goto inf_leave;
                    }
                    state.nlen = BITS(5) + 257;
                    DROPBITS(5);
                    state.ndist = BITS(5) + 1;
                    DROPBITS(5);
                    state.ncode = BITS(4) + 4;
                    DROPBITS(4);
//#ifndef PKZIP_BUG_WORKAROUND
                    if (state.nlen > 286 || state.ndist > 30)
                    {
                        strm.msg   = "too many length or distance symbols";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
//#endif
                    //Tracev((stderr, "inflate:       table sizes ok\n"));
                    state.have = 0;
                    state.mode = inflate_mode.LENLENS;
                    goto case inflate_mode.LENLENS;

                case inflate_mode.LENLENS:
                    while (state.have < state.ncode)
                    {
                        if (NEEDBITS_(3))
                        {
                            goto inf_leave;
                        }
                        state.lens[order[state.have++]] = (ushort)BITS(3);
                        DROPBITS(3);
                    }
                    while (state.have < 19)
                    {
                        state.lens[order[state.have++]] = 0;
                    }
                    state.next          = 0;
                    state.lencode_array = state.codes;
                    state.lencode_index = state.next;
                    state.lenbits       = 7;
                    ret = inftrees.inflate_table(codetype.CODES, state.lens, 0, 19, state.codes, ref state.next,
                                                 ref state.lenbits, state.work);
                    if (ret != 0)
                    {
                        strm.msg   = "invalid code lengths set";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    //Tracev((stderr, "inflate:       code lengths ok\n"));
                    state.have = 0;
                    state.mode = inflate_mode.CODELENS;
                    goto case inflate_mode.CODELENS;

                case inflate_mode.CODELENS:
                    while (state.have < state.nlen + state.ndist)
                    {
                        for (;;)
                        {
                            here = state.lencode_array[state.lencode_index + BITS(state.lenbits)];
                            if ((uint)(here.bits) <= bits)
                            {
                                break;
                            }
                            if (PULLBYTE_())
                            {
                                goto inf_leave;
                            }
                        }
                        if (here.val < 16)
                        {
                            DROPBITS(here.bits);
                            state.lens[state.have++] = here.val;
                        }
                        else
                        {
                            if (here.val == 16)
                            {
                                if (NEEDBITS_(here.bits + 2))
                                {
                                    goto inf_leave;
                                }
                                DROPBITS(here.bits);
                                if (state.have == 0)
                                {
                                    strm.msg   = "invalid bit length repeat";
                                    state.mode = inflate_mode.BAD;
                                    break;
                                }
                                len  = state.lens[state.have - 1];
                                copy = 3 + BITS(2);
                                DROPBITS(2);
                            }
                            else if (here.val == 17)
                            {
                                if (NEEDBITS_(here.bits + 3))
                                {
                                    goto inf_leave;
                                }
                                DROPBITS(here.bits);
                                len  = 0;
                                copy = 3 + BITS(3);
                                DROPBITS(3);
                            }
                            else
                            {
                                if (NEEDBITS_(here.bits + 7))
                                {
                                    goto inf_leave;
                                }
                                DROPBITS(here.bits);
                                len  = 0;
                                copy = 11 + BITS(7);
                                DROPBITS(7);
                            }
                            if (state.have + copy > state.nlen + state.ndist)
                            {
                                strm.msg   = "invalid bit length repeat";
                                state.mode = inflate_mode.BAD;
                                break;
                            }
                            while (copy-- != 0)
                            {
                                state.lens[state.have++] = (ushort)len;
                            }
                        }
                    }

                    /* handle error breaks in while */
                    if (state.mode == inflate_mode.BAD)
                    {
                        break;
                    }

                    /* check for end-of-block code (better have one) */
                    if (state.lens[256] == 0)
                    {
                        strm.msg   = "invalid code -- missing end-of-block";
                        state.mode = inflate_mode.BAD;
                        break;
                    }

                    /* build code tables -- note: do not change the lenbits or distbits
                     * values here (9 and 6) without reading the comments in inftrees.h
                     * concerning the ENOUGH constants, which depend on those values */
                    state.next          = 0;
                    state.lencode_array = state.codes;
                    state.lencode_index = state.next;
                    state.lenbits       = 9;
                    ret = inftrees.inflate_table(codetype.LENS, state.lens, 0, state.nlen, state.codes, ref state.next,
                                                 ref state.lenbits, state.work);
                    if (ret != 0)
                    {
                        strm.msg   = "invalid literal/lengths set";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    state.distcode_array = state.codes;
                    state.distcode_index = state.next;
                    state.distbits       = 6;
                    ret = inftrees.inflate_table(codetype.DISTS, state.lens, state.nlen, state.ndist,
                                                 state.codes, ref state.next, ref state.distbits, state.work);
                    if (ret != 0)
                    {
                        strm.msg   = "invalid distances set";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    //Tracev((stderr, "inflate:       codes ok\n"));
                    state.mode = inflate_mode.LEN_;
                    if (flush == zlib.Z_TREES)
                    {
                        goto inf_leave;
                    }
                    goto case inflate_mode.LEN_;

                case inflate_mode.LEN_:
                    state.mode = inflate_mode.LEN;
                    goto case inflate_mode.LEN;

                case inflate_mode.LEN:
                    if (have >= 6 && left >= 258)
                    {
                        RESTORE();
                        inffast.inflate_fast(strm, @out);
                        LOAD();
                        if (state.mode == inflate_mode.TYPE)
                        {
                            state.back = -1;
                        }
                        break;
                    }
                    state.back = 0;
                    for (;;)
                    {
                        here = state.lencode_array[state.lencode_index + BITS(state.lenbits)];
                        if ((uint)(here.bits) <= bits)
                        {
                            break;
                        }
                        if (PULLBYTE_())
                        {
                            goto inf_leave;
                        }
                    }
                    if (here.op != 0 && (here.op & 0xf0) == 0)
                    {
                        last = here;
                        for (;;)
                        {
                            here = state.lencode_array[state.lencode_index + last.val +
                                                       (BITS(last.bits + last.op) >> last.bits)];
                            if ((uint)(last.bits + here.bits) <= bits)
                            {
                                break;
                            }
                            if (PULLBYTE_())
                            {
                                goto inf_leave;
                            }
                        }
                        DROPBITS(last.bits);
                        state.back += last.bits;
                    }
                    DROPBITS(here.bits);
                    state.back  += here.bits;
                    state.length = (uint)here.val;
                    if ((int)(here.op) == 0)
                    {
                        //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                        //        "inflate:         literal '%c'\n" :
                        //        "inflate:         literal 0x%02x\n", here.val));
                        state.mode = inflate_mode.LIT;
                        break;
                    }
                    if ((here.op & 32) != 0)
                    {
                        //Tracevv((stderr, "inflate:         end of block\n"));
                        state.back = -1;
                        state.mode = inflate_mode.TYPE;
                        break;
                    }
                    if ((here.op & 64) != 0)
                    {
                        strm.msg   = "invalid literal/length code";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    state.extra = (uint)(here.op) & 15;
                    state.mode  = inflate_mode.LENEXT;
                    goto case inflate_mode.LENEXT;

                case inflate_mode.LENEXT:
                    if (state.extra != 0)
                    {
                        if (NEEDBITS_(state.extra))
                        {
                            goto inf_leave;
                        }
                        state.length += BITS(state.extra);
                        DROPBITS(state.extra);
                        state.back += (int)state.extra;
                    }
                    //Tracevv((stderr, "inflate:         length %u\n", state.length));
                    state.was  = state.length;
                    state.mode = inflate_mode.DIST;
                    goto case inflate_mode.DIST;

                case inflate_mode.DIST:
                    for (;;)
                    {
                        here = state.distcode_array[state.distcode_index + BITS(state.distbits)];
                        if ((uint)(here.bits) <= bits)
                        {
                            break;
                        }
                        if (PULLBYTE_())
                        {
                            goto inf_leave;
                        }
                    }
                    if ((here.op & 0xf0) == 0)
                    {
                        last = here;
                        for (;;)
                        {
                            here = state.distcode_array[state.distcode_index + last.val +
                                                        (BITS(last.bits + last.op) >> last.bits)];
                            if ((uint)(last.bits + here.bits) <= bits)
                            {
                                break;
                            }
                            if (PULLBYTE_())
                            {
                                goto inf_leave;
                            }
                        }
                        DROPBITS(last.bits);
                        state.back += last.bits;
                    }
                    DROPBITS(here.bits);
                    state.back += here.bits;
                    if ((here.op & 64) != 0)
                    {
                        strm.msg   = "invalid distance code";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                    state.offset = (uint)here.val;
                    state.extra  = (uint)(here.op) & 15;
                    state.mode   = inflate_mode.DISTEXT;
                    goto case inflate_mode.DISTEXT;

                case inflate_mode.DISTEXT:
                    if (state.extra != 0)
                    {
                        if (NEEDBITS_(state.extra))
                        {
                            goto inf_leave;
                        }
                        state.offset += BITS(state.extra);
                        DROPBITS(state.extra);
                        state.back += (int)state.extra;
                    }
//#ifdef INFLATE_STRICT
//            if (state.offset > state.dmax) {
//                strm.msg = "invalid distance too far back";
//                state.mode = inflate_mode.BAD;
//                break;
//            }
//#endif
                    //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
                    state.mode = inflate_mode.MATCH;
                    goto case inflate_mode.MATCH;

                case inflate_mode.MATCH:
                    if (left == 0)
                    {
                        goto inf_leave;
                    }
                    copy = @out - left;
                    if (state.offset > copy)   /* copy from window */
                    {
                        copy = state.offset - copy;
                        if (copy > state.whave)
                        {
                            if (state.sane != 0)
                            {
                                strm.msg   = "invalid distance too far back";
                                state.mode = inflate_mode.BAD;
                                break;
                            }
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
//                    Trace((stderr, "inflate.c too far\n"));
//                    copy -= state.whave;
//                    if (copy > state.length) copy = state.length;
//                    if (copy > left) copy = left;
//                    left -= copy;
//                    state.length -= copy;
//                    do {
//                        *put++ = 0;
//                    } while (--copy);
//                    if (state.length == 0) state.mode = inflate_mode.LEN;
//                    break;
//#endif
                        }
                        if (copy > state.wnext)
                        {
                            copy       -= state.wnext;
                            from_buffer = state.window; from_index = (state.wsize - copy);
                        }
                        else
                        {
                            from_buffer = state.window; from_index = (state.wnext - copy);
                        }
                        if (copy > state.length)
                        {
                            copy = state.length;
                        }
                    }
                    else                        /* copy from output */
                    {
                        from_buffer = put_buffer; from_index = put_index - state.offset;
                        copy        = state.length;
                    }
                    if (copy > left)
                    {
                        copy = left;
                    }
                    left         -= copy;
                    state.length -= copy;
                    do
                    {
                        put_buffer[put_index++] = from_buffer[from_index++];
                    } while (--copy != 0);
                    if (state.length == 0)
                    {
                        state.mode = inflate_mode.LEN;
                    }
                    break;

                case inflate_mode.LIT:
                    if (left == 0)
                    {
                        goto inf_leave;
                    }
                    put_buffer[put_index++] = (byte)(state.length);
                    left--;
                    state.mode = inflate_mode.LEN;
                    break;

                case inflate_mode.CHECK:
                    if (state.wrap != 0)
                    {
                        if (NEEDBITS_(32))
                        {
                            goto inf_leave;
                        }
                        @out           -= left;
                        strm.total_out += @out;
                        state.total    += @out;
                        if ((state.wrap & 4) != 0 && @out != 0)
                        {
                            strm.adler = state.check =
                                UPDATE(state.check, put_buffer, put_index - @out, @out);
                        }
                        @out = left;
                        if ((state.wrap & 4) != 0 && (
//#ifdef GUNZIP
                                state.flags != 0 ? hold :
//#endif
                                zutil.ZSWAP32((uint)hold)) != state.check)
                        {
                            strm.msg   = "incorrect data check";
                            state.mode = inflate_mode.BAD;
                            break;
                        }
                        INITBITS();
                        //Tracev((stderr, "inflate:   check matches trailer\n"));
                    }
//#ifdef GUNZIP
                    state.mode = inflate_mode.LENGTH;
                    goto case inflate_mode.LENGTH;

                case inflate_mode.LENGTH:
                    if (state.wrap != 0 && state.flags != 0)
                    {
                        if (NEEDBITS_(32))
                        {
                            goto inf_leave;
                        }
                        if (hold != (state.total & 0xffffffffUL))
                        {
                            strm.msg   = "incorrect length check";
                            state.mode = inflate_mode.BAD;
                            break;
                        }
                        INITBITS();
                        //Tracev((stderr, "inflate:   length matches trailer\n"));
                    }
//#endif
                    state.mode = inflate_mode.DONE;
                    goto case inflate_mode.DONE;

                case inflate_mode.DONE:
                    ret = zlib.Z_STREAM_END;
                    goto inf_leave;

                case inflate_mode.BAD:
                    ret = zlib.Z_DATA_ERROR;
                    goto inf_leave;

                case inflate_mode.MEM:
                    return(zlib.Z_MEM_ERROR);

                case inflate_mode.SYNC:
                default:
                    return(zlib.Z_STREAM_ERROR);
                }
            }

            /*
             * Return from inflate(), updating the total counts and the check value.
             * If there was no progress during the inflate() call, return a buffer
             * error.  Call updatewindow() to create and/or update the window state.
             * Note: a memory error from inflate() is non-recoverable.
             */
inf_leave:
            RESTORE();
            if (state.wsize != 0 || (@out != strm.avail_out && state.mode < inflate_mode.BAD &&
                                     (state.mode < inflate_mode.CHECK || flush != zlib.Z_FINISH)))
            {
                if (updatewindow(strm, strm.output_buffer, strm.next_out, @out - strm.avail_out) != 0)
                {
                    state.mode = inflate_mode.MEM;
                    return(zlib.Z_MEM_ERROR);
                }
            }
            @in            -= strm.avail_in;
            @out           -= strm.avail_out;
            strm.total_in  += @in;
            strm.total_out += @out;
            state.total    += @out;
            if ((state.wrap & 4) != 0 && @out != 0)
            {
                strm.adler = state.check =
                    UPDATE(state.check, strm.output_buffer, strm.next_out - @out, @out);
            }
            strm.data_type = (int)state.bits + (state.last != 0 ? 64 : 0) +
                             (state.mode == inflate_mode.TYPE ? 128 : 0) +
                             (state.mode == inflate_mode.LEN_ || state.mode == inflate_mode.COPY_ ? 256 : 0);
            if (((@in == 0 && @out == 0) || flush == zlib.Z_FINISH) && ret == zlib.Z_OK)
            {
                ret = zlib.Z_BUF_ERROR;
            }
            return(ret);
        }
コード例 #48
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		// Returns true if inflate is currently at the end of a block generated by
		// Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
		// implementation to provide an additional safety check. PPP uses
		// Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
		// block. When decompressing, PPP checks that at the end of input packet,
		// inflate is waiting for these length bytes.

		public static int inflateSyncPoint(z_stream strm)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			inflate_state state=(inflate_state)strm.state;
			return (state.mode==inflate_mode.STORED&&state.bits==0)?1:0;
		}
コード例 #49
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		static int read_buf(z_stream strm, byte[] buf, int buf_ind, uint size)
		{
			uint len=strm.avail_in;

			if(len>size) len=size;
			if(len==0) return 0;

			strm.avail_in-=len;

			deflate_state s=(deflate_state)strm.state;

			if(s.wrap==1) strm.adler=adler32(strm.adler, strm.in_buf, (uint)strm.next_in, len);
			else if(s.wrap==2) strm.adler=crc32(strm.adler, strm.in_buf, strm.next_in, len);

			//was memcpy(buf, strm.in_buf+strm.next_in, len);
			Array.Copy(strm.in_buf, strm.next_in, buf, buf_ind, len);
			strm.next_in+=len;
			strm.total_in+=len;

			return (int)len;
		}
コード例 #50
0
ファイル: gzipstream.cs プロジェクト: mintwans/cpsc483
 private static extern ZLibReturnCode     inflate(ref z_stream strm, ZLibFlush flush);
コード例 #51
0
        // Decode literal, length, and distance codes and write out the resulting
        // literal and match bytes until either not enough input or output is
        // available, an end-of-block is encountered, or a data error is encountered.
        // When large enough input and output buffers are supplied to inflate(), for
        // example, a 16K input buffer and a 64K output buffer, more than 95% of the
        // inflate execution time is spent in this routine.
        //
        // Entry assumptions:
        //
        //      state.mode == LEN
        //      strm.avail_in >= 6
        //      strm.avail_out >= 258
        //      start >= strm.avail_out
        //      state.bits < 8
        //
        // On return, state.mode is one of:
        //
        //      LEN -- ran out of enough output space or enough available input
        //      TYPE -- reached end of block code, inflate() to interpret next block
        //      BAD -- error in block data
        //
        // Notes:
        //
        //  - The maximum input bits used by a length/distance pair is 15 bits for the
        //    length code, 5 bits for the length extra, 15 bits for the distance code,
        //    and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
        //    Therefore if strm.avail_in >= 6, then there is enough input to avoid
        //    checking for available input while decoding.
        //
        //  - The maximum bytes that a single length/distance pair can output is 258
        //    bytes, which is the maximum length that can be coded.  inflate_fast()
        //    requires strm.avail_out >= 258 for each loop to avoid checking for
        //    output space.

        private static void inflate_fast(z_stream strm, uint start) // inflate()'s starting value for strm.avail_out
        {
            inflate_state state = null;

            byte[] _in;             // local strm.next_in
            uint   in_ind;          // ind in _in
            int    last;            // while in < last, enough input available

            byte[] @out;            // local strm.next_out
            int    out_ind;         // ind in @out
            int    beg;             // inflate()'s initial strm.next_out
            int    end;             // while out < end, enough space available
            uint   dmax;            // maximum distance from zlib header
            uint   wsize;           // window size or zero if not using window
            uint   whave;           // valid bytes in the window
            uint   wnext;           // window write index

            byte[] window;          // allocated sliding window, if wsize != 0
            uint   hold;            // local strm.hold
            uint   bits;            // local strm.bits

            code[] lcode;           // local strm.lencode
            code[] dcode;           // local strm.distcode
            int    dcode_ind;       // index in strm.distcode
            uint   lmask;           // mask for first level of length codes
            uint   dmask;           // mask for first level of distance codes
            code   here;            // retrieved table entry
            uint   op;              // code bits, operation, extra bits, or window position, window bytes to copy
            uint   len;             // match length, unused bytes
            uint   dist;            // match distance

            byte[] from;            // where to copy match from
            int    from_ind;        // where to copy match from

            // copy state to local variables
            state     = (inflate_state)strm.state;
            _in       = strm.in_buf;
            in_ind    = strm.next_in;
            last      = (int)(in_ind + (strm.avail_in - 5));
            @out      = strm.out_buf;
            out_ind   = strm.next_out;
            beg       = (int)(out_ind - (start - strm.avail_out));
            end       = (int)(out_ind + (strm.avail_out - 257));
            dmax      = state.dmax;
            wsize     = state.wsize;
            whave     = state.whave;
            wnext     = state.wnext;
            window    = state.window;
            hold      = state.hold;
            bits      = state.bits;
            lcode     = state.lencode;
            dcode     = state.distcode;
            dcode_ind = state.distcode_ind;
            lmask     = (1U << (int)state.lenbits) - 1;
            dmask     = (1U << (int)state.distbits) - 1;

            // decode literals and length/distances until end-of-block or not enough input data or output space
            do
            {
                if (bits < 15)
                {
                    hold += (uint)_in[in_ind++] << (int)bits;
                    bits += 8;
                    hold += (uint)_in[in_ind++] << (int)bits;
                    bits += 8;
                }
                here = lcode[hold & lmask];

dolen:
                op     = here.bits;
                hold >>= (int)op;
                bits  -= op;
                op     = here.op;

                if (op == 0)
                { // literal
                  //Tracevv((stderr, @this.val >= 0x20 && @this.val < 0x7f ?
                  //    "inflate:         literal '%c'\n" :
                  //    "inflate:         literal 0x%02x\n", @this.val));
                    @out[out_ind++] = (byte)here.val;
                }
                else if ((op & 16) != 0)
                {             // length base
                    len = here.val;
                    op &= 15; // number of extra bits
                    if (op != 0)
                    {
                        if (bits < op)
                        {
                            hold += (uint)_in[in_ind++] << (int)bits;
                            bits += 8;
                        }
                        len   += (uint)hold & ((1U << (int)op) - 1);
                        hold >>= (int)op;
                        bits  -= op;
                    }
                    //Tracevv((stderr, "inflate:         length %u\n", len));

                    if (bits < 15)
                    {
                        hold += (uint)_in[in_ind++] << (int)bits;
                        bits += 8;
                        hold += (uint)_in[in_ind++] << (int)bits;
                        bits += 8;
                    }
                    here = dcode[dcode_ind + (hold & dmask)];

dodist:
                    op     = here.bits;
                    hold >>= (int)op;
                    bits  -= op;
                    op     = here.op;
                    if ((op & 16) != 0)
                    {              // distance base
                        dist = here.val;
                        op  &= 15; // number of extra bits
                        if (bits < op)
                        {
                            hold += (uint)_in[in_ind++] << (int)bits;
                            bits += 8;
                            if (bits < op)
                            {
                                hold += (uint)_in[in_ind++] << (int)bits;
                                bits += 8;
                            }
                        }
                        dist += (uint)hold & ((1U << (int)op) - 1);
                        if (dist > dmax)
                        {
                            strm.msg   = "invalid distance too far back (STRICT)";
                            state.mode = inflate_mode.BAD;
                            break;
                        }
                        hold >>= (int)op;
                        bits  -= op;
                        //Tracevv((stderr, "inflate:         distance %u\n", dist));
                        op = (uint)(out_ind - beg); // max distance in output
                        if (dist > op)
                        {                           // see if copy from window
                            op = dist - op;         // distance back in window
                            if (op > whave)
                            {
                                if (state.sane)
                                {
                                    strm.msg   = "invalid distance too far back";
                                    state.mode = inflate_mode.BAD;
                                    break;
                                }
#if INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
                                if (len <= op - whave)
                                {
                                    do
                                    {
                                        @out[out_ind++] = 0;
                                    } while(--len != 0);
                                    continue;
                                }
                                len -= op - whave;
                                do
                                {
                                    @out[out_ind++] = 0;
                                } while(--op > whave);
                                if (op == 0)
                                {
                                    from     = @out;
                                    from_ind = (int)(out_ind - dist);
                                    do
                                    {
                                        @out[out_ind++] = from[from_ind++];
                                    } while(--len != 0);
                                    continue;
                                }
#endif
                            }

                            from     = window;
                            from_ind = 0;
                            if (wnext == 0)
                            { // very common case
                                from_ind += (int)(wsize - op);
                                if (op < len)
                                { // some from window
                                    len -= op;
                                    do
                                    {
                                        @out[out_ind++] = from[from_ind++];
                                    } while ((--op) != 0);
                                    from     = @out;
                                    from_ind = (int)(out_ind - dist);   // rest from output
                                }
                            }
                            else if (wnext < op)
                            { // wrap around window
                                from_ind += (int)(wsize + wnext - op);
                                op       -= wnext;
                                if (op < len)
                                { // some from end of window
                                    len -= op;
                                    do
                                    {
                                        @out[out_ind++] = from[from_ind++];
                                    } while ((--op) != 0);
                                    from     = window;
                                    from_ind = 0;
                                    if (wnext < len)
                                    {  // some from start of window
                                        op   = wnext;
                                        len -= op;
                                        do
                                        {
                                            @out[out_ind++] = from[from_ind++];
                                        } while ((--op) != 0);
                                        from     = @out;
                                        from_ind = (int)(out_ind - dist);   // rest from output
                                    }
                                }
                            }
                            else
                            { // contiguous in window
                                from_ind += (int)(wnext - op);
                                if (op < len)
                                { // some from window
                                    len -= op;
                                    do
                                    {
                                        @out[out_ind++] = from[from_ind++];
                                    } while ((--op) != 0);
                                    from     = @out;
                                    from_ind = (int)(out_ind - dist);   // rest from output
                                }
                            }
                            while (len > 2)
                            {
                                @out[out_ind++] = from[from_ind++];
                                @out[out_ind++] = from[from_ind++];
                                @out[out_ind++] = from[from_ind++];
                                len            -= 3;
                            }
                            if (len != 0)
                            {
                                @out[out_ind++] = from[from_ind++];
                                if (len > 1)
                                {
                                    @out[out_ind++] = from[from_ind++];
                                }
                            }
                        }
                        else
                        {
                            from     = @out;
                            from_ind = (int)(out_ind - dist); // copy direct from output
                            do
                            {                                 // minimum length is three
                                @out[out_ind++] = from[from_ind++];
                                @out[out_ind++] = from[from_ind++];
                                @out[out_ind++] = from[from_ind++];
                                len            -= 3;
                            } while (len > 2);
                            if (len != 0)
                            {
                                @out[out_ind++] = from[from_ind++];
                                if (len > 1)
                                {
                                    @out[out_ind++] = from[from_ind++];
                                }
                            }
                        }
                    }
                    else if ((op & 64) == 0)
                    { // 2nd level distance code
                        here = dcode[dcode_ind + here.val + (hold & ((1U << (int)op) - 1))];
                        goto dodist;
                    }
                    else
                    {
                        strm.msg   = "invalid distance code";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                }
                else if ((op & 64) == 0)
                { // 2nd level length code
                    here = lcode[here.val + (hold & ((1U << (int)op) - 1))];
                    goto dolen;
                }
                else if ((op & 32) != 0)
                { // end-of-block
                  //Tracevv((stderr, "inflate:         end of block\n"));
                    state.mode = inflate_mode.TYPE;
                    break;
                }
                else
                {
                    strm.msg   = "invalid literal/length code";
                    state.mode = inflate_mode.BAD;
                    break;
                }
            } while (in_ind < last && out_ind < end);

            // return unused bytes (on entry, bits < 8, so in won't go too far back)
            len     = bits >> 3;
            in_ind -= len;
            bits   -= len << 3;
            hold   &= (1U << (int)bits) - 1;

            // update state and return
            strm.next_in   = in_ind;
            strm.next_out  = out_ind;
            strm.avail_in  = (uint)(in_ind < last ? 5 + (last - in_ind) : 5 - (in_ind - last));
            strm.avail_out = (uint)(out_ind < end ? 257 + (end - out_ind) : 257 - (out_ind - end));
            state.hold     = hold;
            state.bits     = bits;
        }
コード例 #52
0
ファイル: gzipstream.cs プロジェクト: mintwans/cpsc483
 private static extern ZLibReturnCode    inflateInit2(ref z_stream strm, ZLibOpenType windowBits, string version, int stream_size);
コード例 #53
0
ファイル: uncompr.cs プロジェクト: AdmiralCurtiss/zlib-sharp
        /* uncompr.c -- decompress a memory buffer
         * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
         * For conditions of distribution and use, see copyright notice in zlib.h
         */

        /* ===========================================================================
         *   Decompresses the source buffer into the destination buffer.  *sourceLen is
         * the byte length of the source buffer. Upon entry, *destLen is the total size
         * of the destination buffer, which must be large enough to hold the entire
         * uncompressed data. (The size of the uncompressed data must have been saved
         * previously by the compressor and transmitted to the decompressor by some
         * mechanism outside the scope of this compression library.) Upon exit,
         * destLen is the size of the decompressed data and *sourceLen is the number
         * of source bytes consumed. Upon return, source + *sourceLen points to the
         * first unused input byte.
         *
         *   uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
         * memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
         * Z_DATA_ERROR if the input data was corrupted, including if the input data is
         * an incomplete zlib stream.
         */
        public static int uncompress2(byte[] dest_array, long dest_index, ref ulong destLen, byte[] source_array, long source_index, ref ulong sourceLen)
        {
            z_stream   stream = new z_stream();
            int        err;
            const uint max = uint.MaxValue;
            ulong      len, left;

            byte[] buf = new byte[1];                /* for detection of incomplete stream when *destLen == 0 */

            len = sourceLen;
            if (destLen != 0)
            {
                left    = destLen;
                destLen = 0;
            }
            else
            {
                left       = 1;
                dest_array = buf;
                dest_index = 0;
            }

            stream.input_buffer = source_array;
            stream.next_in      = source_index;
            stream.avail_in     = 0;
            //stream.zalloc = (alloc_func)0;
            //stream.zfree = (free_func)0;
            //stream.opaque = (voidpf)0;

            err = zlib_sharp.inflate.inflateInit_(stream, zlib.ZLIB_VERSION, z_stream._sizeof);
            if (err != zlib_sharp.zlib.Z_OK)
            {
                return(err);
            }

            stream.output_buffer = dest_array;
            stream.next_out      = dest_index;
            stream.avail_out     = 0;

            do
            {
                if (stream.avail_out == 0)
                {
                    stream.avail_out = left > (ulong)max ? max : (uint)left;
                    left            -= stream.avail_out;
                }
                if (stream.avail_in == 0)
                {
                    stream.avail_in = len > (ulong)max ? max : (uint)len;
                    len            -= stream.avail_in;
                }
                err = zlib_sharp.inflate.inflate_(stream, zlib_sharp.zlib.Z_NO_FLUSH);
            } while (err == zlib_sharp.zlib.Z_OK);

            sourceLen -= len + stream.avail_in;
            if (dest_array != buf)
            {
                destLen = stream.total_out;
            }
            else if (stream.total_out != 0 && err == zlib_sharp.zlib.Z_BUF_ERROR)
            {
                left = 1;
            }

            zlib_sharp.inflate.inflateEnd(stream);
            return(err == zlib_sharp.zlib.Z_STREAM_END ? zlib_sharp.zlib.Z_OK :
                   err == zlib_sharp.zlib.Z_NEED_DICT ? zlib_sharp.zlib.Z_DATA_ERROR :
                   err == zlib_sharp.zlib.Z_BUF_ERROR && (left + stream.avail_out) != 0 ? zlib_sharp.zlib.Z_DATA_ERROR :
                   err);
        }
コード例 #54
0
ファイル: gzipstream.cs プロジェクト: mintwans/cpsc483
 private static extern ZLibReturnCode    inflateEnd(ref z_stream strm);
コード例 #55
0
ファイル: inflate.cs プロジェクト: JoshDullen/zlib.net
		// Update the window with the last wsize (normally 32K) bytes written before
		// returning.  If window does not exist yet, create it.  This is only called
		// when a window is already in use, or when output has been written during this
		// inflate call, but the end of the deflate stream has not been reached yet.
		// It is also called to create a window for dictionary data when a dictionary
		// is loaded.
		//
		// Providing output buffers larger than 32K to inflate() should provide a speed
		// advantage, since only the last 32K of output is copied to the sliding window
		// upon return from inflate(), and since all distances after the first 32K of
		// output will fall in the output data, making match copies simpler and faster.
		// The advantage may be dependent on the size of the processor's data caches.
		static int updatewindow(z_stream strm, uint _out)
		{
			inflate_state state;
			uint copy, dist;

			state=(inflate_state)strm.state;

			// if it hasn't been done already, allocate space for the window
			if(state.window==null)
			{
				try
				{
					state.window=new byte[1<<(int)state.wbits];
				}
				catch(Exception)
				{
					return 1;
				}
			}

			// if window not in use yet, initialize
			if(state.wsize==0)
			{
				state.wsize=1U<<(int)state.wbits;
				state.wnext=0;
				state.whave=0;
			}

			// copy state.wsize or less output bytes into the circular window
			copy=_out-strm.avail_out;
			if(copy>=state.wsize)
			{
				//memcpy(state.window, strm.next_out-state.wsize, state.wsize);
				Array.Copy(strm.out_buf, strm.next_out-state.wsize, state.window, 0, state.wsize);
				state.wnext=0;
				state.whave=state.wsize;
			}
			else
			{
				dist=state.wsize-state.wnext;
				if(dist>copy) dist=copy;
				//memcpy(state.window+state.write, strm.next_out-copy, dist);
				Array.Copy(strm.out_buf, strm.next_out-copy, state.window, state.wnext, dist);
				copy-=dist;
				if(copy!=0)
				{
					//memcpy(state.window, strm.next_out-copy, copy);
					Array.Copy(strm.out_buf, strm.next_out-copy, state.window, 0, copy);
					state.wnext=copy;
					state.whave=state.wsize;
				}
				else
				{
					state.wnext+=dist;
					if(state.wnext==state.wsize) state.wnext=0;
					if(state.whave<state.wsize) state.whave+=dist;
				}
			}
			return 0;
		}
コード例 #56
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		//   Fine tune deflate's internal compression parameters.  This should only be
		// used by someone who understands the algorithm used by zlib's deflate for
		// searching for the best matching string, and even then only by the most
		// fanatic optimizer trying to squeeze out the last compressed bit for their
		// specific input data.  Read the deflate.cs source code for the meaning of the
		// max_lazy, good_length, nice_length, and max_chain parameters.

		//   deflateTune() can be called after deflateInit() or deflateInit2(), and
		// returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.

		public static int deflateTune(z_stream strm, uint good_length, uint max_lazy, int nice_length, uint max_chain)
		{
			if(strm==null||strm.state==null) return Z_STREAM_ERROR;
			deflate_state s=(deflate_state)strm.state;
			s.good_match=good_length;
			s.max_lazy_match=max_lazy;
			s.nice_match=nice_length;
			s.max_chain_length=max_chain;
			return Z_OK;
		}
コード例 #57
0
 public static int inflate_(z_stream strm, int flush)
 {
     return(new inflate().run(strm, flush));
 }
コード例 #58
0
ファイル: inffast.cs プロジェクト: AdmiralCurtiss/zlib-sharp
/* inffast.c -- fast decoding
 * Copyright (C) 1995-2017 Mark Adler
 * For conditions of distribution and use, see copyright notice in zlib.h
 */

/*
 * Decode literal, length, and distance codes and write out the resulting
 * literal and match bytes until either not enough input or output is
 * available, an end-of-block is encountered, or a data error is encountered.
 * When large enough input and output buffers are supplied to inflate(), for
 * example, a 16K input buffer and a 64K output buffer, more than 95% of the
 * inflate execution time is spent in this routine.
 *
 * Entry assumptions:
 *
 *      state->mode == LEN
 *      strm->avail_in >= 6
 *      strm->avail_out >= 258
 *      start >= strm->avail_out
 *      state->bits < 8
 *
 * On return, state->mode is one of:
 *
 *      LEN -- ran out of enough output space or enough available input
 *      TYPE -- reached end of block code, inflate() to interpret next block
 *      BAD -- error in block data
 *
 * Notes:
 *
 *  - The maximum input bits used by a length/distance pair is 15 bits for the
 *    length code, 5 bits for the length extra, 15 bits for the distance code,
 *    and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
 *    Therefore if strm->avail_in >= 6, then there is enough input to avoid
 *    checking for available input while decoding.
 *
 *  - The maximum bytes that a single length/distance pair can output is 258
 *    bytes, which is the maximum length that can be coded.  inflate_fast()
 *    requires strm->avail_out >= 258 for each loop to avoid checking for
 *    output space.
 */
        public static void inflate_fast(
            z_stream strm,
            uint start) /* inflate()'s starting value for strm->avail_out */
        {
            inflate_state state;

            byte[] in_array;
            long   in_index;   /* local strm->next_in */
            long   last;       /* have enough input while in < last */

            byte [] out_array; /* local strm->next_out */
            long    out_index;
            long    beg;       /* inflate()'s initial strm->next_out */
            long    end;       /* while out < end, enough space available */
//#ifdef INFLATE_STRICT
//    unsigned dmax;              /* maximum distance from zlib header */
//#endif
            uint wsize;         /* window size or zero if not using window */
            uint whave;         /* valid bytes in the window */
            uint wnext;         /* window write index */

            byte[] window;      /* allocated sliding window, if wsize != 0 */
            ulong  hold;        /* local strm->hold */
            uint   bits;        /* local strm->bits */

            code[] lcode_array; /* local strm->lencode */
            long   lcode_index;

            code[] dcode_array; /* local strm->distcode */
            long   dcode_index;
            uint   lmask;       /* mask for first level of length codes */
            uint   dmask;       /* mask for first level of distance codes */
            code   here;        /* retrieved table entry */
            uint   op;          /* code bits, operation, extra bits, or */
            /*  window position, window bytes to copy */
            uint len;           /* match length, unused bytes */
            uint dist;          /* match distance */

            byte[] from_array;  /* where to copy match from */
            long   from_index;

            /* copy state to local variables */
            state     = strm.state;
            in_array  = strm.input_buffer;
            in_index  = strm.next_in;
            last      = in_index + (strm.avail_in - 5);
            out_array = strm.output_buffer;
            out_index = strm.next_out;
            beg       = out_index - (start - strm.avail_out);
            end       = out_index + (strm.avail_out - 257);
//#ifdef INFLATE_STRICT
//    dmax = state->dmax;
//#endif
            wsize       = state.wsize;
            whave       = state.whave;
            wnext       = state.wnext;
            window      = state.window;
            hold        = state.hold;
            bits        = state.bits;
            lcode_array = state.lencode_array;
            lcode_index = state.lencode_index;
            dcode_array = state.distcode_array;
            dcode_index = state.distcode_index;
            lmask       = (1U << (int)state.lenbits) - 1;
            dmask       = (1U << (int)state.distbits) - 1;

            /* decode literals and length/distances until end-of-block or not enough
             * input data or output space */
            do
            {
                if (bits < 15)
                {
                    hold += (ulong)(in_array[in_index++]) << (int)bits;
                    bits += 8;
                    hold += (ulong)(in_array[in_index++]) << (int)bits;
                    bits += 8;
                }
                here = lcode_array[lcode_index + (long)(hold & lmask)];
dolen:
                op     = (uint)(here.bits);
                hold >>= (int)op;
                bits  -= op;
                op     = (uint)(here.op);
                if (op == 0)                    /* literal */
                //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                //        "inflate:         literal '%c'\n" :
                //        "inflate:         literal 0x%02x\n", here.val));
                {
                    out_array[out_index++] = (byte)(here.val);
                }
                else if ((op & 16) != 0)               /* length base */
                {
                    len = (uint)(here.val);
                    op &= 15;                   /* number of extra bits */
                    if (op != 0)
                    {
                        if (bits < op)
                        {
                            hold += (ulong)(in_array[in_index++]) << (int)bits;
                            bits += 8;
                        }
                        len   += (uint)hold & ((1U << (int)op) - 1);
                        hold >>= (int)op;
                        bits  -= op;
                    }
                    //Tracevv((stderr, "inflate:         length %u\n", len));
                    if (bits < 15)
                    {
                        hold += (ulong)(in_array[in_index++]) << (int)bits;
                        bits += 8;
                        hold += (ulong)(in_array[in_index++]) << (int)bits;
                        bits += 8;
                    }
                    here = dcode_array[dcode_index + (long)(hold & dmask)];
dodist:
                    op     = (uint)(here.bits);
                    hold >>= (int)op;
                    bits  -= op;
                    op     = (uint)(here.op);
                    if ((op & 16) != 0)                /* distance base */
                    {
                        dist = (uint)(here.val);
                        op  &= 15;              /* number of extra bits */
                        if (bits < op)
                        {
                            hold += (ulong)(in_array[in_index++]) << (int)bits;
                            bits += 8;
                            if (bits < op)
                            {
                                hold += (ulong)(in_array[in_index++]) << (int)bits;
                                bits += 8;
                            }
                        }
                        dist += (uint)hold & ((1U << (int)op) - 1);
//#ifdef INFLATE_STRICT
//                if (dist > dmax) {
//                    strm->msg = (char *)"invalid distance too far back";
//                    state->mode = BAD;
//                    break;
//                }
//#endif
                        hold >>= (int)op;
                        bits  -= op;
                        //Tracevv((stderr, "inflate:         distance %u\n", dist));
                        op = (uint)(out_index - beg); /* max distance in output */
                        if (dist > op)                /* see if copy from window */
                        {
                            op = dist - op;           /* distance back in window */
                            if (op > whave)
                            {
                                if (state.sane != 0)
                                {
                                    strm.msg =
                                        "invalid distance too far back";
                                    state.mode = inflate_mode.BAD;
                                    break;
                                }
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
//                        if (len <= op - whave) {
//                            do {
//                                *out++ = 0;
//                            } while (--len);
//                            continue;
//                        }
//                        len -= op - whave;
//                        do {
//                            *out++ = 0;
//                        } while (--op > whave);
//                        if (op == 0) {
//                            from = out - dist;
//                            do {
//                                *out++ = *from++;
//                            } while (--len);
//                            continue;
//                        }
//#endif
                            }
                            from_array = window;
                            from_index = 0;
                            if (wnext == 0)     /* very common case */
                            {
                                from_index += wsize - op;
                                if (op < len)   /* some from window */
                                {
                                    len -= op;
                                    do
                                    {
                                        out_array[out_index++] = from_array[from_index++];
                                    } while (--op != 0);
                                    from_array = out_array;
                                    from_index = out_index - dist; /* rest from output */
                                }
                            }
                            else if (wnext < op) /* wrap around window */
                            {
                                from_index += wsize + wnext - op;
                                op         -= wnext;
                                if (op < len)   /* some from end of window */
                                {
                                    len -= op;
                                    do
                                    {
                                        out_array[out_index++] = from_array[from_index++];
                                    } while (--op != 0);
                                    from_array = window;
                                    from_index = 0;
                                    if (wnext < len) /* some from start of window */
                                    {
                                        op   = wnext;
                                        len -= op;
                                        do
                                        {
                                            out_array[out_index++] = from_array[from_index++];
                                        } while (--op != 0);
                                        from_array = out_array;
                                        from_index = out_index - dist; /* rest from output */
                                    }
                                }
                            }
                            else                /* contiguous in window */
                            {
                                from_index += wnext - op;
                                if (op < len)   /* some from window */
                                {
                                    len -= op;
                                    do
                                    {
                                        out_array[out_index++] = from_array[from_index++];
                                    } while (--op != 0);
                                    from_array = out_array;
                                    from_index = out_index - dist; /* rest from output */
                                }
                            }
                            while (len > 2)
                            {
                                out_array[out_index++] = from_array[from_index++];
                                out_array[out_index++] = from_array[from_index++];
                                out_array[out_index++] = from_array[from_index++];
                                len -= 3;
                            }
                            if (len != 0)
                            {
                                out_array[out_index++] = from_array[from_index++];
                                if (len > 1)
                                {
                                    out_array[out_index++] = from_array[from_index++];
                                }
                            }
                        }
                        else
                        {
                            from_array = out_array;
                            from_index = out_index - dist; /* copy direct from output */
                            do                             /* minimum length is three */
                            {
                                out_array[out_index++] = from_array[from_index++];
                                out_array[out_index++] = from_array[from_index++];
                                out_array[out_index++] = from_array[from_index++];
                                len -= 3;
                            } while (len > 2);
                            if (len != 0)
                            {
                                out_array[out_index++] = from_array[from_index++];
                                if (len > 1)
                                {
                                    out_array[out_index++] = from_array[from_index++];
                                }
                            }
                        }
                    }
                    else if ((op & 64) == 0)    /* 2nd level distance code */
                    {
                        here = dcode_array[dcode_index + here.val + (long)(hold & ((1U << (int)op) - 1))];
                        goto dodist;
                    }
                    else
                    {
                        strm.msg   = "invalid distance code";
                        state.mode = inflate_mode.BAD;
                        break;
                    }
                }
                else if ((op & 64) == 0)        /* 2nd level length code */
                {
                    here = lcode_array[lcode_index + here.val + (long)(hold & ((1U << (int)op) - 1))];
                    goto dolen;
                }
                else if ((op & 32) != 0)               /* end-of-block */
                //Tracevv((stderr, "inflate:         end of block\n"));
                {
                    state.mode = inflate_mode.TYPE;
                    break;
                }
                else
                {
                    strm.msg   = "invalid literal/length code";
                    state.mode = inflate_mode.BAD;
                    break;
                }
            } while (in_index < last && out_index < end);

            /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
            len       = bits >> 3;
            in_index -= len;
            bits     -= len << 3;
            hold     &= (1U << (int)bits) - 1;

            /* update state and return */
            strm.next_in   = in_index;
            strm.next_out  = out_index;
            strm.avail_in  = (uint)(in_index < last ? 5 + (last - in_index) : 5 - (in_index - last));
            strm.avail_out = (uint)(out_index < end ?
                                    257 + (end - out_index) : 257 - (out_index - end));
            state.hold = hold;
            state.bits = bits;
            return;
        }
コード例 #59
0
ファイル: deflate.cs プロジェクト: JoshDullen/zlib.net
		// =========================================================================
		// For the default windowBits of 15 and memLevel of 8, this function returns
		// a close to exact, as well as small, upper bound on the compressed size.
		// They are coded as constants here for a reason--if the #define's are
		// changed, then this function needs to be changed as well.  The return
		// value for 15 and 8 only works for those exact settings.
		//
		// For any setting other than those defaults for windowBits and memLevel,
		// the value returned is a conservative worst case for the maximum expansion
		// resulting from using fixed blocks instead of stored blocks, which deflate
		// can emit on compressed data for some combinations of the parameters.
		//
		// This function could be more sophisticated to provide closer upper bounds for
		// every combination of windowBits and memLevel. But even the conservative
		// upper bound of about 14% expansion does not seem onerous for output buffer
		// allocation.

		//   deflateBound() returns an upper bound on the compressed size after
		// deflation of sourceLen bytes.  It must be called after deflateInit()
		// or deflateInit2().  This would be used to allocate an output buffer
		// for deflation in a single pass, and so would be called before deflate().

		public static uint deflateBound(z_stream strm, uint sourceLen)
		{
			// conservative upper bound for compressed data
			uint complen=sourceLen+((sourceLen+7)>>3)+((sourceLen+63)>>6)+5;

			// if can't get parameters, return conservative bound plus zlib wrapper
			if(strm==null||strm.state==null) return complen+6;

			// compute wrapper length
			deflate_state s=(deflate_state)strm.state;
			uint wraplen;
			byte[] str;
			switch(s.wrap)
			{
				case 0: // raw deflate
					wraplen=0;
					break;
				case 1: // zlib wrapper
					wraplen=(uint)(6+(s.strstart!=0?4:0));
					break;
				case 2: // gzip wrapper
					wraplen=18;
					if(s.gzhead!=null) // user-supplied gzip header
					{
						if(s.gzhead.extra!=null) wraplen+=2+s.gzhead.extra_len;
						str=s.gzhead.name;
						int str_ind=0;
						if(str!=null)
						{
							do
							{
								wraplen++;
							} while(str[str_ind++]!=0);
						}
						str=s.gzhead.comment;
						if(str!=null)
						{
							do
							{
								wraplen++;
							} while(str[str_ind++]!=0);
						}
						if(s.gzhead.hcrc!=0) wraplen+=2;
					}
					break;
				default: wraplen=6; break; // for compiler happiness
			}

			// if not default parameters, return conservative bound
			if(s.w_bits!=15||s.hash_bits!=8+7) return complen+wraplen;

			// default settings: return tight bound for that case
			return sourceLen+(sourceLen>>12)+(sourceLen>>14)+(sourceLen>>25)+13-6+wraplen;
		}