rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 694 emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java@0d277415ed02
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
jaroslav@694
     1
/* -*-mode:java; c-basic-offset:2; -*- */
jaroslav@694
     2
/*
jaroslav@694
     3
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
jaroslav@694
     4
jaroslav@694
     5
Redistribution and use in source and binary forms, with or without
jaroslav@694
     6
modification, are permitted provided that the following conditions are met:
jaroslav@694
     7
jaroslav@694
     8
  1. Redistributions of source code must retain the above copyright notice,
jaroslav@694
     9
     this list of conditions and the following disclaimer.
jaroslav@694
    10
jaroslav@694
    11
  2. Redistributions in binary form must reproduce the above copyright 
jaroslav@694
    12
     notice, this list of conditions and the following disclaimer in 
jaroslav@694
    13
     the documentation and/or other materials provided with the distribution.
jaroslav@694
    14
jaroslav@694
    15
  3. The names of the authors may not be used to endorse or promote products
jaroslav@694
    16
     derived from this software without specific prior written permission.
jaroslav@694
    17
jaroslav@694
    18
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
jaroslav@694
    19
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
jaroslav@694
    20
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
jaroslav@694
    21
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
jaroslav@694
    22
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
jaroslav@694
    23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
jaroslav@694
    24
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
jaroslav@694
    25
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
jaroslav@694
    26
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
jaroslav@694
    27
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
jaroslav@694
    28
 */
jaroslav@694
    29
/*
jaroslav@694
    30
 * This program is based on zlib-1.1.3, so all credit should go authors
jaroslav@694
    31
 * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
jaroslav@694
    32
 * and contributors of zlib.
jaroslav@694
    33
 */
jaroslav@694
    34
jaroslav@694
    35
package org.apidesign.bck2brwsr.emul.zip;
jaroslav@694
    36
jaroslav@694
    37
import org.apidesign.bck2brwsr.emul.lang.System;
jaroslav@694
    38
jaroslav@694
    39
