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;
  }
Exemple #2
0
  int inflateReset() {
    if (z == null) return Z_STREAM_ERROR;

    z.total_in = z.total_out = 0;
    z.msg = null;
    this.mode = HEAD;
    this.need_bytes = -1;
    this.blocks.reset();
    return Z_OK;
  }
 public void end() {
   if (z == null) return;
   if (compress) {
     z.deflateEnd();
   } else {
     z.inflateEnd();
   }
   z.free();
   z = null;
 }
Exemple #4
0
 public void init(int type, int level) {
   if (type == DEFLATER) {
     stream.deflateInit(level);
     this.type = DEFLATER;
   } else if (type == INFLATER) {
     stream.inflateInit();
     inflated_buf = new byte[BUF_SIZE];
     this.type = INFLATER;
   }
 }
Exemple #5
0
  int inflateSync() {
    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, w; // temporaries to save total_in and total_out

    // set up
    if (z == null) return Z_STREAM_ERROR;
    if (this.mode != BAD) {
      this.mode = BAD;
      this.marker = 0;
    }
    if ((n = z.avail_in) == 0) return Z_BUF_ERROR;

    p = z.next_in_index;
    m = this.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;
    this.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.total_in = r;
    z.total_out = w;
    this.mode = BLOCKS;

    return Z_OK;
  }
Exemple #6
0
  int inflateInit(int w) {
    z.msg = null;
    blocks = null;

    // handle undocumented wrap option (no zlib header or check)
    wrap = 0;
    if (w < 0) {
      w = -w;
    } else {
      wrap = (w >> 4) + 1;
      if (w < 48) w &= 15;
    }

    if (w < 8 || w > 15) {
      inflateEnd();
      return Z_STREAM_ERROR;
    }
    if (blocks != null && wbits != w) {
      blocks.free();
      blocks = null;
    }

    // set window size
    wbits = w;

    this.blocks = new InfBlocks(z, 1 << w);

    // reset state
    inflateReset();

    return Z_OK;
  }
Exemple #7
0
  int inflate_trees_dynamic(
      int nl, // number of literal/length codes
      int nd, // number of distance codes
      int[] c, // that many (total) code lengths
      int[] bl, // literal desired/actual bit depth
      int[] bd, // distance desired/actual bit depth
      int[] tl, // literal/length tree result
      int[] td, // distance tree result
      int[] hp, // space for trees
      ZStream z // 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;
  }
Exemple #8
0
  public byte[] compress(byte[] buf, int start, int[] len) {
    stream.next_in = buf;
    stream.next_in_index = start;
    stream.avail_in = len[0] - start;
    int status;
    int outputlen = start;
    byte[] outputbuf = buf;
    int tmp = 0;

    do {
      stream.next_out = tmpbuf;
      stream.next_out_index = 0;
      stream.avail_out = BUF_SIZE;
      status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
      switch (status) {
        case JZlib.Z_OK:
          tmp = BUF_SIZE - stream.avail_out;
          if (outputbuf.length < outputlen + tmp + buffer_margin) {
            byte[] foo = new byte[(outputlen + tmp + buffer_margin) * 2];
            System.arraycopy(outputbuf, 0, foo, 0, outputbuf.length);
            outputbuf = foo;
          }
          System.arraycopy(tmpbuf, 0, outputbuf, outputlen, tmp);
          outputlen += tmp;
          break;
        default:
          System.err.println("compress: deflate returnd " + status);
      }
    } while (stream.avail_out == 0);

    len[0] = outputlen;
    return outputbuf;
  }
 public void finish() throws IOException {
   int err;
   do {
     z.next_out = buf;
     z.next_out_index = 0;
     z.avail_out = bufsize;
     if (compress) {
       err = z.deflate(JZlib.Z_FINISH);
     } else {
       err = z.inflate(JZlib.Z_FINISH);
     }
     if (err != JZlib.Z_STREAM_END && err != JZlib.Z_OK)
       throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg);
     if (bufsize - z.avail_out > 0) {
       out.write(buf, 0, bufsize - z.avail_out);
     }
   } while (z.avail_in > 0 || z.avail_out == 0);
   flush();
 }
  // 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 = ((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);

    // 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;
  }
