示例#1
0
        /// <summary>
        /// copy as much as possible from the sliding window to the output area
        /// </summary>
        /// <param name="z">The z.</param>
        /// <param name="r">The r.</param>
        /// <returns></returns>
        public ZLibStatus InflateFlush(ZStream z, ZLibStatus r)
        {
            int n;
            int p;
            int q;

            // local copies of source and destination pointers
            p = z.next_out_index;
            q = read;

            // compute number of bytes to copy as far as end of window
            n = (int)((q <= write ? write : end) - q);
            if (n > z.avail_out) n = z.avail_out;
            if (n != 0 && r == ZLibStatus.Z_BUF_ERROR)
                r = ZLibStatus.Z_OK;

            // update counters
            z.avail_out -= n;
            z.total_out += n;

            // update check information
            if (checkfn != null)
            {
                //z.adler = check = z.Adler32(check, window, q, n);
                z.UpdateAdler(check, window, q, n);
                check = z.Adler;
            }

            // copy as far as end of window
            System.Array.Copy(window, q, z.next_out, p, n);
            p += n;
            q += n;

            // see if more to copy at beginning of window
            if (q == end)
            {
                // wrap pointers
                q = 0;
                if (write == end)
                    write = 0;

                // compute bytes to copy
                n = write - q;
                if (n > z.avail_out) n = z.avail_out;
                if (n != 0 && r == ZLibStatus.Z_BUF_ERROR)
                    r = ZLibStatus.Z_OK;

                // update counters
                z.avail_out -= n;
                z.total_out += n;

                // update check information
                if (checkfn != null)
                {
                    //z.adler = check = z.Adler32(check, window, q, n);
                    z.UpdateAdler(check, window, q, n);
                    check = z.Adler;
                }

                // copy
                System.Array.Copy(window, q, z.next_out, p, n);
                p += n;
                q += n;
            }

            // update pointers
            z.next_out_index = p;
            read = q;

            // done
            return r;
        }
示例#2
0
        public void Reset(ZStream z, long[] c)
        {
            if (c != null) c[0] = check;
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }
            //if (mode == InflateBlockMode.CODES)
            //{
            //    codes.free(z);
            //}
            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
            {
                //z.adler = check = z.Adler32(0L, null, 0, 0);
                z.UpdateAdler(0L, null, 0, 0);
                check = z.Adler;
            }
        }
示例#3
0
        public ZLibStatus deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength)
        {
            int length = dictLength;
            int index = 0;

            if (dictionary == null || status != INIT_STATE)
                return ZLibStatus.Z_STREAM_ERROR;

            //strm.adler = strm.Adler32(strm.adler, dictionary, 0, dictLength);
            strm.UpdateAdler(dictionary, 0, dictLength);


            if (length < MIN_MATCH) return ZLibStatus.Z_OK;
            if (length > w_size - MIN_LOOKAHEAD)
            {
                length = w_size - MIN_LOOKAHEAD;
                index = dictLength - length; // use the tail of the dictionary
            }
            System.Array.Copy(dictionary, index, window, 0, length);
            strstart = length;
            block_start = 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.

            ins_h = window[0] & 0xff;
            ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;

            for (int n = 0; n <= length - MIN_MATCH; n++)
            {
                ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
                prev[n & w_mask] = head[ins_h];
                head[ins_h] = (short)n;
            }
            return ZLibStatus.Z_OK;
        }
