diff src/com/jcraft/jzlib/InfBlocks.java @ 357:46c2115ae1c8

update jzlib to a21be20213d66eff15904d925e9b721956a01ef7
author Carl Byington <carl@five-ten-sg.com>
date Fri, 01 Aug 2014 13:34:58 -0700
parents 0ce5cc452d02
children
line wrap: on
line diff
--- a/src/com/jcraft/jzlib/InfBlocks.java	Fri Aug 01 11:57:17 2014 -0700
+++ b/src/com/jcraft/jzlib/InfBlocks.java	Fri Aug 01 13:34:58 2014 -0700
@@ -1,6 +1,6 @@
 /* -*-mode:java; c-basic-offset:2; -*- */
 /*
-Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
+Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -8,8 +8,8 @@
   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
 
-  2. Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in
+  2. Redistributions in binary form must reproduce the above copyright 
+     notice, this list of conditions and the following disclaimer in 
      the documentation and/or other materials provided with the distribution.
 
   3. The names of the authors may not be used to endorse or promote products
@@ -34,619 +34,581 @@
 
 package com.jcraft.jzlib;
 
-final class InfBlocks {
-    static final private int MANY = 1440;
+final class InfBlocks{
+  static final private int MANY=1440;
+
+  // And'ing with mask[n] masks the lower n bits
+  static final private int[] inflate_mask = {
+    0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
+    0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
+    0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
+    0x00007fff, 0x0000ffff
+  };
+
+  // Table for deflate from PKZIP's appnote.txt.
+  static final int[] border = { // Order of the bit length code lengths
+    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+  };
+
+  static final private int Z_OK=0;
+  static final private int Z_STREAM_END=1;
+  static final private int Z_NEED_DICT=2;
+  static final private int Z_ERRNO=-1;
+  static final private int Z_STREAM_ERROR=-2;
+  static final private int Z_DATA_ERROR=-3;
+  static final private int Z_MEM_ERROR=-4;
+  static final private int Z_BUF_ERROR=-5;
+  static final private int Z_VERSION_ERROR=-6;
+
+  static final private int TYPE=0;  // get type bits (3, including end bit)
+  static final private int LENS=1;  // get lengths for stored
+  static final private int STORED=2;// processing stored block
+  static final private int TABLE=3; // get table lengths
+  static final private int BTREE=4; // get bit lengths tree for a dynamic block
+  static final private int DTREE=5; // get length, distance trees for a dynamic block
+  static final private int CODES=6; // processing fixed or dynamic block
+  static final private int DRY=7;   // output remaining window bytes
+  static final private int DONE=8;  // finished last block, done
+  static final private int BAD=9;   // ot a data error--stuck here
+
+  int mode;            // current inflate_block mode 
+
+  int left;            // if STORED, bytes left to copy 
+
+  int table;           // table lengths (14 bits) 
+  int index;           // index into blens (or border) 
+  int[] blens;         // bit lengths of codes 
+  int[] bb=new int[1]; // bit length tree depth 
+  int[] tb=new int[1]; // bit length decoding tree 
+
+  int[] bl=new int[1];
+  int[] bd=new int[1];
+
+  int[][] tl=new int[1][];
+  int[][] td=new int[1][];
+  int[] tli=new int[1]; // tl_index
+  int[] tdi=new int[1]; // td_index
+
+  private final InfCodes codes;      // if CODES, current state 
 
-    // And'ing with mask[n] masks the lower n bits
-    static final private int[] inflate_mask = {
-        0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
-        0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
-        0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
-        0x00007fff, 0x0000ffff
-    };
+  int last;            // true if this block is the last block 
+
+  // mode independent information 
+  int bitk;            // bits in bit buffer 
+  int bitb;            // bit buffer 
+  int[] hufts;         // single malloc for tree space 
+  byte[] window;       // sliding window 
+  int end;             // one byte after sliding window 
+  int read;            // window read pointer 
+  int write;           // window write pointer 
+  private boolean check;
+
+  private final InfTree inftree=new InfTree();
+
+  private final ZStream z; 
+
+  InfBlocks(ZStream z, int w){
+    this.z=z;
+    this.codes=new InfCodes(this.z, this);
+    hufts=new int[MANY*3];
+    window=new byte[w];
+    end=w;
+    this.check = (z.istate.wrap==0) ? false : true;
+    mode = TYPE;
+    reset();
+  }
 
-    // Table for deflate from PKZIP's appnote.txt.
-    static final int[] border = { // Order of the bit length code lengths
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-    };
+  void reset(){
+    if(mode==BTREE || mode==DTREE){
+    }
+    if(mode==CODES){
+      codes.free(z);
+    }
+    mode=TYPE;
+    bitk=0;
+    bitb=0;
+    read=write=0;
+    if(check){
+      z.adler.reset();
+    }
+  }
+
+  int proc(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:
 
-    static final private int Z_OK = 0;
-    static final private int Z_STREAM_END = 1;
-    static final private int Z_NEED_DICT = 2;
-    static final private int Z_ERRNO = -1;
-    static final private int Z_STREAM_ERROR = -2;
-    static final private int Z_DATA_ERROR = -3;
-    static final private int Z_MEM_ERROR = -4;
-    static final private int Z_BUF_ERROR = -5;
-    static final private int Z_VERSION_ERROR = -6;
+	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(r);
+	  };
+	  n--;
+	  b|=(z.next_in[p++]&0xff)<<k;
+	  k+=8;
+	}
+	t = (int)(b & 7);
+	last = t & 1;
+
+	switch (t >>> 1){
+        case 0:                         // stored 
+          {b>>>=(3);k-=(3);}
+          t = k & 7;                    // go to byte boundary
+
+          {b>>>=(t);k-=(t);}
+          mode = LENS;                  // get length of stored block
+          break;
+        case 1:                         // fixed
+          InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
+          codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
+
+          {b>>>=(3);k-=(3);}
+
+          mode = CODES;
+          break;
+        case 2:                         // dynamic
+
+          {b>>>=(3);k-=(3);}
+
+          mode = TABLE;
+          break;
+        case 3:                         // illegal
+
+          {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(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(r);
+	  };
+	  n--;
+	  b|=(z.next_in[p++]&0xff)<<k;
+	  k+=8;
+	}
 
-    static final private int TYPE = 0; // get type bits (3, including end bit)
-    static final private int LENS = 1; // get lengths for stored
-    static final private int STORED = 2; // processing stored block
-    static final private int TABLE = 3; // get table lengths
-    static final private int BTREE = 4; // get bit lengths tree for a dynamic block
-    static final private int DTREE = 5; // get length, distance trees for a dynamic block
-    static final private int CODES = 6; // processing fixed or dynamic block
-    static final private int DRY = 7; // output remaining window bytes
-    static final private int DONE = 8; // finished last block, done
-    static final private int BAD = 9; // ot a data error--stuck here
+	if ((((~b) >>> 16) & 0xffff) != (b & 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(r);
+	}
+	left = (b & 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(r);
+	}
 
-    int mode;            // current inflate_block mode
+	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(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(r);
+	    }
+	  }
+	}
+	r=Z_OK;
 
-    int left;            // if STORED, bytes left to copy
+	t = left;
+	if(t>n) t = n;
+	if(t>m) t = m;
+	System.arraycopy(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(r);
+	  };
+	  n--;
+	  b|=(z.next_in[p++]&0xff)<<k;
+	  k+=8;
+	}
+
+	table = t = (b & 0x3fff);
+	if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+	  {
+	    mode = BAD;
+	    z.msg = "too many length or distance symbols";
+	    r = Z_DATA_ERROR;
 
-    int table;           // table lengths (14 bits)
-    int index;           // index into blens (or border)
-    int[] blens;         // bit lengths of codes
-    int[] bb = new int[1]; // bit length tree depth
-    int[] tb = new int[1]; // bit length decoding tree
+	    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(r);
+	  }
+	t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+	if(blens==null || blens.length<t){
+	  blens=new int[t];
+	}
+	else{
+	  for(int i=0; i<t; i++){blens[i]=0;}
+	}
+
+	{b>>>=(14);k-=(14);}
 
-    InfCodes codes = new InfCodes();    // if CODES, current state
+	index = 0;
+	mode = BTREE;
+      case BTREE:
+	while (index < 4 + (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(r);
+	    };
+	    n--;
+	    b|=(z.next_in[p++]&0xff)<<k;
+	    k+=8;
+	  }
+
+	  blens[border[index++]] = b&7;
 
-    int last;            // true if this block is the last block
+	  {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(r);
+	}
 
-    // mode independent information
-    int bitk;            // bits in bit buffer
-    int bitb;            // bit buffer
-    int[] hufts;         // single malloc for tree space
-    byte[] window;       // sliding window
-    int end;             // one byte after sliding window
-    int read;            // window read pointer
-    int write;           // window write pointer
-    Object checkfn;      // check function
-    long check;          // check on output
+	index = 0;
+	mode = DTREE;
+      case DTREE:
+	while (true){
+	  t = table;
+	  if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){
+	    break;
+	  }
+
+	  int[] h;
+	  int i, j, 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(r);
+	    };
+	    n--;
+	    b|=(z.next_in[p++]&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];
 
-    InfTree inftree = new InfTree();
+	  if (c < 16){
+	    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(r);
+	      };
+	      n--;
+	      b|=(z.next_in[p++]&0xff)<<k;
+	      k+=8;
+	    }
+
+	    b>>>=(t);k-=(t);
+
+	    j += (b & inflate_mask[i]);
+
+	    b>>>=(i);k-=(i);
+
+	    i = index;
+	    t = table;
+	    if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+		(c == 16 && i < 1)){
+	      blens=null;
+	      mode = BAD;
+	      z.msg = "invalid bit length repeat";
+	      r = Z_DATA_ERROR;
 
-    InfBlocks(ZStream z, Object checkfn, int w) {
-        hufts = new int[MANY * 3];
-        window = new byte[w];
-        end = w;
-        this.checkfn = checkfn;
-        mode = TYPE;
-        reset(z, null);
-    }
+	      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(r);
+	    }
+
+	    c = c == 16 ? blens[i-1] : 0;
+	    do{
+	      blens[i++] = c;
+	    }
+	    while (--j!=0);
+	    index = i;
+	  }
+	}
+
+	tb[0]=-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 & 0x1f), 
+					    1 + ((t >> 5) & 0x1f),
+					    blens, bl, bd, tli, tdi, hufts, z);
 
-    void reset(ZStream z, long[] c) {
-        if (c != null) c[0] = check;
+	  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(r);
+	  }
+	  codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]);
+	}
+	mode = 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(r)) != Z_STREAM_END){
+	  return inflate_flush(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 (mode == BTREE || mode == DTREE) {
-        }
+	if (last==0){
+	  mode = TYPE;
+	  break;
+	}
+	mode = DRY;
+      case DRY:
+	write=q; 
+	r=inflate_flush(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(r);
+	}
+	mode = DONE;
+      case DONE:
+	r = Z_STREAM_END;
 
-        if (mode == CODES) {
-            codes.free(z);
-        }
+	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(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(r);
+
+      default:
+	r = Z_STREAM_ERROR;
 
-        mode = TYPE;
-        bitk = 0;
-        bitb = 0;
-        read = write = 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(r);
+      }
+    }
+  }
+
+  void free(){
+    reset();
+    window=null;
+    hufts=null;
+    //ZFREE(z, s);
+  }
+
+  void set_dictionary(byte[] d, int start, int n){
+    System.arraycopy(d, start, window, 0, n);
+    read = write = n;
+  }
 
-        if (checkfn != null)
-            z.adler = check = z._adler.adler32(0L, null, 0, 0);
+  // Returns true if inflate is currently at the end of a block generated
+  // by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
+  int sync_point(){
+    return mode == LENS ? 1 : 0;
+  }
+
+  // copy as much as possible from the sliding window to the output area
+  int inflate_flush(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(check && n>0){
+      z.adler.update(window, q, n);
     }
 
-    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++] & 0xff) << k;
-
-                        k += 8;
-                    }
-
-                    t = (int)(b & 7);
-                    last = t & 1;
-
-                    switch (t >>> 1) {
-                        case 0:                         // stored
-                            {b >>>= (3); k -= (3);}
-
-                            t = k & 7;                    // go to byte boundary
-                            {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 >>>= (3); k -= (3);}
-
-                            mode = CODES;
-                            break;
-
-                        case 2:                         // dynamic
-                            {b >>>= (3); k -= (3);}
-
-                            mode = TABLE;
-                            break;
-
-                        case 3:                         // illegal
-                            {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++] & 0xff) << k;
-
-                        k += 8;
-                    }
+    // copy as far as end of window
+    System.arraycopy(window, q, z.next_out, p, n);
+    p += n;
+    q += n;
 
-                    if ((((~b) >>> 16) & 0xffff) != (b & 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 & 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.arraycopy(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++] & 0xff) << k;
-
-                        k += 8;
-                    }
-
-                    table = t = (b & 0x3fff);
-
-                    if ((t & 0x1f) > 29 || ((t >> 5) & 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 & 0x1f) + ((t >> 5) & 0x1f);
-
-                    if (blens == null || blens.length < t) {
-                        blens = new int[t];
-                    }
-                    else {
-                        for (int i = 0; i < t; i++) {blens[i] = 0;}
-                    }
-
-                    {b >>>= (14); k -= (14);}
-
-                    index = 0;
-                    mode = BTREE;
+    // see if more to copy at beginning of window
+    if (q == end){
+      // wrap pointers
+      q = 0;
+      if (write == end)
+        write = 0;
 
-                case BTREE:
-                    while (index < 4 + (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++] & 0xff) << k;
-
-                            k += 8;
-                        }
-
-                        blens[border[index++]] = b & 7;
-                        {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;
-
-                case DTREE:
-                    while (true) {
-                        t = table;
-
-                        if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
-                            break;
-                        }
+      // 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;
 
-                        int[] h;
-                        int i, j, 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++] & 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 >>>= (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++] & 0xff) << k;
-
-                                k += 8;
-                            }
+      // update counters
+      z.avail_out -= n;
+      z.total_out += n;
 
-                            b >>>= (t); k -= (t);
-                            j += (b & inflate_mask[i]);
-                            b >>>= (i); k -= (i);
-                            i = index;
-                            t = table;
-
-                            if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 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 & 0x1f),
-                                                          1 + ((t >> 5) & 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);
-                        }
+      // update check information
+      if(check && n>0){
+	z.adler.update(window, q, n);
+      }
 
-                        codes.init(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
-                    }
-                    mode = 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;
-
-                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;
-
-                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);
-            }
-        }
+      // copy
+      System.arraycopy(window, q, z.next_out, p, n);
+      p += n;
+      q += n;
     }
 
-    void free(ZStream z) {
-        reset(z, null);
-        window = null;
-        hufts = null;
-        //ZFREE(z, s);
-    }
-
-    void set_dictionary(byte[] d, int start, int n) {
-        System.arraycopy(d, start, window, 0, n);
-        read = write = n;
-    }
-
-    // Returns true if inflate is currently at the end of a block generated
-    // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
-    int sync_point() {
-        return mode == LENS ? 1 : 0;
-    }
-
-    // copy as much as possible from the sliding window to the output area
-    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.adler32(check, window, q, n);
+    // update pointers
+    z.next_out_index = p;
+    read = q;
 
-        // copy as far as end of window
-        System.arraycopy(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.adler32(check, window, q, n);
-
-            // copy
-            System.arraycopy(window, q, z.next_out, p, n);
-            p += n;
-            q += n;
-        }
-
-        // update pointers
-        z.next_out_index = p;
-        read = q;
-        // done
-        return r;
-    }
+    // done
+    return r;
+  }
 }