Exemple #11
0
  int inflate_trees_bits(
      int[] c, // 19 code lengths
      int[] bb, // bits tree desired/actual depth
      int[] tb, // bits tree result
      int[] hp, // space for trees
      ZStream z // 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;
  }
Exemple #12
0
  void reset(ZStream z, long[] c) {
    if (c != null) {
      c[0] = check;
    }
    mode = TYPE;
    bitk = 0;
    bitb = 0;
    read = write = 0;

    if (checkfn != null) {
      z.adler = check = Adler32.adler32(0L, null, 0, 0);
    }
  }
  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.adler32(0L, null, 0, 0);
  }
 @Override
 public void write(byte b[], int off, int len) throws IOException {
   if (len == 0) return;
   int err;
   z.next_in = b;
   z.next_in_index = off;
   z.avail_in = len;
   do {
     z.next_out = buf;
     z.next_out_index = 0;
     z.avail_out = bufsize;
     if (compress) err = z.deflate(flush);
     else err = z.inflate(flush);
     if (err != JZlib.Z_OK)
       throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg);
     out.write(buf, 0, bufsize - z.avail_out);
   } while (z.avail_in > 0 || z.avail_out == 0);
 }
  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.adler32(1L, dictionary, 0, dictLength) != z.adler) {
      return Z_DATA_ERROR;
    }

    z.adler = z._adler.adler32(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;
  }
Exemple #16
0
  public byte[] uncompress(byte[] buffer, int start, int[] length) {
    int inflated_end = 0;

    stream.next_in = buffer;
    stream.next_in_index = start;
    stream.avail_in = length[0];

    while (true) {
      stream.next_out = tmpbuf;
      stream.next_out_index = 0;
      stream.avail_out = BUF_SIZE;
      int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
      switch (status) {
        case JZlib.Z_OK:
          if (inflated_buf.length < inflated_end + BUF_SIZE - stream.avail_out) {
            int len = inflated_buf.length * 2;
            if (len < inflated_end + BUF_SIZE - stream.avail_out)
              len = inflated_end + BUF_SIZE - stream.avail_out;
            byte[] foo = new byte[len];
            System.arraycopy(inflated_buf, 0, foo, 0, inflated_end);
            inflated_buf = foo;
          }
          System.arraycopy(tmpbuf, 0, inflated_buf, inflated_end, BUF_SIZE - stream.avail_out);
          inflated_end += (BUF_SIZE - stream.avail_out);
          length[0] = inflated_end;
          break;
        case JZlib.Z_BUF_ERROR:
          if (inflated_end > buffer.length - start) {
            byte[] foo = new byte[inflated_end + start];
            System.arraycopy(buffer, 0, foo, 0, start);
            System.arraycopy(inflated_buf, 0, foo, start, inflated_end);
            buffer = foo;
          } else {
            System.arraycopy(inflated_buf, 0, buffer, start, inflated_end);
          }
          length[0] = inflated_end;
          return buffer;
        default:
          System.err.println("uncompress: inflate returnd " + status);
          return null;
      }
    }
  }
  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;
  }