示例#4
0
        public ZLibStatus deflate(ZStream strm, FlushType flush)
        {
            FlushType old_flush;

            if (flush > FlushType.Z_FINISH || flush < 0)
            {
                return ZLibStatus.Z_STREAM_ERROR;
            }

            if (strm.next_out == null ||
                (strm.next_in == null && strm.avail_in != 0) ||
                (status == FINISH_STATE && flush != FlushType.Z_FINISH))
            {
                strm.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_STREAM_ERROR)];
                return ZLibStatus.Z_STREAM_ERROR;
            }
            if (strm.avail_out == 0)
            {
                strm.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_BUF_ERROR)];
                return ZLibStatus.Z_BUF_ERROR;
            }

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

            // Write the zlib header
            if (status == INIT_STATE)
            {
                int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
                int level_flags = (((int)level - 1) & 0xff) >> 1;

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

                status = BUSY_STATE;
                putShortMSB(header);


                // Save the adler32 of the preset dictionary:
                if (strstart != 0)
                {
                    putShortMSB((int)(strm.Adler >> 16));
                    putShortMSB((int)(strm.Adler & 0xffff));
                }
                //strm.adler = strm.Adler32(0, null, 0, 0);
                strm.UpdateAdler(0, null, 0, 0);
            }

            // Flush as much pending output as possible
            if (pending != 0)
            {
                strm.flush_pending();
                if (strm.avail_out == 0)
                {
                    //System.out.println("  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:
                    last_flush = (FlushType)(-1);
                    return ZLibStatus.Z_OK;
                }

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

            // User must not provide more input after the first FINISH:
            if (status == FINISH_STATE && strm.avail_in != 0)
            {
                strm.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_BUF_ERROR)];
                return ZLibStatus.Z_BUF_ERROR;
            }

            // Start a new block or continue the current one.
            if (strm.avail_in != 0 || lookahead != 0 ||
                (flush != FlushType.Z_NO_FLUSH && status != FINISH_STATE))
            {
                int bstate = -1;
                switch (_configurationTable[level].Function)
                {
                    case STORED:
                        bstate = deflate_stored(flush);
                        break;
                    case FAST:
                        bstate = deflate_fast(flush);
                        break;
                    case SLOW:
                        bstate = deflate_slow(flush);
                        break;
                    default:
                        break;
                }

                if (bstate == FinishStarted || bstate == FinishDone)
                {
                    status = FINISH_STATE;
                }
                if (bstate == NeedMore || bstate == FinishStarted)
                {
                    if (strm.avail_out == 0)
                    {
                        last_flush = (FlushType)(-1); // avoid BUF_ERROR next call, see above
                    }
                    return ZLibStatus.Z_OK;
                    // If flush != FlushType.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 == BlockDone)
                {
                    if (flush == FlushType.Z_PARTIAL_FLUSH)
                    {
                        _tr_align();
                    }
                    else
                    { // FULL_FLUSH or SYNC_FLUSH
                        _tr_stored_block(0, 0, false);
                        // For a full flush, this empty block will be recognized
                        // as a special marker by inflate_sync().
                        if (flush == FlushType.Z_FULL_FLUSH)
                        {
                            //state.head[s.hash_size-1]=0;
                            for (int i = 0; i < hash_size/*-1*/; i++)  // forget history
                                head[i] = 0;
                        }
                    }
                    strm.flush_pending();
                    if (strm.avail_out == 0)
                    {
                        last_flush = (FlushType)(-1); // avoid BUF_ERROR at next call, see above
                        return ZLibStatus.Z_OK;
                    }
                }
            }

            if (flush != FlushType.Z_FINISH) return ZLibStatus.Z_OK;
            if (noheader != 0) return ZLibStatus.Z_STREAM_END;

            // Write the zlib trailer (adler32)
            putShortMSB((int)(strm.Adler >> 16));
            putShortMSB((int)(strm.Adler & 0xffff));
            strm.flush_pending();

            // If avail_out is zero, the application will call deflate again
            // to flush the rest.
            noheader = -1; // write the trailer only once!
            return pending != 0 ? ZLibStatus.Z_OK : ZLibStatus.Z_STREAM_END;
        }
示例#5
0
        private ZLibStatus deflateReset(ZStream strm)
        {
            strm.total_in = strm.total_out = 0;
            strm.msg = null; //
            //strm.data_type = Z_UNKNOWN;

            pending = 0;
            pending_out = 0;

            if (noheader < 0)
            {
                noheader = 0; // was set to -1 by deflate(..., FlushType.Z_FINISH);
            }
            status = (noheader != 0) ? BUSY_STATE : INIT_STATE;
            //strm.adler = strm.Adler32(0, null, 0, 0);
            strm.UpdateAdler(0L, null, 0, 0);


            last_flush = FlushType.Z_NO_FLUSH;

            tr_init();
            lm_init();
            return ZLibStatus.Z_OK;
        }