private int _dtreeIndex; // distance tree internal void InitCodes(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) { this._mode = InflateCodeMode.START; this._lbits = (byte)bl; this._dbits = (byte)bd; this._ltree = tl; this._ltreeIndex = tl_index; this._dtree = td; this._dtreeIndex = td_index; this._tree = null; }
internal void codesinit(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) { mode = InflateCodeMode.START; lbits = (byte)bl; dbits = (byte)bd; ltree = tl; ltree_index = tl_index; dtree = td; dtree_index = td_index; tree = null; }
internal ZLibStatus ProcessCodes(InfBlocks s, ZStream z, ZLibStatus r) { int j; // temporary storage 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 (this._mode) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case InflateCodeMode.START: // x: set up for InflateCodeMode.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 = InflateFast(this._lbits, this._dbits, this._ltree, this._ltreeIndex, this._dtree, _dtreeIndex, 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 != ZLibStatus.Z_OK) { this._mode = r == ZLibStatus.Z_STREAM_END ? InflateCodeMode.WASH : InflateCodeMode.BADCODE; break; } } this._need = this._lbits; this._tree = this._ltree; this._treeIndex = this._ltreeIndex; this._mode = InflateCodeMode.LEN; goto case InflateCodeMode.LEN; case InflateCodeMode.LEN: // i: get length/literal/eob next j = this._need; while (k < (j)) { if (n != 0) { r = ZLibStatus.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++] & 0xff) << k; k += 8; } tindex = (this._treeIndex + (b & inflate_mask[j])) * 3; b >>= (this._tree[tindex + 1]); k -= (this._tree[tindex + 1]); e = this._tree[tindex]; if (e == 0) { // literal this._lit = this._tree[tindex + 2]; this._mode = InflateCodeMode.LIT; break; } if ((e & 16) != 0) { // length this._get = e & 15; this._len = this._tree[tindex + 2]; this._mode = InflateCodeMode.LENEXT; break; } if ((e & 64) == 0) { // next table this._need = e; this._treeIndex = tindex / 3 + this._tree[tindex + 2]; break; } if ((e & 32) != 0) { // end of block this._mode = InflateCodeMode.WASH; break; } this._mode = InflateCodeMode.BADCODE; // invalid code z.msg = "invalid literal/length code"; r = ZLibStatus.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 InflateCodeMode.LENEXT: // i: getting length extra (have base) j = this._get; while (k < (j)) { if (n != 0) { r = ZLibStatus.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++] & 0xff) << k; k += 8; } this._len += (b & inflate_mask[j]); b >>= j; k -= j; this._need = this._dbits; this._tree = this._dtree; this._treeIndex = _dtreeIndex; this._mode = InflateCodeMode.DIST; goto case InflateCodeMode.DIST; case InflateCodeMode.DIST: // i: get distance next j = this._need; while (k < (j)) { if (n != 0) { r = ZLibStatus.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++] & 0xff) << k; k += 8; } tindex = (this._treeIndex + (b & inflate_mask[j])) * 3; b >>= this._tree[tindex + 1]; k -= this._tree[tindex + 1]; e = (this._tree[tindex]); if ((e & 16) != 0) { // distance this._get = e & 15; this._dist = this._tree[tindex + 2]; this._mode = InflateCodeMode.DISTEXT; break; } if ((e & 64) == 0) { // next table this._need = e; this._treeIndex = tindex / 3 + this._tree[tindex + 2]; break; } this._mode = InflateCodeMode.BADCODE; // invalid code z.msg = "invalid distance code"; r = ZLibStatus.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 InflateCodeMode.DISTEXT: // i: getting distance extra j = this._get; while (k < (j)) { if (n != 0) { r = ZLibStatus.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++] & 0xff) << k; k += 8; } this._dist += (b & inflate_mask[j]); b >>= j; k -= j; this._mode = InflateCodeMode.COPY; goto case InflateCodeMode.COPY; case InflateCodeMode.COPY: // o: copying bytes in window, waiting for space f = q - this._dist; while (f < 0) { // modulo window size-"while" instead f += s.end; // of "if" handles invalid distances } while (this._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; } this._len--; } this._mode = InflateCodeMode.START; break; case InflateCodeMode.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 = ZLibStatus.Z_OK; s.window[q++] = (byte)this._lit; m--; this._mode = InflateCodeMode.START; break; case InflateCodeMode.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)); } this._mode = InflateCodeMode.END; goto case InflateCodeMode.END; case InflateCodeMode.END: r = ZLibStatus.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 InflateCodeMode.BADCODE: // x: got error r = ZLibStatus.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 = ZLibStatus.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)); } } }
internal ZLibStatus codesproc(InflateBlocks s, ZStream z, ZLibStatus r) { int j; // temporary storage 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) { // waiting for "i:"=input, "o:"=output, "x:"=nothing case InflateCodeMode.START: // 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 != ZLibStatus.Z_OK) { mode = r == ZLibStatus.Z_STREAM_END ? InflateCodeMode.WASH : InflateCodeMode.BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = InflateCodeMode.LEN; goto case InflateCodeMode.LEN; case InflateCodeMode.LEN: // i: get length/literal/eob next j = need; while (k < (j)) { if (n != 0) r = ZLibStatus.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++] & 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 == 0) { // literal lit = tree[tindex + 2]; mode = InflateCodeMode.LIT; break; } if ((e & 16) != 0) { // length get = e & 15; len = tree[tindex + 2]; mode = InflateCodeMode.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 = InflateCodeMode.WASH; break; } mode = InflateCodeMode.BADCODE; // invalid code z.msg = "invalid literal/length code"; r = ZLibStatus.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 InflateCodeMode.LENEXT: // i: getting length extra (have base) j = get; while (k < (j)) { if (n != 0) r = ZLibStatus.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++] & 0xff) << k; k += 8; } len += (b & inflate_mask[j]); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = InflateCodeMode.DIST; goto case InflateCodeMode.DIST; case InflateCodeMode.DIST: // i: get distance next j = need; while (k < (j)) { if (n != 0) r = ZLibStatus.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++] & 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 = InflateCodeMode.DISTEXT; break; } if ((e & 64) == 0) { // next table need = e; tree_index = tindex / 3 + tree[tindex + 2]; break; } mode = InflateCodeMode.BADCODE; // invalid code z.msg = "invalid distance code"; r = ZLibStatus.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 InflateCodeMode.DISTEXT: // i: getting distance extra j = get; while (k < (j)) { if (n != 0) r = ZLibStatus.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++] & 0xff) << k; k += 8; } dist += (b & inflate_mask[j]); b >>= j; k -= j; mode = InflateCodeMode.COPY; goto case InflateCodeMode.COPY; case InflateCodeMode.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 = InflateCodeMode.START; break; case InflateCodeMode.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 = ZLibStatus.Z_OK; s.window[q++] = (byte)lit; m--; mode = InflateCodeMode.START; break; case InflateCodeMode.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 = InflateCodeMode.END; goto case InflateCodeMode.END; case InflateCodeMode.END: r = ZLibStatus.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 InflateCodeMode.BADCODE: // x: got error r = ZLibStatus.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 = ZLibStatus.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); } } }
internal void codesinit(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) { mode = InflateCodeMode.START; lbits = (byte)bl; dbits = (byte)bd; ltree = tl; ltree_index = tl_index; dtree = td; dtree_index = td_index; tree = null; }
private void InitCodes(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) { this._mode = InflateCodeMode.START; this._lbits = (byte)bl; this._dbits = (byte)bd; this._ltree = tl; this._ltreeIndex = tl_index; this._dtree = td; this._dtreeIndex = td_index; this._tree = null; }