final class InfBlocks{
jaroslav@694
    40
  static final private int MANY=1440;
jaroslav@694
    41
jaroslav@694
    42
  // And'ing with mask[n] masks the lower n bits
jaroslav@694
    43
  static final private int[] inflate_mask = {
jaroslav@694
    44
    0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
jaroslav@694
    45
    0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
jaroslav@694
    46
    0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
jaroslav@694
    47
    0x00007fff, 0x0000ffff
jaroslav@694
    48
  };
jaroslav@694
    49
jaroslav@694
    50
  // Table for deflate from PKZIP's appnote.txt.
jaroslav@694
    51
  static final int[] border = { // Order of the bit length code lengths
jaroslav@694
    52
    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
jaroslav@694
    53
  };
jaroslav@694
    54
jaroslav@694
    55
  static final private int Z_OK=0;
jaroslav@694
    56
  static final private int Z_STREAM_END=1;
jaroslav@694
    57
  static final private int Z_NEED_DICT=2;
jaroslav@694
    58
  static final private int Z_ERRNO=-1;
jaroslav@694
    59
  static final private int Z_STREAM_ERROR=-2;
jaroslav@694
    60
  static final private int Z_DATA_ERROR=-3;
jaroslav@694
    61
  static final private int Z_MEM_ERROR=-4;
jaroslav@694
    62
  static final private int Z_BUF_ERROR=-5;
jaroslav@694
    63
  static final private int Z_VERSION_ERROR=-6;
jaroslav@694
    64
jaroslav@694
    65
  static final private int TYPE=0;  // get type bits (3, including end bit)
jaroslav@694
    66
  static final private int LENS=1;  // get lengths for stored
jaroslav@694
    67
  static final private int STORED=2;// processing stored block
jaroslav@694
    68
  static final private int TABLE=3; // get table lengths
jaroslav@694
    69
  static final private int BTREE=4; // get bit lengths tree for a dynamic block
jaroslav@694
    70
  static final private int DTREE=5; // get length, distance trees for a dynamic block
jaroslav@694
    71
  static final private int CODES=6; // processing fixed or dynamic block
jaroslav@694
    72
  static final private int DRY=7;   // output remaining window bytes
jaroslav@694
    73
  static final private int DONE=8;  // finished last block, done
jaroslav@694
    74
  static final private int BAD=9;   // ot a data error--stuck here
jaroslav@694
    75
jaroslav@694
    76
  int mode;            // current inflate_block mode 
jaroslav@694
    77
jaroslav@694
    78
  int left;            // if STORED, bytes left to copy 
jaroslav@694
    79
jaroslav@694
    80
  int table;           // table lengths (14 bits) 
jaroslav@694
    81
  int index;           // index into blens (or border) 
jaroslav@694
    82
  int[] blens;         // bit lengths of codes 
jaroslav@694
    83
  int[] bb=new int[1]; // bit length tree depth 
jaroslav@694
    84
  int[] tb=new int[1]; // bit length decoding tree 
jaroslav@694
    85
jaroslav@694
    86
  int[] bl=new int[1];
jaroslav@694
    87
  int[] bd=new int[1];
jaroslav@694
    88
jaroslav@694
    89
  int[][] tl=new int[1][];
jaroslav@694
    90
  int[][] td=new int[1][];
jaroslav@694
    91
  int[] tli=new int[1]; // tl_index
jaroslav@694
    92
  int[] tdi=new int[1]; // td_index
jaroslav@694
    93
jaroslav@694
    94
  private final InfCodes codes;      // if CODES, current state 
jaroslav@694
    95
jaroslav@694
    96
  int last;            // true if this block is the last block 
jaroslav@694
    97
jaroslav@694
    98
  // mode independent information 
jaroslav@694
    99
  int bitk;            // bits in bit buffer 
jaroslav@694
   100
  int bitb;            // bit buffer 
jaroslav@694
   101
  int[] hufts;         // single malloc for tree space 
jaroslav@694
   102
  byte[] window;       // sliding window 
jaroslav@694
   103
  int end;             // one byte after sliding window 
jaroslav@694
   104
  int read;            // window read pointer 
jaroslav@694
   105
  int write;           // window write pointer 
jaroslav@694
   106
  private boolean check;
jaroslav@694
   107
jaroslav@694
   108
  private final InfTree inftree=new InfTree();
jaroslav@694
   109
jaroslav@694
   110
  private final ZStream z; 
jaroslav@694
   111
jaroslav@694
   112
  InfBlocks(ZStream z, int w){
jaroslav@694
   113
    this.z=z;
jaroslav@694
   114
    this.codes=new InfCodes(this.z, this);
jaroslav@694
   115
    hufts=new int[MANY*3];
jaroslav@694
   116
    window=new byte[w];
jaroslav@694
   117
    end=w;
jaroslav@694
   118
    this.check = (z.istate.wrap==0) ? false : true;
jaroslav@694
   119
    mode = TYPE;
jaroslav@694
   120
    reset();
jaroslav@694
   121
  }
jaroslav@694
   122
jaroslav@694
   123
  void reset(){
jaroslav@694
   124
    if(mode==BTREE || mode==DTREE){
jaroslav@694
   125
    }
jaroslav@694
   126
    if(mode==CODES){
jaroslav@694
   127
      codes.free(z);
jaroslav@694
   128
    }
jaroslav@694
   129
    mode=TYPE;
jaroslav@694
   130
    bitk=0;
jaroslav@694
   131
    bitb=0;
jaroslav@694
   132
    read=write=0;
jaroslav@694
   133
    if(check){
jaroslav@694
   134
      z.adler.reset();
jaroslav@694
   135
    }
jaroslav@694
   136
  }
jaroslav@694
   137
jaroslav@694
   138
  int proc(int r){
jaroslav@694
   139
    int t;              // temporary storage
jaroslav@694
   140
    int b;              // bit buffer
jaroslav@694
   141
    int k;              // bits in bit buffer
jaroslav@694
   142
    int p;              // input data pointer
jaroslav@694
   143
    int n;              // bytes available there
jaroslav@694
   144
    int q;              // output window write pointer
jaroslav@694
   145
    int m;              // bytes to end of window or read pointer
jaroslav@694
   146
jaroslav@694
   147
    // copy input/output information to locals (UPDATE macro restores)
jaroslav@694
   148
    {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;}
jaroslav@694
   149
    {q=write;m=(int)(q<read?read-q-1:end-q);}
jaroslav@694
   150
jaroslav@694
   151
    // process input based on current state
jaroslav@694
   152
    while(true){
jaroslav@694
   153
      switch (mode){
jaroslav@694
   154
      case TYPE:
jaroslav@694
   155
jaroslav@694
   156
	while(k<(3)){
jaroslav@694
   157
	  if(n!=0){
jaroslav@694
   158
	    r=Z_OK;
jaroslav@694
   159
	  }
jaroslav@694
   160
	  else{
jaroslav@694
   161
	    bitb=b; bitk=k; 
jaroslav@694
   162
	    z.avail_in=n;
jaroslav@694
   163
	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   164
	    write=q;
jaroslav@694
   165
	    return inflate_flush(r);
jaroslav@694
   166
	  };
jaroslav@694
   167
	  n--;
jaroslav@694
   168
	  b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   169
	  k+=8;
jaroslav@694
   170
	}
jaroslav@694
   171
	t = (int)(b & 7);
jaroslav@694
   172
	last = t & 1;
jaroslav@694
   173
jaroslav@694
   174
	switch (t >>> 1){
jaroslav@694
   175
        case 0:                         // stored 
jaroslav@694
   176
          {b>>>=(3);k-=(3);}
jaroslav@694
   177
          t = k & 7;                    // go to byte boundary
jaroslav@694
   178
jaroslav@694
   179
          {b>>>=(t);k-=(t);}
jaroslav@694
   180
          mode = LENS;                  // get length of stored block
jaroslav@694
   181
          break;
jaroslav@694
   182
        case 1:                         // fixed
jaroslav@694
   183
          InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
jaroslav@694
   184
          codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
jaroslav@694
   185
jaroslav@694
   186
          {b>>>=(3);k-=(3);}
jaroslav@694
   187
jaroslav@694
   188
          mode = CODES;
jaroslav@694
   189
          break;
jaroslav@694
   190
        case 2:                         // dynamic
jaroslav@694
   191
jaroslav@694
   192
          {b>>>=(3);k-=(3);}
jaroslav@694
   193
jaroslav@694
   194
          mode = TABLE;
jaroslav@694
   195
          break;
jaroslav@694
   196
        case 3:                         // illegal
jaroslav@694
   197
jaroslav@694
   198
          {b>>>=(3);k-=(3);}
jaroslav@694
   199
          mode = BAD;
jaroslav@694
   200
          z.msg = "invalid block type";
jaroslav@694
   201
          r = Z_DATA_ERROR;
jaroslav@694
   202
jaroslav@694
   203
	  bitb=b; bitk=k; 
jaroslav@694
   204
	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   205
	  write=q;
jaroslav@694
   206
	  return inflate_flush(r);
jaroslav@694
   207
	}
jaroslav@694
   208
	break;
jaroslav@694
   209
      case LENS:
jaroslav@694
   210
jaroslav@694
   211
	while(k<(32)){
jaroslav@694
   212
	  if(n!=0){
jaroslav@694
   213
	    r=Z_OK;
jaroslav@694
   214
	  }
jaroslav@694
   215
	  else{
jaroslav@694
   216
	    bitb=b; bitk=k; 
jaroslav@694
   217
	    z.avail_in=n;
jaroslav@694
   218
	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   219
	    write=q;
jaroslav@694
   220
	    return inflate_flush(r);
jaroslav@694
   221
	  };
jaroslav@694
   222
	  n--;
jaroslav@694
   223
	  b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   224
	  k+=8;
jaroslav@694
   225
	}
jaroslav@694
   226
jaroslav@694
   227
	if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)){
jaroslav@694
   228
	  mode = BAD;
jaroslav@694
   229
	  z.msg = "invalid stored block lengths";
jaroslav@694
   230
	  r = Z_DATA_ERROR;
jaroslav@694
   231
jaroslav@694
   232
	  bitb=b; bitk=k; 
jaroslav@694
   233
	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   234
	  write=q;
jaroslav@694
   235
	  return inflate_flush(r);
jaroslav@694
   236
	}
jaroslav@694
   237
	left = (b & 0xffff);
jaroslav@694
   238
	b = k = 0;                       // dump bits
jaroslav@694
   239
	mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE);
jaroslav@694
   240
	break;
jaroslav@694
   241
      case STORED:
jaroslav@694
   242
	if (n == 0){
jaroslav@694
   243
	  bitb=b; bitk=k; 
jaroslav@694
   244
	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   245
	  write=q;
jaroslav@694
   246
	  return inflate_flush(r);
jaroslav@694
   247
	}
jaroslav@694
   248
jaroslav@694
   249
	if(m==0){
jaroslav@694
   250
	  if(q==end&&read!=0){
jaroslav@694
   251
	    q=0; m=(int)(q<read?read-q-1:end-q);
jaroslav@694
   252
	  }
jaroslav@694
   253
	  if(m==0){
jaroslav@694
   254
	    write=q; 
jaroslav@694
   255
	    r=inflate_flush(r);
jaroslav@694
   256
	    q=write;m=(int)(q<read?read-q-1:end-q);
jaroslav@694
   257
	    if(q==end&&read!=0){
jaroslav@694
   258
	      q=0; m=(int)(q<read?read-q-1:end-q);
jaroslav@694
   259
	    }
jaroslav@694
   260
	    if(m==0){
jaroslav@694
   261
	      bitb=b; bitk=k; 
jaroslav@694
   262
	      z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   263
	      write=q;
jaroslav@694
   264
	      return inflate_flush(r);
jaroslav@694
   265
	    }
jaroslav@694
   266
	  }
jaroslav@694
   267
	}
jaroslav@694
   268
	r=Z_OK;
jaroslav@694
   269
jaroslav@694
   270
	t = left;
jaroslav@694
   271
	if(t>n) t = n;
jaroslav@694
   272
	if(t>m) t = m;
jaroslav@694
   273
	System.arraycopy(z.next_in, p, window, q, t);
jaroslav@694
   274
	p += t;  n -= t;
jaroslav@694
   275
	q += t;  m -= t;
jaroslav@694
   276
	if ((left -= t) != 0)
jaroslav@694
   277
	  break;
jaroslav@694
   278
	mode = last!=0 ? DRY : TYPE;
jaroslav@694
   279
	break;
jaroslav@694
   280
      case TABLE:
jaroslav@694
   281
jaroslav@694
   282
	while(k<(14)){
jaroslav@694
   283
	  if(n!=0){
jaroslav@694
   284
	    r=Z_OK;
jaroslav@694
   285
	  }
jaroslav@694
   286
	  else{
jaroslav@694
   287
	    bitb=b; bitk=k; 
jaroslav@694
   288
	    z.avail_in=n;
jaroslav@694
   289
	    z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   290
	    write=q;
jaroslav@694
   291
	    return inflate_flush(r);
jaroslav@694
   292
	  };
jaroslav@694
   293
	  n--;
jaroslav@694
   294
	  b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   295
	  k+=8;
jaroslav@694
   296
	}
jaroslav@694
   297
jaroslav@694
   298
	table = t = (b & 0x3fff);
jaroslav@694
   299
	if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
jaroslav@694
   300
	  {
jaroslav@694
   301
	    mode = BAD;
jaroslav@694
   302
	    z.msg = "too many length or distance symbols";
jaroslav@694
   303
	    r = Z_DATA_ERROR;
jaroslav@694
   304
jaroslav@694
   305
	    bitb=b; bitk=k; 
jaroslav@694
   306
	    z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   307
	    write=q;
jaroslav@694
   308
	    return inflate_flush(r);
jaroslav@694
   309
	  }
jaroslav@694
   310
	t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
jaroslav@694
   311
	if(blens==null || blens.length<t){
jaroslav@694
   312
	  blens=new int[t];
jaroslav@694
   313
	}
jaroslav@694
   314
	else{
jaroslav@694
   315
	  for(int i=0; i<t; i++){blens[i]=0;}
jaroslav@694
   316
	}
jaroslav@694
   317
jaroslav@694
   318
	{b>>>=(14);k-=(14);}
jaroslav@694
   319
jaroslav@694
   320
	index = 0;
jaroslav@694
   321
	mode = BTREE;
jaroslav@694
   322
      case BTREE:
jaroslav@694
   323
	while (index < 4 + (table >>> 10)){
jaroslav@694
   324
	  while(k<(3)){
jaroslav@694
   325
	    if(n!=0){
jaroslav@694
   326
	      r=Z_OK;
jaroslav@694
   327
	    }
jaroslav@694
   328
	    else{
jaroslav@694
   329
	      bitb=b; bitk=k; 
jaroslav@694
   330
	      z.avail_in=n;
jaroslav@694
   331
	      z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   332
	      write=q;
jaroslav@694
   333
	      return inflate_flush(r);
jaroslav@694
   334
	    };
jaroslav@694
   335
	    n--;
jaroslav@694
   336
	    b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   337
	    k+=8;
jaroslav@694
   338
	  }
jaroslav@694
   339
jaroslav@694
   340
	  blens[border[index++]] = b&7;
jaroslav@694
   341
jaroslav@694
   342
	  {b>>>=(3);k-=(3);}
jaroslav@694
   343
	}
jaroslav@694
   344
jaroslav@694
   345
	while(index < 19){
jaroslav@694
   346
	  blens[border[index++]] = 0;
jaroslav@694
   347
	}
jaroslav@694
   348
jaroslav@694
   349
	bb[0] = 7;
jaroslav@694
   350
	t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
jaroslav@694
   351
	if (t != Z_OK){
jaroslav@694
   352
	  r = t;
jaroslav@694
   353
	  if (r == Z_DATA_ERROR){
jaroslav@694
   354
	    blens=null;
jaroslav@694
   355
	    mode = BAD;
jaroslav@694
   356
	  }
jaroslav@694
   357
jaroslav@694
   358
	  bitb=b; bitk=k; 
jaroslav@694
   359
	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   360
	  write=q;
jaroslav@694
   361
	  return inflate_flush(r);
jaroslav@694
   362
	}
jaroslav@694
   363
jaroslav@694
   364
	index = 0;
jaroslav@694
   365
	mode = DTREE;
jaroslav@694
   366
      case DTREE:
jaroslav@694
   367
	while (true){
jaroslav@694
   368
	  t = table;
jaroslav@694
   369
	  if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){
jaroslav@694
   370
	    break;
jaroslav@694
   371
	  }
jaroslav@694
   372
jaroslav@694
   373
	  int[] h;
jaroslav@694
   374
	  int i, j, c;
jaroslav@694
   375
jaroslav@694
   376
	  t = bb[0];
jaroslav@694
   377
jaroslav@694
   378
	  while(k<(t)){
jaroslav@694
   379
	    if(n!=0){
jaroslav@694
   380
	      r=Z_OK;
jaroslav@694
   381
	    }
jaroslav@694
   382
	    else{
jaroslav@694
   383
	      bitb=b; bitk=k; 
jaroslav@694
   384
	      z.avail_in=n;
jaroslav@694
   385
	      z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   386
	      write=q;
jaroslav@694
   387
	      return inflate_flush(r);
jaroslav@694
   388
	    };
jaroslav@694
   389
	    n--;
jaroslav@694
   390
	    b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   391
	    k+=8;
jaroslav@694
   392
	  }
jaroslav@694
   393
jaroslav@694
   394
	  if(tb[0]==-1){
jaroslav@694
   395
            //System.err.println("null...");
jaroslav@694
   396
	  }
jaroslav@694
   397
jaroslav@694
   398
	  t=hufts[(tb[0]+(b&inflate_mask[t]))*3+1];
jaroslav@694
   399
	  c=hufts[(tb[0]+(b&inflate_mask[t]))*3+2];
jaroslav@694
   400
jaroslav@694
   401
	  if (c < 16){
jaroslav@694
   402
	    b>>>=(t);k-=(t);
jaroslav@694
   403
	    blens[index++] = c;
jaroslav@694
   404
	  }
jaroslav@694
   405
	  else { // c == 16..18
jaroslav@694
   406
	    i = c == 18 ? 7 : c - 14;
jaroslav@694
   407
	    j = c == 18 ? 11 : 3;
jaroslav@694
   408
jaroslav@694
   409
	    while(k<(t+i)){
jaroslav@694
   410
	      if(n!=0){
jaroslav@694
   411
		r=Z_OK;
jaroslav@694
   412
	      }
jaroslav@694
   413
	      else{
jaroslav@694
   414
		bitb=b; bitk=k; 
jaroslav@694
   415
		z.avail_in=n;
jaroslav@694
   416
		z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   417
		write=q;
jaroslav@694
   418
		return inflate_flush(r);
jaroslav@694
   419
	      };
jaroslav@694
   420
	      n--;
jaroslav@694
   421
	      b|=(z.next_in[p++]&0xff)<<k;
jaroslav@694
   422
	      k+=8;
jaroslav@694
   423
	    }
jaroslav@694
   424
jaroslav@694
   425
	    b>>>=(t);k-=(t);
jaroslav@694
   426
jaroslav@694
   427
	    j += (b & inflate_mask[i]);
jaroslav@694
   428
jaroslav@694
   429
	    b>>>=(i);k-=(i);
jaroslav@694
   430
jaroslav@694
   431
	    i = index;
jaroslav@694
   432
	    t = table;
jaroslav@694
   433
	    if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
jaroslav@694
   434
		(c == 16 && i < 1)){
jaroslav@694
   435
	      blens=null;
jaroslav@694
   436
	      mode = BAD;
jaroslav@694
   437
	      z.msg = "invalid bit length repeat";
jaroslav@694
   438
	      r = Z_DATA_ERROR;
jaroslav@694
   439
jaroslav@694
   440
	      bitb=b; bitk=k; 
jaroslav@694
   441
	      z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   442
	      write=q;
jaroslav@694
   443
	      return inflate_flush(r);
jaroslav@694
   444
	    }
jaroslav@694
   445
jaroslav@694
   446
	    c = c == 16 ? blens[i-1] : 0;
jaroslav@694
   447
	    do{
jaroslav@694
   448
	      blens[i++] = c;
jaroslav@694
   449
	    }
jaroslav@694
   450
	    while (--j!=0);
jaroslav@694
   451
	    index = i;
jaroslav@694
   452
	  }