Exemple #18
0
  public int compress(byte[] buf, int start, int len) {
    stream.next_in = buf;
    stream.next_in_index = start;
    stream.avail_in = len - start;
    int status;
    int outputlen = start;

    do {
      stream.next_out = tmpbuf;
      stream.next_out_index = 0;
      stream.avail_out = BUF_SIZE;
      status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
      switch (status) {
        case JZlib.Z_OK:
          System.arraycopy(tmpbuf, 0, buf, outputlen, BUF_SIZE - stream.avail_out);
          outputlen += (BUF_SIZE - stream.avail_out);
          break;
        default:
          System.err.println("compress: deflate returnd " + status);
      }
    } while (stream.avail_out == 0);
    return outputlen;
  }
  int inflate(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) {
      // System.out.println("mode: "+z.istate.mode);
      switch (z.istate.mode) {
        case METHOD:
          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++]) & 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;
        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++]) & 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;
        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++] & 0xff) << 24) & 0xff000000L;
          z.istate.mode = 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++] & 0xff) << 16) & 0xff0000L;
          z.istate.mode = 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++] & 0xff) << 8) & 0xff00L;
          z.istate.mode = 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++] & 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;
        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++] & 0xff) << 24) & 0xff000000L;
          z.istate.mode = 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++] & 0xff) << 16) & 0xff0000L;
          z.istate.mode = 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++] & 0xff) << 8) & 0xff00L;
          z.istate.mode = 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++] & 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;
        case DONE:
          return Z_STREAM_END;
        case BAD:
          return Z_DATA_ERROR;
        default:
          return Z_STREAM_ERROR;
      }
    }
  }
  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 = (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 = (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;
          }

          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 = (q < read ? read - q - 1 : end - q);
            }
            if (m == 0) {
              write = q;
              r = inflate_flush(z, r);
              q = write;
              m = (q < read ? read - q - 1 : end - q);
              if (q == end && read != 0) {
                q = 0;
                m = (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;
        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;
            }

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

              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);
            }
            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 = (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 = (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);
      }
    }
  }
 public ZOutputStream(OutputStream out) {
   super();
   this.out = out;
   z.inflateInit();
   compress = false;
 }
 public ZOutputStream(OutputStream out, int level, boolean nowrap) {
   super();
   this.out = out;
   z.deflateInit(level, nowrap);
   compress = true;
 }
Exemple #23
0
  int proc(InfBlocks s, ZStream z, int r) {
    int j; // temporary storage
    @SuppressWarnings("unused")
    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) {
          // waiting for "i:"=input, "o:"=output, "x:"=nothing
        case 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 != Z_OK) {
              mode = r == Z_STREAM_END ? WASH : BADCODE;
              break;
            }
          }
          need = lbits;
          tree = ltree;
          tree_index = ltree_index;

          mode = 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++] & 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 = 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++] & 0xff) << k;
            k += 8;
          }

          len += (b & inflate_mask[j]);

          b >>= j;
          k -= j;

          need = dbits;
          tree = dtree;
          tree_index = dtree_index;
          mode = 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++] & 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++] & 0xff) << k;
            k += 8;
          }

          dist += (b & inflate_mask[j]);

          b >>= j;
          k -= j;

          mode = 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++] = (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;
        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);
      }
    }
  }
Exemple #24
0
  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 until not enough input or output space for fast loop
    do { // 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++] & 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 & 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++] & 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++] & 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.arraycopy(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; // force pointer in window
                } while (r < 0); // 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.arraycopy(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.arraycopy(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++] = (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;
  }
