]> Joshua Wise's Git repositories - dumload.git/blob - src/com/jcraft/jzlib/InfCodes.java
Initial commit.
[dumload.git] / src / com / jcraft / jzlib / InfCodes.java
1 /* -*-mode:java; c-basic-offset:2; -*- */
2 /*
3 Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
11   2. Redistributions in binary form must reproduce the above copyright 
12      notice, this list of conditions and the following disclaimer in 
13      the documentation and/or other materials provided with the distribution.
14
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*
30  * This program is based on zlib-1.1.3, so all credit should go authors
31  * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
32  * and contributors of zlib.
33  */
34
35 package com.jcraft.jzlib;
36
37 final class InfCodes{
38
39   static final private int[] inflate_mask = {
40     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
41     0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
42     0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
43     0x00007fff, 0x0000ffff
44   };
45
46   static final private int Z_OK=0;
47   static final private int Z_STREAM_END=1;
48   static final private int Z_NEED_DICT=2;
49   static final private int Z_ERRNO=-1;
50   static final private int Z_STREAM_ERROR=-2;
51   static final private int Z_DATA_ERROR=-3;
52   static final private int Z_MEM_ERROR=-4;
53   static final private int Z_BUF_ERROR=-5;
54   static final private int Z_VERSION_ERROR=-6;
55
56   // waiting for "i:"=input,
57   //             "o:"=output,
58   //             "x:"=nothing
59   static final private int START=0;  // x: set up for LEN
60   static final private int LEN=1;    // i: get length/literal/eob next
61   static final private int LENEXT=2; // i: getting length extra (have base)
62   static final private int DIST=3;   // i: get distance next
63   static final private int DISTEXT=4;// i: getting distance extra
64   static final private int COPY=5;   // o: copying bytes in window, waiting for space
65   static final private int LIT=6;    // o: got literal, waiting for output space
66   static final private int WASH=7;   // o: got eob, possibly still output waiting
67   static final private int END=8;    // x: got eob and all data flushed
68   static final private int BADCODE=9;// x: got error
69
70   int mode;      // current inflate_codes mode
71
72   // mode dependent information
73   int len;
74
75   int[] tree; // pointer into tree
76   int tree_index=0;
77   int need;   // bits needed
78
79   int lit;
80
81   // if EXT or COPY, where and how much
82   int get;              // bits to get for extra
83   int dist;             // distance back to copy from
84
85   byte lbits;           // ltree bits decoded per branch
86   byte dbits;           // dtree bits decoder per branch
87   int[] ltree;          // literal/length/eob tree
88   int ltree_index;      // literal/length/eob tree
89   int[] dtree;          // distance tree
90   int dtree_index;      // distance tree
91
92   InfCodes(){
93   }
94   void init(int bl, int bd,
95            int[] tl, int tl_index,
96            int[] td, int td_index, ZStream z){
97     mode=START;
98     lbits=(byte)bl;
99     dbits=(byte)bd;
100     ltree=tl;
101     ltree_index=tl_index;
102     dtree = td;
103     dtree_index=td_index;
104     tree=null;
105   }
106
107   int proc(InfBlocks s, ZStream z, int r){ 
108     int j;              // temporary storage
109     int[] t;            // temporary pointer
110     int tindex;         // temporary pointer
111     int e;              // extra bits or operation
112     int b=0;            // bit buffer
113     int k=0;            // bits in bit buffer
114     int p=0;            // input data pointer
115     int n;              // bytes available there
116     int q;              // output window write pointer
117     int m;              // bytes to end of window or read pointer
118     int f;              // pointer to copy strings from
119
120     // copy input/output information to locals (UPDATE macro restores)
121     p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
122     q=s.write;m=q<s.read?s.read-q-1:s.end-q;
123
124     // process input and output based on current state
125     while (true){
126       switch (mode){
127         // waiting for "i:"=input, "o:"=output, "x:"=nothing
128       case START:         // x: set up for LEN
129         if (m >= 258 && n >= 10){
130
131           s.bitb=b;s.bitk=k;
132           z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
133           s.write=q;
134           r = inflate_fast(lbits, dbits, 
135                            ltree, ltree_index, 
136                            dtree, dtree_index,
137                            s, z);
138
139           p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
140           q=s.write;m=q<s.read?s.read-q-1:s.end-q;
141
142           if (r != Z_OK){
143             mode = r == Z_STREAM_END ? WASH : BADCODE;
144             break;
145           }
146         }
147         need = lbits;
148         tree = ltree;
149         tree_index=ltree_index;
150
151         mode = LEN;
152       case LEN:           // i: get length/literal/eob next
153         j = need;
154
155         while(k<(j)){
156           if(n!=0)r=Z_OK;
157           else{
158
159             s.bitb=b;s.bitk=k;
160             z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
161             s.write=q;
162             return s.inflate_flush(z,r);
163           }
164           n--;
165           b|=(z.next_in[p++]&0xff)<<k;
166           k+=8;
167         }
168
169         tindex=(tree_index+(b&inflate_mask[j]))*3;
170
171         b>>>=(tree[tindex+1]);
172         k-=(tree[tindex+1]);
173
174         e=tree[tindex];
175
176         if(e == 0){               // literal
177           lit = tree[tindex+2];
178           mode = LIT;
179           break;
180         }
181         if((e & 16)!=0 ){          // length
182           get = e & 15;
183           len = tree[tindex+2];
184           mode = LENEXT;
185           break;
186         }
187         if ((e & 64) == 0){        // next table
188           need = e;
189           tree_index = tindex/3+tree[tindex+2];
190           break;
191         }
192         if ((e & 32)!=0){               // end of block
193           mode = WASH;
194           break;
195         }
196         mode = BADCODE;        // invalid code
197         z.msg = "invalid literal/length code";
198         r = Z_DATA_ERROR;
199
200         s.bitb=b;s.bitk=k;
201         z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
202         s.write=q;
203         return s.inflate_flush(z,r);
204
205       case LENEXT:        // i: getting length extra (have base)
206         j = get;
207
208         while(k<(j)){
209           if(n!=0)r=Z_OK;
210           else{
211
212             s.bitb=b;s.bitk=k;
213             z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
214             s.write=q;
215             return s.inflate_flush(z,r);
216           }
217           n--; b|=(z.next_in[p++]&0xff)<<k;
218           k+=8;
219         }
220
221         len += (b & inflate_mask[j]);
222
223         b>>=j;
224         k-=j;
225
226         need = dbits;
227         tree = dtree;
228         tree_index=dtree_index;
229         mode = DIST;
230       case DIST:          // i: get distance next
231         j = need;
232
233         while(k<(j)){
234           if(n!=0)r=Z_OK;
235           else{
236
237             s.bitb=b;s.bitk=k;
238             z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
239             s.write=q;
240             return s.inflate_flush(z,r);
241           }
242           n--; b|=(z.next_in[p++]&0xff)<<k;
243           k+=8;
244         }
245
246         tindex=(tree_index+(b & inflate_mask[j]))*3;
247
248         b>>=tree[tindex+1];
249         k-=tree[tindex+1];
250
251         e = (tree[tindex]);
252         if((e & 16)!=0){               // distance
253           get = e & 15;
254           dist = tree[tindex+2];
255           mode = DISTEXT;
256           break;
257         }
258         if ((e & 64) == 0){        // next table
259           need = e;
260           tree_index = tindex/3 + tree[tindex+2];
261           break;
262         }
263         mode = BADCODE;        // invalid code
264         z.msg = "invalid distance code";
265         r = Z_DATA_ERROR;
266
267         s.bitb=b;s.bitk=k;
268         z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
269         s.write=q;
270         return s.inflate_flush(z,r);
271
272       case DISTEXT:       // i: getting distance extra
273         j = get;
274
275         while(k<(j)){
276           if(n!=0)r=Z_OK;
277           else{
278
279             s.bitb=b;s.bitk=k;
280             z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
281             s.write=q;
282             return s.inflate_flush(z,r);
283           }
284           n--; b|=(z.next_in[p++]&0xff)<<k;
285           k+=8;
286         }
287
288         dist += (b & inflate_mask[j]);
289
290         b>>=j;
291         k-=j;
292
293         mode = COPY;
294       case COPY:          // o: copying bytes in window, waiting for space
295         f = q - dist;
296         while(f < 0){     // modulo window size-"while" instead
297           f += s.end;     // of "if" handles invalid distances
298         }
299         while (len!=0){
300
301           if(m==0){
302             if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
303             if(m==0){
304               s.write=q; r=s.inflate_flush(z,r);
305               q=s.write;m=q<s.read?s.read-q-1:s.end-q;
306
307               if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
308
309               if(m==0){
310                 s.bitb=b;s.bitk=k;
311                 z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
312                 s.write=q;
313                 return s.inflate_flush(z,r);
314               }  
315             }
316           }
317
318           s.window[q++]=s.window[f++]; m--;
319
320           if (f == s.end)
321             f = 0;
322           len--;
323         }
324         mode = START;
325         break;
326       case LIT:           // o: got literal, waiting for output space
327         if(m==0){
328           if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
329           if(m==0){
330             s.write=q; r=s.inflate_flush(z,r);
331             q=s.write;m=q<s.read?s.read-q-1:s.end-q;
332
333             if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
334             if(m==0){
335               s.bitb=b;s.bitk=k;
336               z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
337               s.write=q;
338               return s.inflate_flush(z,r);
339             }
340           }
341         }
342         r=Z_OK;
343
344         s.window[q++]=(byte)lit; m--;
345
346         mode = START;
347         break;
348       case WASH:           // o: got eob, possibly more output
349         if (k > 7){        // return unused byte, if any
350           k -= 8;
351           n++;
352           p--;             // can always return one
353         }
354
355         s.write=q; r=s.inflate_flush(z,r);
356         q=s.write;m=q<s.read?s.read-q-1:s.end-q;
357
358         if (s.read != s.write){
359           s.bitb=b;s.bitk=k;
360           z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
361           s.write=q;
362           return s.inflate_flush(z,r);
363         }
364         mode = END;
365       case END:
366         r = Z_STREAM_END;
367         s.bitb=b;s.bitk=k;
368         z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
369         s.write=q;
370         return s.inflate_flush(z,r);
371
372       case BADCODE:       // x: got error
373
374         r = Z_DATA_ERROR;
375
376         s.bitb=b;s.bitk=k;
377         z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
378         s.write=q;
379         return s.inflate_flush(z,r);
380
381       default:
382         r = Z_STREAM_ERROR;
383
384         s.bitb=b;s.bitk=k;
385         z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
386         s.write=q;
387         return s.inflate_flush(z,r);
388       }
389     }
390   }
391
392   void free(ZStream z){
393     //  ZFREE(z, c);
394   }
395
396   // Called with number of bytes left to write in window at least 258
397   // (the maximum string length) and number of input bytes available
398   // at least ten.  The ten bytes are six bytes for the longest length/
399   // distance pair plus four bytes for overloading the bit buffer.
400
401   int inflate_fast(int bl, int bd, 
402                    int[] tl, int tl_index,
403                    int[] td, int td_index,
404                    InfBlocks s, ZStream z){
405     int t;                // temporary pointer
406     int[] tp;             // temporary pointer
407     int tp_index;         // temporary pointer
408     int e;                // extra bits or operation
409     int b;                // bit buffer
410     int k;                // bits in bit buffer
411     int p;                // input data pointer
412     int n;                // bytes available there
413     int q;                // output window write pointer
414     int m;                // bytes to end of window or read pointer
415     int ml;               // mask for literal/length tree
416     int md;               // mask for distance tree
417     int c;                // bytes to copy
418     int d;                // distance back to copy from
419     int r;                // copy source pointer
420
421     int tp_index_t_3;     // (tp_index+t)*3
422
423     // load input, output, bit values
424     p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
425     q=s.write;m=q<s.read?s.read-q-1:s.end-q;
426
427     // initialize masks
428     ml = inflate_mask[bl];
429     md = inflate_mask[bd];
430
431     // do until not enough input or output space for fast loop
432     do {                          // assume called with m >= 258 && n >= 10
433       // get literal/length code
434       while(k<(20)){              // max bits for literal/length code
435         n--;
436         b|=(z.next_in[p++]&0xff)<<k;k+=8;
437       }
438
439       t= b&ml;
440       tp=tl; 
441       tp_index=tl_index;
442       tp_index_t_3=(tp_index+t)*3;
443       if ((e = tp[tp_index_t_3]) == 0){
444         b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
445
446         s.window[q++] = (byte)tp[tp_index_t_3+2];
447         m--;
448         continue;
449       }
450       do {
451
452         b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
453
454         if((e&16)!=0){
455           e &= 15;
456           c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]);
457
458           b>>=e; k-=e;
459
460           // decode distance base of block to copy
461           while(k<(15)){           // max bits for distance code
462             n--;
463             b|=(z.next_in[p++]&0xff)<<k;k+=8;
464           }
465
466           t= b&md;
467           tp=td;
468           tp_index=td_index;
469           tp_index_t_3=(tp_index+t)*3;
470           e = tp[tp_index_t_3];
471
472           do {
473
474             b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
475
476             if((e&16)!=0){
477               // get extra bits to add to distance base
478               e &= 15;
479               while(k<(e)){         // get extra bits (up to 13)
480                 n--;
481                 b|=(z.next_in[p++]&0xff)<<k;k+=8;
482               }
483
484               d = tp[tp_index_t_3+2] + (b&inflate_mask[e]);
485
486               b>>=(e); k-=(e);
487
488               // do the copy
489               m -= c;
490               if (q >= d){                // offset before dest
491                 //  just copy
492                 r=q-d;
493                 if(q-r>0 && 2>(q-r)){           
494                   s.window[q++]=s.window[r++]; // minimum count is three,
495                   s.window[q++]=s.window[r++]; // so unroll loop a little
496                   c-=2;
497                 }
498                 else{
499                   System.arraycopy(s.window, r, s.window, q, 2);
500                   q+=2; r+=2; c-=2;
501                 }
502               }
503               else{                  // else offset after destination
504                 r=q-d;
505                 do{
506                   r+=s.end;          // force pointer in window
507                 }while(r<0);         // covers invalid distances
508                 e=s.end-r;
509                 if(c>e){             // if source crosses,
510                   c-=e;              // wrapped copy
511                   if(q-r>0 && e>(q-r)){           
512                     do{s.window[q++] = s.window[r++];}
513                     while(--e!=0);
514                   }
515                   else{
516                     System.arraycopy(s.window, r, s.window, q, e);
517                     q+=e; r+=e; e=0;
518                   }
519                   r = 0;                  // copy rest from start of window
520                 }
521
522               }
523
524               // copy all or what's left
525               if(q-r>0 && c>(q-r)){           
526                 do{s.window[q++] = s.window[r++];}
527                 while(--c!=0);
528               }
529               else{
530                 System.arraycopy(s.window, r, s.window, q, c);
531                 q+=c; r+=c; c=0;
532               }
533               break;
534             }
535             else if((e&64)==0){
536               t+=tp[tp_index_t_3+2];
537               t+=(b&inflate_mask[e]);
538               tp_index_t_3=(tp_index+t)*3;
539               e=tp[tp_index_t_3];
540             }
541             else{
542               z.msg = "invalid distance code";
543
544               c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
545
546               s.bitb=b;s.bitk=k;
547               z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
548               s.write=q;
549
550               return Z_DATA_ERROR;
551             }
552           }
553           while(true);
554           break;
555         }
556
557         if((e&64)==0){
558           t+=tp[tp_index_t_3+2];
559           t+=(b&inflate_mask[e]);
560           tp_index_t_3=(tp_index+t)*3;
561           if((e=tp[tp_index_t_3])==0){
562
563             b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
564
565             s.window[q++]=(byte)tp[tp_index_t_3+2];
566             m--;
567             break;
568           }
569         }
570         else if((e&32)!=0){
571
572           c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
573  
574           s.bitb=b;s.bitk=k;
575           z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
576           s.write=q;
577
578           return Z_STREAM_END;
579         }
580         else{
581           z.msg="invalid literal/length code";
582
583           c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
584
585           s.bitb=b;s.bitk=k;
586           z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
587           s.write=q;
588
589           return Z_DATA_ERROR;
590         }
591       } 
592       while(true);
593     } 
594     while(m>=258 && n>= 10);
595
596     // not enough input or output--restore pointers and return
597     c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
598
599     s.bitb=b;s.bitk=k;
600     z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
601     s.write=q;
602
603     return Z_OK;
604   }
605 }
This page took 0.053161 seconds and 4 git commands to generate.