jaroslav@694
   453
	}
jaroslav@694
   454
jaroslav@694
   455
	tb[0]=-1;
jaroslav@694
   456
	{
jaroslav@694
   457
	  bl[0] = 9;         // must be <= 9 for lookahead assumptions
jaroslav@694
   458
	  bd[0] = 6;         // must be <= 9 for lookahead assumptions
jaroslav@694
   459
	  t = table;
jaroslav@694
   460
	  t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 
jaroslav@694
   461
					    1 + ((t >> 5) & 0x1f),
jaroslav@694
   462
					    blens, bl, bd, tli, tdi, hufts, z);
jaroslav@694
   463
jaroslav@694
   464
	  if (t != Z_OK){
jaroslav@694
   465
	    if (t == Z_DATA_ERROR){
jaroslav@694
   466
	      blens=null;
jaroslav@694
   467
	      mode = BAD;
jaroslav@694
   468
	    }
jaroslav@694
   469
	    r = t;
jaroslav@694
   470
jaroslav@694
   471
	    bitb=b; bitk=k; 
jaroslav@694
   472
	    z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   473
	    write=q;
jaroslav@694
   474
	    return inflate_flush(r);
jaroslav@694
   475
	  }
jaroslav@694
   476
	  codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]);
jaroslav@694
   477
	}
