Exemple #1
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 #2
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;
  }
  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 #4
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;
  }
Exemple #5
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;
  }
  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 #7
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 #8
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);
      }
    }
  }
  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);
      }
    }
  }
Exemple #10
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;
      }
    }
  }
  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;
      }
    }
  }