internal int Proc(ZStream z, int r) { int t; // temporary storage int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; { // bytes to end of window or read pointer // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; } { q = write; m = (int)(q < read ? read - q - 1 : end - q); } // process input based on current state while (true) { switch (mode) { case TYPE: { while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } t = (int)(b & 7); last = t & 1; switch ((int)(((uint)t) >> 1)) { case 0: { // stored b = (int)(((uint)b) >> (3)); k -= (3); t = k & 7; // go to byte boundary b = (int)(((uint)b) >> (t)); k -= (t); mode = LENS; // get length of stored block break; } case 1: { // fixed int[] bl = new int[1]; int[] bd = new int[1]; int[][] tl = new int[1][]; int[][] td = new int[1][]; InfTree.Inflate_trees_fixed(bl, bd, tl, td, z); codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0, z); b = (int)(((uint)b) >> (3)); k -= (3); mode = CODES; break; } case 2: { // dynamic b = (int)(((uint)b) >> (3)); k -= (3); mode = TABLE; break; } case 3: { // illegal b = (int)(((uint)b) >> (3)); k -= (3); mode = BAD; z.msg = "invalid block type"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } } break; } case LENS: { while (k < (32)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } if ((((int)(((uint)(~b)) >> 16)) & unchecked((int)(0xffff))) != (b & unchecked((int )(0xffff)))) { mode = BAD; z.msg = "invalid stored block lengths"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } left = (b & unchecked((int)(0xffff))); b = k = 0; // dump bits mode = left != 0 ? STORED : (last != 0 ? DRY : TYPE); break; } case STORED: { if (n == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } if (m == 0) { if (q == end && read != 0) { q = 0; m = (int)(q < read ? read - q - 1 : end - q); } if (m == 0) { write = q; r = Inflate_flush(z, r); q = write; m = (int)(q < read ? read - q - 1 : end - q); if (q == end && read != 0) { q = 0; m = (int)(q < read ? read - q - 1 : end - q); } if (m == 0) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } } } r = Z_OK; t = left; if (t > n) { t = n; } if (t > m) { t = m; } System.Array.Copy(z.next_in, p, window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) { break; } mode = last != 0 ? DRY : TYPE; break; } case TABLE: { while (k < (14)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } table = t = (b & unchecked((int)(0x3fff))); if ((t & unchecked((int)(0x1f))) > 29 || ((t >> 5) & unchecked((int)(0x1f))) > 29) { mode = BAD; z.msg = "too many length or distance symbols"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } t = 258 + (t & unchecked((int)(0x1f))) + ((t >> 5) & unchecked((int)(0x1f))); if (blens == null || blens.Length < t) { blens = new int[t]; } else { for (int i = 0; i < t; i++) { blens[i] = 0; } } b = (int)(((uint)b) >> (14)); k -= (14); index = 0; mode = BTREE; goto case BTREE; } case BTREE: { while (index < 4 + ((int)(((uint)table) >> 10))) { while (k < (3)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } blens[border[index++]] = b & 7; { b = (int)(((uint)b) >> (3)); k -= (3); } } while (index < 19) { blens[border[index++]] = 0; } bb[0] = 7; t = inftree.Inflate_trees_bits(blens, bb, tb, hufts, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) { blens = null; mode = BAD; } bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } index = 0; mode = DTREE; goto case DTREE; } case DTREE: { while (true) { t = table; if (!(index < 258 + (t & unchecked((int)(0x1f))) + ((t >> 5) & unchecked((int)(0x1f ))))) { break; } int[] h; int i; int j; int c; t = bb[0]; while (k < (t)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } if (tb[0] == -1) { } //System.err.println("null..."); t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1]; c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2]; if (c < 16) { b = (int)(((uint)b) >> (t)); k -= (t); blens[index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while (k < (t + i)) { if (n != 0) { r = Z_OK; } else { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } b = (int)(((uint)b) >> (t)); k -= (t); j += (b & inflate_mask[i]); b = (int)(((uint)b) >> (i)); k -= (i); i = index; t = table; if (i + j > 258 + (t & unchecked((int)(0x1f))) + ((t >> 5) & unchecked((int)(0x1f ))) || (c == 16 && i < 1)) { blens = null; mode = BAD; z.msg = "invalid bit length repeat"; r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } c = c == 16 ? blens[i - 1] : 0; do { blens[i++] = c; } while (--j != 0); index = i; } } tb[0] = -1; int[] bl = new int[1]; int[] bd = new int[1]; int[] tl = new int[1]; int[] td = new int[1]; bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = inftree.Inflate_trees_dynamic(257 + (t & unchecked((int)(0x1f))), 1 + ((t >> 5) & unchecked((int)(0x1f))), blens, bl, bd, tl, td, hufts, z); if (t != Z_OK) { if (t == Z_DATA_ERROR) { blens = null; mode = BAD; } r = t; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z); mode = CODES; goto case CODES; } case CODES: { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; if ((r = codes.Proc(this, z, r)) != Z_STREAM_END) { return Inflate_flush(z, r); } r = Z_OK; codes.Free(z); p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk; q = write; m = (int)(q < read ? read - q - 1 : end - q); if (last == 0) { mode = TYPE; break; } mode = DRY; goto case DRY; } case DRY: { write = q; r = Inflate_flush(z, r); q = write; m = (int)(q < read ? read - q - 1 : end - q); if (read != write) { bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } mode = DONE; goto case DONE; } case DONE: { r = Z_STREAM_END; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } case BAD: { r = Z_DATA_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } default: { r = Z_STREAM_ERROR; bitb = b; bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; write = q; return Inflate_flush(z, r); } } } }
internal int Inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int [] tl, int[] td, int[] hp, ZStream z) { // number of literal/length codes // number of distance codes // that many (total) code lengths // literal desired/actual bit depth // distance desired/actual bit depth // literal/length tree result // distance tree result // space for trees // for messages int result; // build literal/length tree InitWorkArea(288); hn[0] = 0; result = Huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); if (result != Z_OK || bl[0] == 0) { if (result == Z_DATA_ERROR) { z.msg = "oversubscribed literal/length tree"; } else { if (result != Z_MEM_ERROR) { z.msg = "incomplete literal/length tree"; result = Z_DATA_ERROR; } } return result; } // build distance tree InitWorkArea(288); result = Huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); if (result != Z_OK || (bd[0] == 0 && nl > 257)) { if (result == Z_DATA_ERROR) { z.msg = "oversubscribed distance tree"; } else { if (result == Z_BUF_ERROR) { z.msg = "incomplete distance tree"; result = Z_DATA_ERROR; } else { if (result != Z_MEM_ERROR) { z.msg = "empty distance tree with lengths"; result = Z_DATA_ERROR; } } } return result; } return Z_OK; }
public virtual void End() { if (z == null) { return; } if (compress) { z.DeflateEnd(); } else { z.InflateEnd(); } z.Free(); z = null; }
internal void Free(ZStream z) { Reset(z, null); window = null; hufts = null; }
internal int DoInflate(ZStream z, int f) { int r; int b; if (z == null || z.istate == null || z.next_in == null) { return Z_STREAM_ERROR; } f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (true) { switch (z.istate.mode) { case METHOD: { //System.out.println("mode: "+z.istate.mode); if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; if (((z.istate.method = z.next_in[z.next_in_index++]) & unchecked((int)(0xf))) != Z_DEFLATED) { z.istate.mode = BAD; z.msg = "unknown compression method"; z.istate.marker = 5; // can't try inflateSync break; } if ((z.istate.method >> 4) + 8 > z.istate.wbits) { z.istate.mode = BAD; z.msg = "invalid window size"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = FLAG; goto case FLAG; } case FLAG: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; b = (z.next_in[z.next_in_index++]) & unchecked((int)(0xff)); if ((((z.istate.method << 8) + b) % 31) != 0) { z.istate.mode = BAD; z.msg = "incorrect header check"; z.istate.marker = 5; // can't try inflateSync break; } if ((b & PRESET_DICT) == 0) { z.istate.mode = BLOCKS; break; } z.istate.mode = DICT4; goto case DICT4; } case DICT4: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 24) & unchecked((long)(0xff000000L)); z.istate.mode = DICT3; goto case DICT3; } case DICT3: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 16) & unchecked((long)(0xff0000L)); z.istate.mode = DICT2; goto case DICT2; } case DICT2: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 8) & unchecked((long)(0xff00L)); z.istate.mode = DICT1; goto case DICT1; } case DICT1: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & unchecked((long)(0xffL))); z.adler = z.istate.need; z.istate.mode = DICT0; return Z_NEED_DICT; } case DICT0: { z.istate.mode = BAD; z.msg = "need dictionary"; z.istate.marker = 0; // can try inflateSync return Z_STREAM_ERROR; } case BLOCKS: { r = z.istate.blocks.Proc(z, r); if (r == Z_DATA_ERROR) { z.istate.mode = BAD; z.istate.marker = 0; // can try inflateSync break; } if (r == Z_OK) { r = f; } if (r != Z_STREAM_END) { return r; } r = f; z.istate.blocks.Reset(z, z.istate.was); if (z.istate.nowrap != 0) { z.istate.mode = DONE; break; } z.istate.mode = CHECK4; goto case CHECK4; } case CHECK4: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need = ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 24) & unchecked((long)(0xff000000L)); z.istate.mode = CHECK3; goto case CHECK3; } case CHECK3: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 16) & unchecked((long)(0xff0000L)); z.istate.mode = CHECK2; goto case CHECK2; } case CHECK2: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 8) & unchecked((long)(0xff00L)); z.istate.mode = CHECK1; goto case CHECK1; } case CHECK1: { if (z.avail_in == 0) { return r; } r = f; z.avail_in--; z.total_in++; z.istate.need += (z.next_in[z.next_in_index++] & unchecked((long)(0xffL))); if (((int)(z.istate.was[0])) != ((int)(z.istate.need))) { z.istate.mode = BAD; z.msg = "incorrect data check"; z.istate.marker = 5; // can't try inflateSync break; } z.istate.mode = DONE; goto case DONE; } case DONE: { return Z_STREAM_END; } case BAD: { return Z_DATA_ERROR; } default: { return Z_STREAM_ERROR; break; } } } }
internal int InflateSync(ZStream z) { int n; // number of bytes to look at int p; // pointer to bytes int m; // number of marker bytes found in a row long r; long w; // temporaries to save total_in and total_out // set up if (z == null || z.istate == null) { return Z_STREAM_ERROR; } if (z.istate.mode != BAD) { z.istate.mode = BAD; z.istate.marker = 0; } if ((n = z.avail_in) == 0) { return Z_BUF_ERROR; } p = z.next_in_index; m = z.istate.marker; // search while (n != 0 && m < 4) { if (z.next_in[p] == mark[m]) { m++; } else { if (z.next_in[p] != 0) { m = 0; } else { m = 4 - m; } } p++; n--; } // restore z.total_in += p - z.next_in_index; z.next_in_index = p; z.avail_in = n; z.istate.marker = m; // return no joy or set up to restart on a new block if (m != 4) { return Z_DATA_ERROR; } r = z.total_in; w = z.total_out; InflateReset(z); z.total_in = r; z.total_out = w; z.istate.mode = BLOCKS; return Z_OK; }
internal int DeflateParams(ZStream strm, int _level, int _strategy) { int err = Z_OK; if (_level == Z_DEFAULT_COMPRESSION) { _level = 6; } if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } if (config_table[level].func != config_table[_level].func && strm.total_in != 0) { // Flush the last buffer: err = strm.Deflate(Z_PARTIAL_FLUSH); } if (level != _level) { level = _level; max_lazy_match = config_table[level].max_lazy; good_match = config_table[level].good_length; nice_match = config_table[level].nice_length; max_chain_length = config_table[level].max_chain; } strategy = _strategy; return err; }
internal int InflateEnd(ZStream z) { if (blocks != null) { blocks.Free(z); } blocks = null; // ZFREE(z, z->state); return Z_OK; }
internal int DeflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy) { int noheader = 0; // byte[] my_version=ZLIB_VERSION; // // if (version == null || version[0] != my_version[0] // || stream_size != sizeof(z_stream)) { // return Z_VERSION_ERROR; // } strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (windowBits < 0) { // undocumented feature: suppress zlib header noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } strm.dstate = (Deflate)this; this.noheader = noheader; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); window = new byte[w_size * 2]; prev = new short[w_size]; head = new short[hash_size]; lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. pending_buf = new byte[lit_bufsize * 4]; pending_buf_size = lit_bufsize * 4; d_buf = lit_bufsize / 2; l_buf = (1 + 2) * lit_bufsize; this.level = level; //System.out.println("level="+level); this.strategy = strategy; this.method = unchecked((byte)method); return DeflateReset(strm); }
internal int 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(..., Z_FINISH); status = (noheader != 0) ? BUSY_STATE : INIT_STATE; strm.adler = strm._adler.Adler(0, null, 0, 0); last_flush = Z_NO_FLUSH; Tr_init(); Lm_init(); return Z_OK; }
internal int DeflateInit(ZStream strm, int level) { return DeflateInit(strm, level, MAX_WBITS); }
internal int DeflateInit(ZStream strm, int level, int bits) { return DeflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY ); }
internal static int Inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td , ZStream z) { //literal desired/actual bit depth //distance desired/actual bit depth //literal/length tree result //distance tree result //for memory allocation bl[0] = fixed_bl; bd[0] = fixed_bd; tl[0] = fixed_tl; td[0] = fixed_td; return Z_OK; }
public Compression() { // AES256 + HMACSHA1 stream = new ZStream(); }
internal int DeflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength ) { int length = dictLength; int index = 0; if (dictionary == null || status != INIT_STATE) { return Z_STREAM_ERROR; } strm.adler = strm._adler.Adler(strm.adler, dictionary, 0, dictLength); if (length < MIN_MATCH) { return 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] & unchecked((int)(0xff)); ins_h = (((ins_h) << hash_shift) ^ (window[1] & unchecked((int)(0xff)))) & hash_mask; for (int n = 0; n <= length - MIN_MATCH; n++) { ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & unchecked((int )(0xff)))) & hash_mask; prev[n & w_mask] = head[ins_h]; head[ins_h] = (short)n; } return Z_OK; }
// 32K LZ77 window // preset dictionary flag in zlib header // waiting for method byte // waiting for flag byte // four dictionary check bytes to go // three dictionary check bytes to go // two dictionary check bytes to go // one dictionary check byte to go // waiting for inflateSetDictionary // decompressing blocks // four check bytes to go // three check bytes to go // two check bytes to go // one check byte to go // finished check, done // got an error--stay here // current inflate mode // mode dependent information // if FLAGS, method byte // if CHECK, check values to compare // computed check value // stream check value // if BAD, inflateSync's marker bytes count // mode independent information // flag for no wrapper // log2(window size) (8..15, defaults to 15) // current inflate_blocks state internal int InflateReset(ZStream z) { if (z == null || z.istate == null) { return Z_STREAM_ERROR; } z.total_in = z.total_out = 0; z.msg = null; z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD; z.istate.blocks.Reset(z, null); return Z_OK; }
internal int DoDeflate(ZStream strm, int flush) { int old_flush; if (flush > Z_FINISH || flush < 0) { return Z_STREAM_ERROR; } if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == FINISH_STATE && flush != Z_FINISH)) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)]; return Z_STREAM_ERROR; } if (strm.avail_out == 0) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)]; return 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 = ((level - 1) & unchecked((int)(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)((long)(((ulong)strm.adler) >> 16))); PutShortMSB((int)(strm.adler & unchecked((int)(0xffff)))); } strm.adler = strm._adler.Adler(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 = -1; return Z_OK; } } else { // 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_BUFF_ERROR. if (strm.avail_in == 0 && flush <= old_flush && flush != Z_FINISH) { strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)]; return 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[Z_NEED_DICT - (Z_BUF_ERROR)]; return Z_BUF_ERROR; } // Start a new block or continue the current one. if (strm.avail_in != 0 || lookahead != 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE )) { int bstate = -1; switch (config_table[level].func) { 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 = -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 == BlockDone) { if (flush == 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 == Z_FULL_FLUSH) { //state.head[s.hash_size-1]=0; for (int i = 0; i < hash_size; i++) { // forget history head[i] = 0; } } } strm.Flush_pending(); if (strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR at next call, see above return Z_OK; } } } if (flush != Z_FINISH) { return Z_OK; } if (noheader != 0) { return Z_STREAM_END; } // Write the zlib trailer (adler32) PutShortMSB((int)((long)(((ulong)strm.adler) >> 16))); PutShortMSB((int)(strm.adler & unchecked((int)(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 ? Z_OK : Z_STREAM_END; }
internal int InflateInit(ZStream z, int w) { z.msg = null; blocks = null; // handle undocumented nowrap option (no zlib header or check) nowrap = 0; if (w < 0) { w = -w; nowrap = 1; } // set window size if (w < 8 || w > 15) { InflateEnd(z); return Z_STREAM_ERROR; } wbits = w; z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0 ? null : this, 1 << w); // reset state InflateReset(z); return Z_OK; }
internal void Free(ZStream z) { }
internal int InflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) { int index = 0; int length = dictLength; if (z == null || z.istate == null || z.istate.mode != DICT0) { return Z_STREAM_ERROR; } if (z._adler.Adler(1L, dictionary, 0, dictLength) != z.adler) { return Z_DATA_ERROR; } z.adler = z._adler.Adler(0, null, 0, 0); if (length >= (1 << z.istate.wbits)) { length = (1 << z.istate.wbits) - 1; index = dictLength - length; } z.istate.blocks.Set_dictionary(dictionary, index, length); z.istate.mode = BLOCKS; return Z_OK; }
// ZFREE(z, c); // Called with number of bytes left to write in window at least 258 // (the maximum string length) and number of input bytes available // at least ten. The ten bytes are six bytes for the longest length/ // distance pair plus four bytes for overloading the bit buffer. internal int Inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index , InfBlocks s, ZStream z) { int t; // temporary pointer int[] tp; // temporary pointer int tp_index; // temporary pointer int e; // extra bits or operation int b; // bit buffer int k; // bits in bit buffer int p; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int ml; // mask for literal/length tree int md; // mask for distance tree int c; // bytes to copy int d; // distance back to copy from int r; // copy source pointer int tp_index_t_3; // (tp_index+t)*3 // load input, output, bit values p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; // initialize masks ml = inflate_mask[bl]; md = inflate_mask[bd]; do { // do until not enough input or output space for fast loop // assume called with m >= 258 && n >= 10 // get literal/length code while (k < (20)) { // max bits for literal/length code n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } t = b & ml; tp = tl; tp_index = tl_index; tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = unchecked((byte)tp[tp_index_t_3 + 2]); m--; continue; } do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { e &= 15; c = tp[tp_index_t_3 + 2] + ((int)b & inflate_mask[e]); b >>= e; k -= e; // decode distance base of block to copy while (k < (15)) { // max bits for distance code n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } t = b & md; tp = td; tp_index = td_index; tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; do { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); if ((e & 16) != 0) { // get extra bits to add to distance base e &= 15; while (k < (e)) { // get extra bits (up to 13) n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]); b >>= (e); k -= (e); // do the copy m -= c; if (q >= d) { // offset before dest // just copy r = q - d; if (q - r > 0 && 2 > (q - r)) { s.window[q++] = s.window[r++]; // minimum count is three, s.window[q++] = s.window[r++]; // so unroll loop a little c -= 2; } else { System.Array.Copy(s.window, r, s.window, q, 2); q += 2; r += 2; c -= 2; } } else { // else offset after destination r = q - d; do { r += s.end; } while (r < 0); // force pointer in window // covers invalid distances e = s.end - r; if (c > e) { // if source crosses, c -= e; // wrapped copy if (q - r > 0 && e > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--e != 0); } else { System.Array.Copy(s.window, r, s.window, q, e); q += e; r += e; e = 0; } r = 0; } } // copy rest from start of window // copy all or what's left if (q - r > 0 && c > (q - r)) { do { s.window[q++] = s.window[r++]; } while (--c != 0); } else { System.Array.Copy(s.window, r, s.window, q, c); q += c; r += c; c = 0; } break; } else { if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; e = tp[tp_index_t_3]; } else { z.msg = "invalid distance code"; c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } } while (true); break; } if ((e & 64) == 0) { t += tp[tp_index_t_3 + 2]; t += (b & inflate_mask[e]); tp_index_t_3 = (tp_index + t) * 3; if ((e = tp[tp_index_t_3]) == 0) { b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); s.window[q++] = unchecked((byte)tp[tp_index_t_3 + 2]); m--; break; } } else { if ((e & 32) != 0) { c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_STREAM_END; } else { z.msg = "invalid literal/length code"; c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_DATA_ERROR; } } } while (true); } while (m >= 258 && n >= 10); // not enough input or output--restore pointers and return c = z.avail_in - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= c << 3; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return Z_OK; }
// 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. internal int InflateSyncPoint(ZStream z) { if (z == null || z.istate == null || z.istate.blocks == null) { return Z_STREAM_ERROR; } return z.istate.blocks.Sync_point(); }
// waiting for "i:"=input, // "o:"=output, // "x:"=nothing // x: set up for LEN // i: get length/literal/eob next // i: getting length extra (have base) // i: get distance next // i: getting distance extra // o: copying bytes in window, waiting for space // o: got literal, waiting for output space // o: got eob, possibly still output waiting // x: got eob and all data flushed // x: got error // current inflate_codes mode // mode dependent information // pointer into tree // bits needed // if EXT or COPY, where and how much // bits to get for extra // distance back to copy from // ltree bits decoded per branch // dtree bits decoder per branch // literal/length/eob tree // literal/length/eob tree // distance tree // distance tree internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index , ZStream z) { mode = START; lbits = unchecked((byte)bl); dbits = unchecked((byte)bd); ltree = tl; ltree_index = tl_index; dtree = td; dtree_index = td_index; tree = null; }
internal InfBlocks(ZStream z, object checkfn, int w) { // And'ing with mask[n] masks the lower n bits // Table for deflate from PKZIP's appnote.txt. // Order of the bit length code lengths // get type bits (3, including end bit) // get lengths for stored // processing stored block // get table lengths // get bit lengths tree for a dynamic block // get length, distance trees for a dynamic block // processing fixed or dynamic block // output remaining window bytes // finished last block, done // ot a data error--stuck here // current inflate_block mode // if STORED, bytes left to copy // table lengths (14 bits) // index into blens (or border) // bit lengths of codes // bit length tree depth // bit length decoding tree // if CODES, current state // true if this block is the last block // mode independent information // bits in bit buffer // bit buffer // single malloc for tree space // sliding window // one byte after sliding window // window read pointer // window write pointer // check function // check on output hufts = new int[MANY * 3]; window = new byte[w]; end = w; this.checkfn = checkfn; mode = TYPE; Reset(z, null); }
internal int Proc(InfBlocks s, ZStream z, int r) { int j; // temporary storage int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation int b = 0; // bit buffer int k = 0; // bits in bit buffer int p = 0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; // process input and output based on current state while (true) { switch (mode) { case START: { // waiting for "i:"=input, "o:"=output, "x:"=nothing // x: set up for LEN if (m >= 258 && n >= 10) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; r = Inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p = z.next_in_index; n = z.avail_in; b = s.bitb; k = s.bitk; q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (r != Z_OK) { mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = LEN; goto case LEN; } case LEN: { // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b = (int)(((uint)b) >> (tree[tindex + 1])); k -= (tree[tindex + 1]); e = tree[tindex]; if (e == 0) { // literal lit = tree[tindex + 2]; mode = LIT; break; } if ((e & 16) != 0) { // length get = e & 15; len = tree[tindex + 2]; mode = LENEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } case LENEXT: { // i: getting length extra (have base) j = get; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } len += (b & inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = DIST; goto case DIST; } case DIST: { // i: get distance next j = need; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } tindex = (tree_index + (b & inflate_mask[j])) * 3; b >>= tree[tindex + 1]; k -= tree[tindex + 1]; e = (tree[tindex]); if ((e & 16) != 0) { // distance get = e & 15; dist = tree[tindex + 2]; mode = DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } case DISTEXT: { // i: getting distance extra j = get; while (k < (j)) { if (n != 0) { r = Z_OK; } else { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } n--; b |= (z.next_in[p++] & unchecked((int)(0xff))) << k; k += 8; } dist += (b & inflate_mask[j]); b >>= j; k -= j; mode = COPY; goto case COPY; } case COPY: { // o: copying bytes in window, waiting for space f = q - dist; while (f < 0) { // modulo window size-"while" instead f += s.end; } // of "if" handles invalid distances while (len != 0) { if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.write = q; r = s.Inflate_flush(z, r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } } } s.window[q++] = s.window[f++]; m--; if (f == s.end) { f = 0; } len--; } mode = START; break; } case LIT: { // o: got literal, waiting for output space if (m == 0) { if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.write = q; r = s.Inflate_flush(z, r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (q == s.end && s.read != 0) { q = 0; m = q < s.read ? s.read - q - 1 : s.end - q; } if (m == 0) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } } } r = Z_OK; s.window[q++] = unchecked((byte)lit); m--; mode = START; break; } case WASH: { // o: got eob, possibly more output if (k > 7) { // return unused byte, if any k -= 8; n++; p--; } // can always return one s.write = q; r = s.Inflate_flush(z, r); q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q; if (s.read != s.write) { s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } mode = END; goto case END; } case END: { r = Z_STREAM_END; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } case BADCODE: { // x: got error r = Z_DATA_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } default: { r = Z_STREAM_ERROR; s.bitb = b; s.bitk = k; z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p; s.write = q; return s.Inflate_flush(z, r); } } } }
// copy as much as possible from the sliding window to the output area internal int Inflate_flush(ZStream z, int 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 == Z_BUF_ERROR) { r = Z_OK; } // update counters z.avail_out -= n; z.total_out += n; // update check information if (checkfn != null) { z.adler = check = z._adler.Adler(check, window, q, n); } // 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 == Z_BUF_ERROR) { r = Z_OK; } // update counters z.avail_out -= n; z.total_out += n; // update check information if (checkfn != null) { z.adler = check = z._adler.Adler(check, window, q, n); } // 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 Compression() { stream = new ZStream(); }
internal void Reset(ZStream z, long[] c) { if (c != null) { c[0] = check; } if (mode == BTREE || mode == DTREE) { } if (mode == CODES) { codes.Free(z); } mode = TYPE; bitk = 0; bitb = 0; read = write = 0; if (checkfn != null) { z.adler = check = z._adler.Adler(0L, null, 0, 0); } }
internal int Inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZStream z) { // 19 code lengths // bits tree desired/actual depth // bits tree result // space for trees // for messages int result; InitWorkArea(19); hn[0] = 0; result = Huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); if (result == Z_DATA_ERROR) { z.msg = "oversubscribed dynamic bit lengths tree"; } else { if (result == Z_BUF_ERROR || bb[0] == 0) { z.msg = "incomplete dynamic bit lengths tree"; result = Z_DATA_ERROR; } } return result; }