Path: blob/main/src/lwjgl/java/com/jcraft/jzlib/InfBlocks.java
8650 views
/* -*-mode:java; c-basic-offset:2; -*- */1/*2Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.34Redistribution and use in source and binary forms, with or without5modification, are permitted provided that the following conditions are met:671. Redistributions of source code must retain the above copyright notice,8this list of conditions and the following disclaimer.9102. Redistributions in binary form must reproduce the above copyright11notice, this list of conditions and the following disclaimer in12the documentation and/or other materials provided with the distribution.13143. The names of the authors may not be used to endorse or promote products15derived from this software without specific prior written permission.1617THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,18INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND19FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,20INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,21INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT22LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,23OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF24LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING25NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,26EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27*/28/*29* This program is based on zlib-1.1.3, so all credit should go authors30* Jean-loup Gailly([email protected]) and Mark Adler([email protected])31* and contributors of zlib.32*/3334package com.jcraft.jzlib;3536final class InfBlocks{37static final private int MANY=1440;3839// And'ing with mask[n] masks the lower n bits40static final private int[] inflate_mask = {410x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,420x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,430x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,440x00007fff, 0x0000ffff45};4647// Table for deflate from PKZIP's appnote.txt.48static final int[] border = { // Order of the bit length code lengths4916, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 1550};5152static final private int Z_OK=0;53static final private int Z_STREAM_END=1;54static final private int Z_NEED_DICT=2;55static final private int Z_ERRNO=-1;56static final private int Z_STREAM_ERROR=-2;57static final private int Z_DATA_ERROR=-3;58static final private int Z_MEM_ERROR=-4;59static final private int Z_BUF_ERROR=-5;60static final private int Z_VERSION_ERROR=-6;6162static final private int TYPE=0; // get type bits (3, including end bit)63static final private int LENS=1; // get lengths for stored64static final private int STORED=2;// processing stored block65static final private int TABLE=3; // get table lengths66static final private int BTREE=4; // get bit lengths tree for a dynamic block67static final private int DTREE=5; // get length, distance trees for a dynamic block68static final private int CODES=6; // processing fixed or dynamic block69static final private int DRY=7; // output remaining window bytes70static final private int DONE=8; // finished last block, done71static final private int BAD=9; // ot a data error--stuck here7273int mode; // current inflate_block mode7475int left; // if STORED, bytes left to copy7677int table; // table lengths (14 bits)78int index; // index into blens (or border)79int[] blens; // bit lengths of codes80int[] bb=new int[1]; // bit length tree depth81int[] tb=new int[1]; // bit length decoding tree8283int[] bl=new int[1];84int[] bd=new int[1];8586int[][] tl=new int[1][];87int[][] td=new int[1][];88int[] tli=new int[1]; // tl_index89int[] tdi=new int[1]; // td_index9091private final InfCodes codes; // if CODES, current state9293int last; // true if this block is the last block9495// mode independent information96int bitk; // bits in bit buffer97int bitb; // bit buffer98int[] hufts; // single malloc for tree space99byte[] window; // sliding window100int end; // one byte after sliding window101int read; // window read pointer102int write; // window write pointer103private boolean check;104105private final InfTree inftree=new InfTree();106107private final ZStream z;108109InfBlocks(ZStream z, int w){110this.z=z;111this.codes=new InfCodes(this.z, this);112hufts=new int[MANY*3];113window=new byte[w];114end=w;115this.check = (z.istate.wrap==0) ? false : true;116mode = TYPE;117reset();118}119120void reset(){121if(mode==BTREE || mode==DTREE){122}123if(mode==CODES){124codes.free(z);125}126mode=TYPE;127bitk=0;128bitb=0;129read=write=0;130if(check){131z.adler.reset();132}133}134135int proc(int r){136int t; // temporary storage137int b; // bit buffer138int k; // bits in bit buffer139int p; // input data pointer140int n; // bytes available there141int q; // output window write pointer142int m; // bytes to end of window or read pointer143144// copy input/output information to locals (UPDATE macro restores)145{p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;}146{q=write;m=(int)(q<read?read-q-1:end-q);}147148// process input based on current state149while(true){150switch (mode){151case TYPE:152153while(k<(3)){154if(n!=0){155r=Z_OK;156}157else{158bitb=b; bitk=k;159z.avail_in=n;160z.total_in+=p-z.next_in_index;z.next_in_index=p;161write=q;162return inflate_flush(r);163};164n--;165b|=(z.next_in[p++]&0xff)<<k;166k+=8;167}168t = (int)(b & 7);169last = t & 1;170171switch (t >>> 1){172case 0: // stored173{b>>>=(3);k-=(3);}174t = k & 7; // go to byte boundary175176{b>>>=(t);k-=(t);}177mode = LENS; // get length of stored block178break;179case 1: // fixed180InfTree.inflate_trees_fixed(bl, bd, tl, td, z);181codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);182183{b>>>=(3);k-=(3);}184185mode = CODES;186break;187case 2: // dynamic188189{b>>>=(3);k-=(3);}190191mode = TABLE;192break;193case 3: // illegal194195{b>>>=(3);k-=(3);}196mode = BAD;197z.msg = "invalid block type";198r = Z_DATA_ERROR;199200bitb=b; bitk=k;201z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;202write=q;203return inflate_flush(r);204}205break;206case LENS:207208while(k<(32)){209if(n!=0){210r=Z_OK;211}212else{213bitb=b; bitk=k;214z.avail_in=n;215z.total_in+=p-z.next_in_index;z.next_in_index=p;216write=q;217return inflate_flush(r);218};219n--;220b|=(z.next_in[p++]&0xff)<<k;221k+=8;222}223224if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)){225mode = BAD;226z.msg = "invalid stored block lengths";227r = Z_DATA_ERROR;228229bitb=b; bitk=k;230z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;231write=q;232return inflate_flush(r);233}234left = (b & 0xffff);235b = k = 0; // dump bits236mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE);237break;238case STORED:239if (n == 0){240bitb=b; bitk=k;241z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;242write=q;243return inflate_flush(r);244}245246if(m==0){247if(q==end&&read!=0){248q=0; m=(int)(q<read?read-q-1:end-q);249}250if(m==0){251write=q;252r=inflate_flush(r);253q=write;m=(int)(q<read?read-q-1:end-q);254if(q==end&&read!=0){255q=0; m=(int)(q<read?read-q-1:end-q);256}257if(m==0){258bitb=b; bitk=k;259z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;260write=q;261return inflate_flush(r);262}263}264}265r=Z_OK;266267t = left;268if(t>n) t = n;269if(t>m) t = m;270System.arraycopy(z.next_in, p, window, q, t);271p += t; n -= t;272q += t; m -= t;273if ((left -= t) != 0)274break;275mode = last!=0 ? DRY : TYPE;276break;277case TABLE:278279while(k<(14)){280if(n!=0){281r=Z_OK;282}283else{284bitb=b; bitk=k;285z.avail_in=n;286z.total_in+=p-z.next_in_index;z.next_in_index=p;287write=q;288return inflate_flush(r);289};290n--;291b|=(z.next_in[p++]&0xff)<<k;292k+=8;293}294295table = t = (b & 0x3fff);296if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)297{298mode = BAD;299z.msg = "too many length or distance symbols";300r = Z_DATA_ERROR;301302bitb=b; bitk=k;303z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;304write=q;305return inflate_flush(r);306}307t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);308if(blens==null || blens.length<t){309blens=new int[t];310}311else{312for(int i=0; i<t; i++){blens[i]=0;}313}314315{b>>>=(14);k-=(14);}316317index = 0;318mode = BTREE;319case BTREE:320while (index < 4 + (table >>> 10)){321while(k<(3)){322if(n!=0){323r=Z_OK;324}325else{326bitb=b; bitk=k;327z.avail_in=n;328z.total_in+=p-z.next_in_index;z.next_in_index=p;329write=q;330return inflate_flush(r);331};332n--;333b|=(z.next_in[p++]&0xff)<<k;334k+=8;335}336337blens[border[index++]] = b&7;338339{b>>>=(3);k-=(3);}340}341342while(index < 19){343blens[border[index++]] = 0;344}345346bb[0] = 7;347t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);348if (t != Z_OK){349r = t;350if (r == Z_DATA_ERROR){351blens=null;352mode = BAD;353}354355bitb=b; bitk=k;356z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;357write=q;358return inflate_flush(r);359}360361index = 0;362mode = DTREE;363case DTREE:364while (true){365t = table;366if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){367break;368}369370int[] h;371int i, j, c;372373t = bb[0];374375while(k<(t)){376if(n!=0){377r=Z_OK;378}379else{380bitb=b; bitk=k;381z.avail_in=n;382z.total_in+=p-z.next_in_index;z.next_in_index=p;383write=q;384return inflate_flush(r);385};386n--;387b|=(z.next_in[p++]&0xff)<<k;388k+=8;389}390391if(tb[0]==-1){392//System.err.println("null...");393}394395t=hufts[(tb[0]+(b&inflate_mask[t]))*3+1];396c=hufts[(tb[0]+(b&inflate_mask[t]))*3+2];397398if (c < 16){399b>>>=(t);k-=(t);400blens[index++] = c;401}402else { // c == 16..18403i = c == 18 ? 7 : c - 14;404j = c == 18 ? 11 : 3;405406while(k<(t+i)){407if(n!=0){408r=Z_OK;409}410else{411bitb=b; bitk=k;412z.avail_in=n;413z.total_in+=p-z.next_in_index;z.next_in_index=p;414write=q;415return inflate_flush(r);416};417n--;418b|=(z.next_in[p++]&0xff)<<k;419k+=8;420}421422b>>>=(t);k-=(t);423424j += (b & inflate_mask[i]);425426b>>>=(i);k-=(i);427428i = index;429t = table;430if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||431(c == 16 && i < 1)){432blens=null;433mode = BAD;434z.msg = "invalid bit length repeat";435r = Z_DATA_ERROR;436437bitb=b; bitk=k;438z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;439write=q;440return inflate_flush(r);441}442443c = c == 16 ? blens[i-1] : 0;444do{445blens[i++] = c;446}447while (--j!=0);448index = i;449}450}451452tb[0]=-1;453{454bl[0] = 9; // must be <= 9 for lookahead assumptions455bd[0] = 6; // must be <= 9 for lookahead assumptions456t = table;457t = inftree.inflate_trees_dynamic(257 + (t & 0x1f),4581 + ((t >> 5) & 0x1f),459blens, bl, bd, tli, tdi, hufts, z);460461if (t != Z_OK){462if (t == Z_DATA_ERROR){463blens=null;464mode = BAD;465}466r = t;467468bitb=b; bitk=k;469z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;470write=q;471return inflate_flush(r);472}473codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]);474}475mode = CODES;476case CODES:477bitb=b; bitk=k;478z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p;479write=q;480481if ((r = codes.proc(r)) != Z_STREAM_END){482return inflate_flush(r);483}484r = Z_OK;485codes.free(z);486487p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk;488q=write;m=(int)(q<read?read-q-1:end-q);489490if (last==0){491mode = TYPE;492break;493}494mode = DRY;495case DRY:496write=q;497r=inflate_flush(r);498q=write; m=(int)(q<read?read-q-1:end-q);499if (read != write){500bitb=b; bitk=k;501z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;502write=q;503return inflate_flush(r);504}505mode = DONE;506case DONE:507r = Z_STREAM_END;508509bitb=b; bitk=k;510z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;511write=q;512return inflate_flush(r);513case BAD:514r = Z_DATA_ERROR;515516bitb=b; bitk=k;517z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;518write=q;519return inflate_flush(r);520521default:522r = Z_STREAM_ERROR;523524bitb=b; bitk=k;525z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;526write=q;527return inflate_flush(r);528}529}530}531532void free(){533reset();534window=null;535hufts=null;536//ZFREE(z, s);537}538539void set_dictionary(byte[] d, int start, int n){540System.arraycopy(d, start, window, 0, n);541read = write = n;542}543544// Returns true if inflate is currently at the end of a block generated545// by Z_SYNC_FLUSH or Z_FULL_FLUSH.546int sync_point(){547return mode == LENS ? 1 : 0;548}549550// copy as much as possible from the sliding window to the output area551int inflate_flush(int r){552int n;553int p;554int q;555556// local copies of source and destination pointers557p = z.next_out_index;558q = read;559560// compute number of bytes to copy as far as end of window561n = (int)((q <= write ? write : end) - q);562if(n > z.avail_out) n = z.avail_out;563if(n!=0 && r == Z_BUF_ERROR) r = Z_OK;564565// update counters566z.avail_out -= n;567z.total_out += n;568569// update check information570if(check && n>0){571z.adler.update(window, q, n);572}573574// copy as far as end of window575System.arraycopy(window, q, z.next_out, p, n);576p += n;577q += n;578579// see if more to copy at beginning of window580if (q == end){581// wrap pointers582q = 0;583if (write == end)584write = 0;585586// compute bytes to copy587n = write - q;588if (n > z.avail_out) n = z.avail_out;589if (n!=0 && r == Z_BUF_ERROR) r = Z_OK;590591// update counters592z.avail_out -= n;593z.total_out += n;594595// update check information596if(check && n>0){597z.adler.update(window, q, n);598}599600// copy601System.arraycopy(window, q, z.next_out, p, n);602p += n;603q += n;604}605606// update pointers607z.next_out_index = p;608read = q;609610// done611return r;612}613}614615616