Exemple #25
0
  int inflate(int f) {
    int hold = 0;

    int r;
    int b;

    if (z == null || z.next_in == null) {
      if (f == Z_FINISH && this.mode == HEAD) return Z_OK;
      return Z_STREAM_ERROR;
    }

    f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
    r = Z_BUF_ERROR;
    while (true) {

      switch (this.mode) {
        case HEAD:
          if (wrap == 0) {
            this.mode = BLOCKS;
            break;
          }

          try {
            r = readBytes(2, r, f);
          } catch (Return e) {
            return e.r;
          }

          if ((wrap & 2) != 0 && this.need == 0x8b1fL) { // gzip header
            z.adler = new CRC32();
            checksum(2, this.need);

            if (gheader == null) gheader = new GZIPHeader();

            this.mode = FLAGS;
            break;
          }

          flags = 0;

          this.method = ((int) this.need) & 0xff;
          b = ((int) (this.need >> 8)) & 0xff;

          if ((wrap & 1) == 0
              || // check if zlib header allowed
              (((this.method << 8) + b) % 31) != 0) {
            this.mode = BAD;
            z.msg = "incorrect header check";
            // since zlib 1.2, it is allowted to inflateSync for this
            // case.
            /*
             * this.marker = 5; // can't try inflateSync
             */
            break;
          }

          if ((this.method & 0xf) != Z_DEFLATED) {
            this.mode = BAD;
            z.msg = "unknown compression method";
            // since zlib 1.2, it is allowted to inflateSync for this
            // case.
            /*
             * this.marker = 5; // can't try inflateSync
             */
            break;
          }

          if ((this.method >> 4) + 8 > this.wbits) {
            this.mode = BAD;
            z.msg = "invalid window size";
            // since zlib 1.2, it is allowted to inflateSync for this
            // case.
            /*
             * this.marker = 5; // can't try inflateSync
             */
            break;
          }

          z.adler = new Adler32();

          if ((b & PRESET_DICT) == 0) {
            this.mode = BLOCKS;
            break;
          }
          this.mode = DICT4;
        case DICT4:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
          this.mode = DICT3;
        case DICT3:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
          this.mode = DICT2;
        case DICT2:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
          this.mode = DICT1;
        case DICT1:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += (z.next_in[z.next_in_index++] & 0xffL);
          z.adler.reset(this.need);
          this.mode = DICT0;
          return Z_NEED_DICT;
        case DICT0:
          this.mode = BAD;
          z.msg = "need dictionary";
          this.marker = 0; // can try inflateSync
          return Z_STREAM_ERROR;
        case BLOCKS:
          r = this.blocks.proc(r);
          if (r == Z_DATA_ERROR) {
            this.mode = BAD;
            this.marker = 0; // can try inflateSync
            break;
          }
          if (r == Z_OK) {
            r = f;
          }
          if (r != Z_STREAM_END) {
            return r;
          }
          r = f;
          this.was = z.adler.getValue();
          this.blocks.reset();
          if (this.wrap == 0) {
            this.mode = DONE;
            break;
          }
          this.mode = CHECK4;
        case CHECK4:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
          this.mode = CHECK3;
        case CHECK3:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
          this.mode = CHECK2;
        case CHECK2:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
          this.mode = CHECK1;
        case CHECK1:
          if (z.avail_in == 0) return r;
          r = f;

          z.avail_in--;
          z.total_in++;
          this.need += (z.next_in[z.next_in_index++] & 0xffL);

          if (flags != 0) { // gzip
            this.need =
                ((this.need & 0xff000000) >> 24
                        | (this.need & 0x00ff0000) >> 8
                        | (this.need & 0x0000ff00) << 8
                        | (this.need & 0x0000ffff) << 24)
                    & 0xffffffffL;
          }

          if (((int) (this.was)) != ((int) (this.need))) {
            z.msg = "incorrect data check";
            // chack is delayed
            /*
             * this.mode = BAD; this.marker = 5; // can't try
             * inflateSync break;
             */
          } else if (flags != 0 && gheader != null) {
            gheader.crc = this.need;
          }

          this.mode = LENGTH;
        case LENGTH:
          if (wrap != 0 && flags != 0) {

            try {
              r = readBytes(4, r, f);
            } catch (Return e) {
              return e.r;
            }

            if (z.msg != null && z.msg.equals("incorrect data check")) {
              this.mode = BAD;
              this.marker = 5; // can't try inflateSync
              break;
            }

            if (this.need != (z.total_out & 0xffffffffL)) {
              z.msg = "incorrect length check";
              this.mode = BAD;
              break;
            }
            z.msg = null;
          } else {
            if (z.msg != null && z.msg.equals("incorrect data check")) {
              this.mode = BAD;
              this.marker = 5; // can't try inflateSync
              break;
            }
          }

          this.mode = DONE;
        case DONE:
          return Z_STREAM_END;
        case BAD:
          return Z_DATA_ERROR;

        case FLAGS:
          try {
            r = readBytes(2, r, f);
          } catch (Return e) {
            return e.r;
          }

          flags = ((int) this.need) & 0xffff;

          if ((flags & 0xff) != Z_DEFLATED) {
            z.msg = "unknown compression method";
            this.mode = BAD;
            break;
          }
          if ((flags & 0xe000) != 0) {
            z.msg = "unknown header flags set";
            this.mode = BAD;
            break;
          }

          if ((flags & 0x0200) != 0) {
            checksum(2, this.need);
          }

          this.mode = TIME;

        case TIME:
          try {
            r = readBytes(4, r, f);
          } catch (Return e) {
            return e.r;
          }
          if (gheader != null) gheader.time = this.need;
          if ((flags & 0x0200) != 0) {
            checksum(4, this.need);
          }
          this.mode = OS;
        case OS:
          try {
            r = readBytes(2, r, f);
          } catch (Return e) {
            return e.r;
          }
          if (gheader != null) {
            gheader.xflags = ((int) this.need) & 0xff;
            gheader.os = (((int) this.need) >> 8) & 0xff;
          }
          if ((flags & 0x0200) != 0) {
            checksum(2, this.need);
          }
          this.mode = EXLEN;
        case EXLEN:
          if ((flags & 0x0400) != 0) {
            try {
              r = readBytes(2, r, f);
            } catch (Return e) {
              return e.r;
            }
            if (gheader != null) {
              gheader.extra = new byte[((int) this.need) & 0xffff];
            }
            if ((flags & 0x0200) != 0) {
              checksum(2, this.need);
            }
          } else if (gheader != null) {
            gheader.extra = null;
          }
          this.mode = EXTRA;

        case EXTRA:
          if ((flags & 0x0400) != 0) {
            try {
              r = readBytes(r, f);
              if (gheader != null) {
                byte[] foo = tmp_string.toByteArray();
                tmp_string = null;
                if (foo.length == gheader.extra.length) {
                  System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
                } else {
                  z.msg = "bad extra field length";
                  this.mode = BAD;
                  break;
                }
              }
            } catch (Return e) {
              return e.r;
            }
          } else if (gheader != null) {
            gheader.extra = null;
          }
          this.mode = NAME;
        case NAME:
          if ((flags & 0x0800) != 0) {
            try {
              r = readString(r, f);
              if (gheader != null) {
                gheader.name = tmp_string.toByteArray();
              }
              tmp_string = null;
            } catch (Return e) {
              return e.r;
            }
          } else if (gheader != null) {
            gheader.name = null;
          }
          this.mode = COMMENT;
        case COMMENT:
          if ((flags & 0x1000) != 0) {
            try {
              r = readString(r, f);
              if (gheader != null) {
                gheader.comment = tmp_string.toByteArray();
              }
              tmp_string = null;
            } catch (Return e) {
              return e.r;
            }
          } else if (gheader != null) {
            gheader.comment = null;
          }
          this.mode = HCRC;
        case HCRC:
          if ((flags & 0x0200) != 0) {
            try {
              r = readBytes(2, r, f);
            } catch (Return e) {
              return e.r;
            }
            if (gheader != null) {
              gheader.hcrc = (int) (this.need & 0xffff);
            }
            if (this.need != (z.adler.getValue() & 0xffffL)) {
              this.mode = BAD;
              z.msg = "header crc mismatch";
              this.marker = 5; // can't try inflateSync
              break;
            }
          }
          z.adler = new CRC32();

          this.mode = BLOCKS;
          break;
        default:
          return Z_STREAM_ERROR;
      }
    }
  }