/// <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; }
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; } }
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; }
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; }
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; }