jaroslav@694
   478
	mode = CODES;
jaroslav@694
   479
      case CODES:
jaroslav@694
   480
	bitb=b; bitk=k;
jaroslav@694
   481
	z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   482
	write=q;
jaroslav@694
   483
jaroslav@694
   484
	if ((r = codes.proc(r)) != Z_STREAM_END){
jaroslav@694
   485
	  return inflate_flush(r);
jaroslav@694
   486
	}
jaroslav@694
   487
	r = Z_OK;
jaroslav@694
   488
	codes.free(z);
jaroslav@694
   489
jaroslav@694
   490
	p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk;
jaroslav@694
   491
	q=write;m=(int)(q<read?read-q-1:end-q);
jaroslav@694
   492
jaroslav@694
   493
	if (last==0){
jaroslav@694
   494
	  mode = TYPE;
jaroslav@694
   495
	  break;
jaroslav@694
   496
	}
jaroslav@694
   497
	mode = DRY;
jaroslav@694
   498
      case DRY:
jaroslav@694
   499
	write=q; 
jaroslav@694
   500
	r=inflate_flush(r); 
jaroslav@694
   501
	q=write; m=(int)(q<read?read-q-1:end-q);
jaroslav@694
   502
	if (read != write){
jaroslav@694
   503
	  bitb=b; bitk=k; 
jaroslav@694
   504
	  z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   505
	  write=q;
jaroslav@694
   506
	  return inflate_flush(r);
jaroslav@694
   507
	}
