internal int End() { if ( blocks != null ) blocks.Free (); blocks = null; return ZlibConstants.Z_OK; }
internal int Process( InflateBlocks blocks, int r ) { int j; int tindex; int e; int b = 0; int k = 0; int p = 0; int n; int q; int m; int f; ZlibCodec z = blocks._codec; p = z.NextIn; n = z.AvailableBytesIn; b = blocks.bitb; k = blocks.bitk; q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; while ( true ) { switch ( mode ) { case START: if ( m >= 258 && n >= 10 ) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; r = InflateFast ( lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z ); p = z.NextIn; n = z.AvailableBytesIn; b = blocks.bitb; k = blocks.bitk; q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if ( r != ZlibConstants.Z_OK ) { mode = ( r == ZlibConstants.Z_STREAM_END ) ? WASH : BADCODE; break; } } need = lbits; tree = ltree; tree_index = ltree_index; mode = LEN; goto case LEN; case LEN: j = need; while ( k < j ) { if ( n != 0 ) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } n--; b |= ( z.InputBuffer [ p++ ] & 0xff ) << k; k += 8; } tindex = ( tree_index + ( b & InternalInflateConstants.InflateMask [ j ] ) ) * 3; b >>= ( tree [ tindex + 1 ] ); k -= ( tree [ tindex + 1 ] ); e = tree [ tindex ]; if ( e == 0 ) { lit = tree [ tindex + 2 ]; mode = LIT; break; } if ( ( e & 16 ) != 0 ) { bitsToGet = e & 15; len = tree [ tindex + 2 ]; mode = LENEXT; break; } if ( ( e & 64 ) == 0 ) { need = e; tree_index = tindex / 3 + tree [ tindex + 2 ]; break; } if ( ( e & 32 ) != 0 ) { mode = WASH; break; } mode = BADCODE; z.Message = "invalid literal/length code"; r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); case LENEXT: j = bitsToGet; while ( k < j ) { if ( n != 0 ) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } n--; b |= ( z.InputBuffer [ p++ ] & 0xff ) << k; k += 8; } len += ( b & InternalInflateConstants.InflateMask [ j ] ); b >>= j; k -= j; need = dbits; tree = dtree; tree_index = dtree_index; mode = DIST; goto case DIST; case DIST: j = need; while ( k < j ) { if ( n != 0 ) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } n--; b |= ( z.InputBuffer [ p++ ] & 0xff ) << k; k += 8; } tindex = ( tree_index + ( b & InternalInflateConstants.InflateMask [ j ] ) ) * 3; b >>= tree [ tindex + 1 ]; k -= tree [ tindex + 1 ]; e = ( tree [ tindex ] ); if ( ( e & 0x10 ) != 0 ) { bitsToGet = e & 15; dist = tree [ tindex + 2 ]; mode = DISTEXT; break; } if ( ( e & 64 ) == 0 ) { need = e; tree_index = tindex / 3 + tree [ tindex + 2 ]; break; } mode = BADCODE; z.Message = "invalid distance code"; r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); case DISTEXT: j = bitsToGet; while ( k < j ) { if ( n != 0 ) r = ZlibConstants.Z_OK; else { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } n--; b |= ( z.InputBuffer [ p++ ] & 0xff ) << k; k += 8; } dist += ( b & InternalInflateConstants.InflateMask [ j ] ); b >>= j; k -= j; mode = COPY; goto case COPY; case COPY: f = q - dist; while ( f < 0 ) { f += blocks.end; } while ( len != 0 ) { if ( m == 0 ) { if ( q == blocks.end && blocks.readAt != 0 ) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if ( m == 0 ) { blocks.writeAt = q; r = blocks.Flush ( r ); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if ( q == blocks.end && blocks.readAt != 0 ) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if ( m == 0 ) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } } } blocks.window [ q++ ] = blocks.window [ f++ ]; m--; if ( f == blocks.end ) f = 0; len--; } mode = START; break; case LIT: if ( m == 0 ) { if ( q == blocks.end && blocks.readAt != 0 ) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if ( m == 0 ) { blocks.writeAt = q; r = blocks.Flush ( r ); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if ( q == blocks.end && blocks.readAt != 0 ) { q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; } if ( m == 0 ) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } } } r = ZlibConstants.Z_OK; blocks.window [ q++ ] = ( byte ) lit; m--; mode = START; break; case WASH: if ( k > 7 ) { k -= 8; n++; p--; } blocks.writeAt = q; r = blocks.Flush ( r ); q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; if ( blocks.readAt != blocks.writeAt ) { blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } mode = END; goto case END; case END: r = ZlibConstants.Z_STREAM_END; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); case BADCODE: r = ZlibConstants.Z_DATA_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); default: r = ZlibConstants.Z_STREAM_ERROR; blocks.bitb = b; blocks.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; blocks.writeAt = q; return blocks.Flush ( r ); } } }
internal int Initialize( ZlibCodec codec, int w ) { _codec = codec; _codec.Message = null; blocks = null; if ( w < 8 || w > 15 ) { End (); throw new CompressionProcessException ( "Bad window size." ); } wbits = w; blocks = new InflateBlocks ( codec, HandleRfc1950HeaderBytes ? this : null, 1 << w ); Reset (); return ZlibConstants.Z_OK; }
internal int InflateFast( int bl, int bd, int [] tl, int tl_index, int [] td, int td_index, InflateBlocks s, ZlibCodec z ) { int t; int [] tp; int tp_index; int e; int b; int k; int p; int n; int q; int m; int ml; int md; int c; int d; int r; int tp_index_t_3; p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk; q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q; ml = InternalInflateConstants.InflateMask [ bl ]; md = InternalInflateConstants.InflateMask [ bd ]; do { while ( k < ( 20 ) ) { n--; b |= ( z.InputBuffer [ p++ ] & 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++ ] = ( 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 & InternalInflateConstants.InflateMask [ e ] ); b >>= e; k -= e; while ( k < 15 ) { n--; b |= ( z.InputBuffer [ p++ ] & 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 ) { e &= 15; while ( k < e ) { n--; b |= ( z.InputBuffer [ p++ ] & 0xff ) << k; k += 8; } d = tp [ tp_index_t_3 + 2 ] + ( b & InternalInflateConstants.InflateMask [ e ] ); b >>= e; k -= e; m -= c; if ( q >= d ) { r = q - d; if ( q - r > 0 && 2 > ( q - r ) ) { s.window [ q++ ] = s.window [ r++ ]; s.window [ q++ ] = s.window [ r++ ]; c -= 2; } else { Array.Copy ( s.window, r, s.window, q, 2 ); q += 2; r += 2; c -= 2; } } else { r = q - d; do { r += s.end; } while ( r < 0 ); e = s.end - r; if ( c > e ) { c -= e; if ( q - r > 0 && e > ( q - r ) ) { do { s.window [ q++ ] = s.window [ r++ ]; } while ( --e != 0 ); } else { Array.Copy ( s.window, r, s.window, q, e ); q += e; r += e; e = 0; } r = 0; } } if ( q - r > 0 && c > ( q - r ) ) { do { s.window [ q++ ] = s.window [ r++ ]; } while ( --c != 0 ); } else { 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 & InternalInflateConstants.InflateMask [ e ] ); tp_index_t_3 = ( tp_index + t ) * 3; e = tp [ tp_index_t_3 ]; } else { z.Message = "invalid distance code"; c = z.AvailableBytesIn - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= ( c << 3 ); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_DATA_ERROR; } } while ( true ); break; } if ( ( e & 64 ) == 0 ) { t += tp [ tp_index_t_3 + 2 ]; t += ( b & InternalInflateConstants.InflateMask [ 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++ ] = ( byte ) tp [ tp_index_t_3 + 2 ]; m--; break; } } else if ( ( e & 32 ) != 0 ) { c = z.AvailableBytesIn - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= ( c << 3 ); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_STREAM_END; } else { z.Message = "invalid literal/length code"; c = z.AvailableBytesIn - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= ( c << 3 ); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_DATA_ERROR; } } while ( true ); } while ( m >= 258 && n >= 10 ); c = z.AvailableBytesIn - n; c = ( k >> 3 ) < c ? k >> 3 : c; n += c; p -= c; k -= ( c << 3 ); s.bitb = b; s.bitk = k; z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; s.writeAt = q; return ZlibConstants.Z_OK; }