jaroslav@694
   508
	mode = DONE;
jaroslav@694
   509
      case DONE:
jaroslav@694
   510
	r = Z_STREAM_END;
jaroslav@694
   511
jaroslav@694
   512
	bitb=b; bitk=k; 
jaroslav@694
   513
	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   514
	write=q;
jaroslav@694
   515
	return inflate_flush(r);
jaroslav@694
   516
      case BAD:
jaroslav@694
   517
	r = Z_DATA_ERROR;
jaroslav@694
   518
jaroslav@694
   519
	bitb=b; bitk=k; 
jaroslav@694
   520
	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   521
	write=q;
jaroslav@694
   522
	return inflate_flush(r);
jaroslav@694
   523
jaroslav@694
   524
      default:
jaroslav@694
   525
	r = Z_STREAM_ERROR;
jaroslav@694
   526
jaroslav@694
   527
	bitb=b; bitk=k; 
jaroslav@694
   528
	z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
jaroslav@694
   529
	write=q;
jaroslav@694
   530
	return inflate_flush(r);
jaroslav@694
   531
      }
jaroslav@694
   532
    }
jaroslav@694
   533
  }
jaroslav@694
   534
jaroslav@694
   535
  void free(){
jaroslav@694
   536
    reset();
jaroslav@694
   537
    window=null;
jaroslav@694
   538
    hufts=null;
jaroslav@694
   539
    //ZFREE(z, s);
jaroslav@694
   540
  }
jaroslav@694
   541
jaroslav@694
   542
  void set_dictionary(byte[] d, int start, int n){
jaroslav@694
   543
    System.arraycopy(d, start, window, 0, n);
jaroslav@694
   544
    read = write = n;
jaroslav@694
   545
  }
jaroslav@694
   546
jaroslav@694
   547
  // Returns true if inflate is currently at the end of a block generated
jaroslav@694
   548
  // by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
jaroslav@694
   549
  int sync_point(){
jaroslav@694
   550
    return mode == LENS ? 1 : 0;
jaroslav@694
   551
  }
jaroslav@694
   552
jaroslav@694
   553
  // copy as much as possible from the sliding window to the output area
jaroslav@694
   554
  int inflate_flush(int r){
jaroslav@694
   555
    int n;
jaroslav@694
   556
    int p;
jaroslav@694
   557
    int q;
jaroslav@694
   558
jaroslav@694
   559
    // local copies of source and destination pointers
jaroslav@694
   560
    p = z.next_out_index;
jaroslav@694
   561
    q = read;
jaroslav@694
   562
jaroslav@694
   563
    // compute number of bytes to copy as far as end of window
jaroslav@694
   564
    n = (int)((q <= write ? write : end) - q);
jaroslav@694
   565
    if(n > z.avail_out) n = z.avail_out;
jaroslav@694
   566
    if(n!=0 && r == Z_BUF_ERROR) r = Z_OK;
jaroslav@694
   567
jaroslav@694
   568
    // update counters
jaroslav@694
   569
    z.avail_out -= n;
jaroslav@694
   570
    z.total_out += n;
jaroslav@694
   571
jaroslav@694
   572
    // update check information
jaroslav@694
   573
    if(check && n>0){
jaroslav@694
   574
      z.adler.update(window, q, n);
jaroslav@694
   575
    }
jaroslav@694
   576
jaroslav@694
   577
    // copy as far as end of window
jaroslav@694
   578
    System.arraycopy(window, q, z.next_out, p, n);
jaroslav@694
   579
    p += n;
jaroslav@694
   580
    q += n;
jaroslav@694
   581
jaroslav@694
   582
    // see if more to copy at beginning of window
jaroslav@694
   583
    if (q == end){
jaroslav@694
   584
      // wrap pointers
jaroslav@694
   585
      q = 0;
jaroslav@694
   586
      if (write == end)
jaroslav@694
   587
        write = 0;
jaroslav@694
   588
jaroslav@694
   589
      // compute bytes to copy
jaroslav@694
   590
      n = write - q;
jaroslav@694
   591
      if (n > z.avail_out) n = z.avail_out;
jaroslav@694
   592
      if (n!=0 && r == Z_BUF_ERROR) r = Z_OK;
jaroslav@694
   593
jaroslav@694
   594
      // update counters
jaroslav@694
   595
      z.avail_out -= n;
jaroslav@694
   596
      z.total_out += n;
jaroslav@694
   597
jaroslav@694
   598
      // update check information
jaroslav@694
   599
      if(check && n>0){
jaroslav@694
   600
	z.adler.update(window, q, n);
jaroslav@694
   601
      }
jaroslav@694
   602
jaroslav@694
   603
      // copy
jaroslav@694
   604
      System.arraycopy(window, q, z.next_out, p, n);
jaroslav@694
   605
      p += n;
jaroslav@694
   606
      q += n;
jaroslav@694
   607
    }
jaroslav@694
   608
jaroslav@694
   609
    // update pointers
jaroslav@694
   610
    z.next_out_index = p;
jaroslav@694
   611
    read = q;
jaroslav@694
   612
jaroslav@694
   613
    // done
jaroslav@694
   614
    return r;
jaroslav@694
   615
  }
jaroslav@694
   616
}