Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lDEVinux
GitHub Repository: lDEVinux/eaglercraft
Path: blob/main/src/lwjgl/java/com/jcraft/jzlib/Inflate.java
8650 views
1
/* -*-mode:java; c-basic-offset:2; -*- */
2
/*
3
Copyright (c) 2000-2011 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([email protected]) and Mark Adler([email protected])
32
* and contributors of zlib.
33
*/
34
35
package com.jcraft.jzlib;
36
37
final class Inflate{
38
39
static final private int MAX_WBITS=15; // 32K LZ77 window
40
41
// preset dictionary flag in zlib header
42
static final private int PRESET_DICT=0x20;
43
44
static final int Z_NO_FLUSH=0;
45
static final int Z_PARTIAL_FLUSH=1;
46
static final int Z_SYNC_FLUSH=2;
47
static final int Z_FULL_FLUSH=3;
48
static final int Z_FINISH=4;
49
50
static final private int Z_DEFLATED=8;
51
52
static final private int Z_OK=0;
53
static final private int Z_STREAM_END=1;
54
static final private int Z_NEED_DICT=2;
55
static final private int Z_ERRNO=-1;
56
static final private int Z_STREAM_ERROR=-2;
57
static final private int Z_DATA_ERROR=-3;
58
static final private int Z_MEM_ERROR=-4;
59
static final private int Z_BUF_ERROR=-5;
60
static final private int Z_VERSION_ERROR=-6;
61
62
static final private int METHOD=0; // waiting for method byte
63
static final private int FLAG=1; // waiting for flag byte
64
static final private int DICT4=2; // four dictionary check bytes to go
65
static final private int DICT3=3; // three dictionary check bytes to go
66
static final private int DICT2=4; // two dictionary check bytes to go
67
static final private int DICT1=5; // one dictionary check byte to go
68
static final private int DICT0=6; // waiting for inflateSetDictionary
69
static final private int BLOCKS=7; // decompressing blocks
70
static final private int CHECK4=8; // four check bytes to go
71
static final private int CHECK3=9; // three check bytes to go
72
static final private int CHECK2=10; // two check bytes to go
73
static final private int CHECK1=11; // one check byte to go
74
static final private int DONE=12; // finished check, done
75
static final private int BAD=13; // got an error--stay here
76
77
static final private int HEAD=14;
78
static final private int LENGTH=15;
79
static final private int TIME=16;
80
static final private int OS=17;
81
static final private int EXLEN=18;
82
static final private int EXTRA=19;
83
static final private int NAME=20;
84
static final private int COMMENT=21;
85
static final private int HCRC=22;
86
static final private int FLAGS=23;
87
88
static final int INFLATE_ANY=0x40000000;
89
90
int mode; // current inflate mode
91
92
// mode dependent information
93
int method; // if FLAGS, method byte
94
95
// if CHECK, check values to compare
96
long was = -1; // computed check value
97
long need; // stream check value
98
99
// if BAD, inflateSync's marker bytes count
100
int marker;
101
102
// mode independent information
103
int wrap; // flag for no wrapper
104
// 0: no wrapper
105
// 1: zlib header
106
// 2: gzip header
107
// 4: auto detection
108
109
int wbits; // log2(window size) (8..15, defaults to 15)
110
111
InfBlocks blocks; // current inflate_blocks state
112
113
private final ZStream z;
114
115
private int flags;
116
117
private int need_bytes = -1;
118
private byte[] crcbuf=new byte[4];
119
120
GZIPHeader gheader = null;
121
122
int inflateReset(){
123
if(z == null) return Z_STREAM_ERROR;
124
125
z.total_in = z.total_out = 0;
126
z.msg = null;
127
this.mode = HEAD;
128
this.need_bytes = -1;
129
this.blocks.reset();
130
return Z_OK;
131
}
132
133
int inflateEnd(){
134
if(blocks != null){
135
blocks.free();
136
}
137
return Z_OK;
138
}
139
140
Inflate(ZStream z){
141
this.z=z;
142
}
143
144
int inflateInit(int w){
145
z.msg = null;
146
blocks = null;
147
148
// handle undocumented wrap option (no zlib header or check)
149
wrap = 0;
150
if(w < 0){
151
w = - w;
152
}
153
else if((w&INFLATE_ANY) != 0){
154
wrap = 4;
155
w &= ~INFLATE_ANY;
156
if(w < 48)
157
w &= 15;
158
}
159
else if((w & ~31) != 0) { // for example, DEF_WBITS + 32
160
wrap = 4; // zlib and gzip wrapped data should be accepted.
161
w &= 15;
162
}
163
else {
164
wrap = (w >> 4) + 1;
165
if(w < 48)
166
w &= 15;
167
}
168
169
if(w<8 ||w>15){
170
inflateEnd();
171
return Z_STREAM_ERROR;
172
}
173
if(blocks != null && wbits != w){
174
blocks.free();
175
blocks=null;
176
}
177
178
// set window size
179
wbits=w;
180
181
this.blocks=new InfBlocks(z, 1<<w);
182
183
// reset state
184
inflateReset();
185
186
return Z_OK;
187
}
188
189
int inflate(int f){
190
int hold = 0;
191
192
int r;
193
int b;
194
195
if(z == null || z.next_in == null){
196
if(f == Z_FINISH && this.mode==HEAD)
197
return Z_OK;
198
return Z_STREAM_ERROR;
199
}
200
201
f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
202
r = Z_BUF_ERROR;
203
while (true){
204
205
switch (this.mode){
206
case HEAD:
207
if(wrap==0){
208
this.mode = BLOCKS;
209
break;
210
}
211
212
try { r=readBytes(2, r, f); }
213
catch(Return e){ return e.r; }
214
215
if((wrap == 4 || (wrap&2)!=0) &&
216
this.need == 0x8b1fL) { // gzip header
217
if(wrap == 4){
218
wrap = 2;
219
}
220
z.adler=new CRC32();
221
checksum(2, this.need);
222
223
if(gheader==null)
224
gheader=new GZIPHeader();
225
226
this.mode = FLAGS;
227
break;
228
}
229
230
if((wrap&2) != 0){
231
this.mode = BAD;
232
z.msg = "incorrect header check";
233
break;
234
}
235
236
flags = 0;
237
238
this.method = ((int)this.need)&0xff;
239
b=((int)(this.need>>8))&0xff;
240
241
if(((wrap&1)==0 || // check if zlib header allowed
242
(((this.method << 8)+b) % 31)!=0) &&
243
(this.method&0xf)!=Z_DEFLATED){
244
if(wrap == 4){
245
z.next_in_index -= 2;
246
z.avail_in += 2;
247
z.total_in -= 2;
248
wrap = 0;
249
this.mode = BLOCKS;
250
break;
251
}
252
this.mode = BAD;
253
z.msg = "incorrect header check";
254
// since zlib 1.2, it is allowted to inflateSync for this case.
255
/*
256
this.marker = 5; // can't try inflateSync
257
*/
258
break;
259
}
260
261
if((this.method&0xf)!=Z_DEFLATED){
262
this.mode = BAD;
263
z.msg="unknown compression method";
264
// since zlib 1.2, it is allowted to inflateSync for this case.
265
/*
266
this.marker = 5; // can't try inflateSync
267
*/
268
break;
269
}
270
271
if(wrap == 4){
272
wrap = 1;
273
}
274
275
if((this.method>>4)+8>this.wbits){
276
this.mode = BAD;
277
z.msg="invalid window size";
278
// since zlib 1.2, it is allowted to inflateSync for this case.
279
/*
280
this.marker = 5; // can't try inflateSync
281
*/
282
break;
283
}
284
285
z.adler=new Adler32();
286
287
if((b&PRESET_DICT)==0){
288
this.mode = BLOCKS;
289
break;
290
}
291
this.mode = DICT4;
292
case DICT4:
293
294
if(z.avail_in==0)return r;r=f;
295
296
z.avail_in--; z.total_in++;
297
this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
298
this.mode=DICT3;
299
case DICT3:
300
301
if(z.avail_in==0)return r;r=f;
302
303
z.avail_in--; z.total_in++;
304
this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
305
this.mode=DICT2;
306
case DICT2:
307
308
if(z.avail_in==0)return r;r=f;
309
310
z.avail_in--; z.total_in++;
311
this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
312
this.mode=DICT1;
313
case DICT1:
314
315
if(z.avail_in==0)return r;r=f;
316
317
z.avail_in--; z.total_in++;
318
this.need += (z.next_in[z.next_in_index++]&0xffL);
319
z.adler.reset(this.need);
320
this.mode = DICT0;
321
return Z_NEED_DICT;
322
case DICT0:
323
this.mode = BAD;
324
z.msg = "need dictionary";
325
this.marker = 0; // can try inflateSync
326
return Z_STREAM_ERROR;
327
case BLOCKS:
328
r = this.blocks.proc(r);
329
if(r == Z_DATA_ERROR){
330
this.mode = BAD;
331
this.marker = 0; // can try inflateSync
332
break;
333
}
334
if(r == Z_OK){
335
r = f;
336
}
337
if(r != Z_STREAM_END){
338
return r;
339
}
340
r = f;
341
this.was=z.adler.getValue();
342
this.blocks.reset();
343
if(this.wrap==0){
344
this.mode=DONE;
345
break;
346
}
347
this.mode=CHECK4;
348
case CHECK4:
349
350
if(z.avail_in==0)return r;r=f;
351
352
z.avail_in--; z.total_in++;
353
this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
354
this.mode=CHECK3;
355
case CHECK3:
356
357
if(z.avail_in==0)return r;r=f;
358
359
z.avail_in--; z.total_in++;
360
this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
361
this.mode = CHECK2;
362
case CHECK2:
363
364
if(z.avail_in==0)return r;r=f;
365
366
z.avail_in--; z.total_in++;
367
this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
368
this.mode = CHECK1;
369
case CHECK1:
370
371
if(z.avail_in==0)return r;r=f;
372
373
z.avail_in--; z.total_in++;
374
this.need+=(z.next_in[z.next_in_index++]&0xffL);
375
376
if(flags!=0){ // gzip
377
this.need = ((this.need&0xff000000)>>24 |
378
(this.need&0x00ff0000)>>8 |
379
(this.need&0x0000ff00)<<8 |
380
(this.need&0x0000ffff)<<24)&0xffffffffL;
381
}
382
383
if(((int)(this.was)) != ((int)(this.need))){
384
z.msg = "incorrect data check";
385
// chack is delayed
386
/*
387
this.mode = BAD;
388
this.marker = 5; // can't try inflateSync
389
break;
390
*/
391
}
392
else if(flags!=0 && gheader!=null){
393
gheader.crc = this.need;
394
}
395
396
this.mode = LENGTH;
397
case LENGTH:
398
if (wrap!=0 && flags!=0) {
399
400
try { r=readBytes(4, r, f); }
401
catch(Return e){ return e.r; }
402
403
if(z.msg!=null && z.msg.equals("incorrect data check")){
404
this.mode = BAD;
405
this.marker = 5; // can't try inflateSync
406
break;
407
}
408
409
if (this.need != (z.total_out & 0xffffffffL)) {
410
z.msg = "incorrect length check";
411
this.mode = BAD;
412
break;
413
}
414
z.msg = null;
415
}
416
else {
417
if(z.msg!=null && z.msg.equals("incorrect data check")){
418
this.mode = BAD;
419
this.marker = 5; // can't try inflateSync
420
break;
421
}
422
}
423
424
this.mode = DONE;
425
case DONE:
426
return Z_STREAM_END;
427
case BAD:
428
return Z_DATA_ERROR;
429
430
case FLAGS:
431
432
try { r=readBytes(2, r, f); }
433
catch(Return e){ return e.r; }
434
435
flags = ((int)this.need)&0xffff;
436
437
if ((flags & 0xff) != Z_DEFLATED) {
438
z.msg = "unknown compression method";
439
this.mode = BAD;
440
break;
441
}
442
if ((flags & 0xe000)!=0) {
443
z.msg = "unknown header flags set";
444
this.mode = BAD;
445
break;
446
}
447
448
if ((flags & 0x0200)!=0){
449
checksum(2, this.need);
450
}
451
452
this.mode = TIME;
453
454
case TIME:
455
try { r=readBytes(4, r, f); }
456
catch(Return e){ return e.r; }
457
if(gheader!=null)
458
gheader.time = this.need;
459
if ((flags & 0x0200)!=0){
460
checksum(4, this.need);
461
}
462
this.mode = OS;
463
case OS:
464
try { r=readBytes(2, r, f); }
465
catch(Return e){ return e.r; }
466
if(gheader!=null){
467
gheader.xflags = ((int)this.need)&0xff;
468
gheader.os = (((int)this.need)>>8)&0xff;
469
}
470
if ((flags & 0x0200)!=0){
471
checksum(2, this.need);
472
}
473
this.mode = EXLEN;
474
case EXLEN:
475
if ((flags & 0x0400)!=0) {
476
try { r=readBytes(2, r, f); }
477
catch(Return e){ return e.r; }
478
if(gheader!=null){
479
gheader.extra = new byte[((int)this.need)&0xffff];
480
}
481
if ((flags & 0x0200)!=0){
482
checksum(2, this.need);
483
}
484
}
485
else if(gheader!=null){
486
gheader.extra=null;
487
}
488
this.mode = EXTRA;
489
490
case EXTRA:
491
if ((flags & 0x0400)!=0) {
492
try {
493
r=readBytes(r, f);
494
if(gheader!=null){
495
byte[] foo = tmp_string.toByteArray();
496
tmp_string=null;
497
if(foo.length == gheader.extra.length){
498
System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
499
}
500
else{
501
z.msg = "bad extra field length";
502
this.mode = BAD;
503
break;
504
}
505
}
506
}
507
catch(Return e){ return e.r; }
508
}
509
else if(gheader!=null){
510
gheader.extra=null;
511
}
512
this.mode = NAME;
513
case NAME:
514
if ((flags & 0x0800)!=0) {
515
try {
516
r=readString(r, f);
517
if(gheader!=null){
518
gheader.name=tmp_string.toByteArray();
519
}
520
tmp_string=null;
521
}
522
catch(Return e){ return e.r; }
523
}
524
else if(gheader!=null){
525
gheader.name=null;
526
}
527
this.mode = COMMENT;
528
case COMMENT:
529
if ((flags & 0x1000)!=0) {
530
try {
531
r=readString(r, f);
532
if(gheader!=null){
533
gheader.comment=tmp_string.toByteArray();
534
}
535
tmp_string=null;
536
}
537
catch(Return e){ return e.r; }
538
}
539
else if(gheader!=null){
540
gheader.comment=null;
541
}
542
this.mode = HCRC;
543
case HCRC:
544
if ((flags & 0x0200)!=0) {
545
try { r=readBytes(2, r, f); }
546
catch(Return e){ return e.r; }
547
if(gheader!=null){
548
gheader.hcrc=(int)(this.need&0xffff);
549
}
550
if(this.need != (z.adler.getValue()&0xffffL)){
551
this.mode = BAD;
552
z.msg = "header crc mismatch";
553
this.marker = 5; // can't try inflateSync
554
break;
555
}
556
}
557
z.adler = new CRC32();
558
559
this.mode = BLOCKS;
560
break;
561
default:
562
return Z_STREAM_ERROR;
563
}
564
}
565
}
566
567
int inflateSetDictionary(byte[] dictionary, int dictLength){
568
if(z==null || (this.mode != DICT0 && this.wrap != 0)){
569
return Z_STREAM_ERROR;
570
}
571
572
int index=0;
573
int length = dictLength;
574
575
if(this.mode==DICT0){
576
long adler_need=z.adler.getValue();
577
z.adler.reset();
578
z.adler.update(dictionary, 0, dictLength);
579
if(z.adler.getValue()!=adler_need){
580
return Z_DATA_ERROR;
581
}
582
}
583
584
z.adler.reset();
585
586
if(length >= (1<<this.wbits)){
587
length = (1<<this.wbits)-1;
588
index=dictLength - length;
589
}
590
this.blocks.set_dictionary(dictionary, index, length);
591
this.mode = BLOCKS;
592
return Z_OK;
593
}
594
595
static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
596
597
int inflateSync(){
598
int n; // number of bytes to look at
599
int p; // pointer to bytes
600
int m; // number of marker bytes found in a row
601
long r, w; // temporaries to save total_in and total_out
602
603
// set up
604
if(z == null)
605
return Z_STREAM_ERROR;
606
if(this.mode != BAD){
607
this.mode = BAD;
608
this.marker = 0;
609
}
610
if((n=z.avail_in)==0)
611
return Z_BUF_ERROR;
612
613
p=z.next_in_index;
614
m=this.marker;
615
// search
616
while (n!=0 && m < 4){
617
if(z.next_in[p] == mark[m]){
618
m++;
619
}
620
else if(z.next_in[p]!=0){
621
m = 0;
622
}
623
else{
624
m = 4 - m;
625
}
626
p++; n--;
627
}
628
629
// restore
630
z.total_in += p-z.next_in_index;
631
z.next_in_index = p;
632
z.avail_in = n;
633
this.marker = m;
634
635
// return no joy or set up to restart on a new block
636
if(m != 4){
637
return Z_DATA_ERROR;
638
}
639
r=z.total_in; w=z.total_out;
640
inflateReset();
641
z.total_in=r; z.total_out = w;
642
this.mode = BLOCKS;
643
644
return Z_OK;
645
}
646
647
// Returns true if inflate is currently at the end of a block generated
648
// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
649
// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
650
// but removes the length bytes of the resulting empty stored block. When
651
// decompressing, PPP checks that at the end of input packet, inflate is
652
// waiting for these length bytes.
653
int inflateSyncPoint(){
654
if(z == null || this.blocks == null)
655
return Z_STREAM_ERROR;
656
return this.blocks.sync_point();
657
}
658
659
private int readBytes(int n, int r, int f) throws Return{
660
if(need_bytes == -1){
661
need_bytes=n;
662
this.need=0;
663
}
664
while(need_bytes>0){
665
if(z.avail_in==0){ throw new Return(r); }; r=f;
666
z.avail_in--; z.total_in++;
667
this.need = this.need |
668
((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8));
669
need_bytes--;
670
}
671
if(n==2){
672
this.need&=0xffffL;
673
}
674
else if(n==4) {
675
this.need&=0xffffffffL;
676
}
677
need_bytes=-1;
678
return r;
679
}
680
class Return extends Exception{
681
int r;
682
Return(int r){this.r=r; }
683
}
684
685
private java.io.ByteArrayOutputStream tmp_string = null;
686
private int readString(int r, int f) throws Return{
687
if(tmp_string == null){
688
tmp_string=new java.io.ByteArrayOutputStream();
689
}
690
int b=0;
691
do {
692
if(z.avail_in==0){ throw new Return(r); }; r=f;
693
z.avail_in--; z.total_in++;
694
b = z.next_in[z.next_in_index];
695
if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1);
696
z.adler.update(z.next_in, z.next_in_index, 1);
697
z.next_in_index++;
698
}while(b!=0);
699
return r;
700
}
701
702
private int readBytes(int r, int f) throws Return{
703
if(tmp_string == null){
704
tmp_string=new java.io.ByteArrayOutputStream();
705
}
706
int b=0;
707
while(this.need>0){
708
if(z.avail_in==0){ throw new Return(r); }; r=f;
709
z.avail_in--; z.total_in++;
710
b = z.next_in[z.next_in_index];
711
tmp_string.write(z.next_in, z.next_in_index, 1);
712
z.adler.update(z.next_in, z.next_in_index, 1);
713
z.next_in_index++;
714
this.need--;
715
}
716
return r;
717
}
718
719
private void checksum(int n, long v){
720
for(int i=0; i<n; i++){
721
crcbuf[i]=(byte)(v&0xff);
722
v>>=8;
723
}
724
z.adler.update(crcbuf, 0, n);
725
}
726
727
public GZIPHeader getGZIPHeader(){
728
return gheader;
729
}
730
731
boolean inParsingHeader(){
732
switch(mode){
733
case HEAD:
734
case DICT4:
735
case DICT3:
736
case DICT2:
737
case DICT1:
738
case FLAGS:
739
case TIME:
740
case OS:
741
case EXLEN:
742
case EXTRA:
743
case NAME:
744
case COMMENT:
745
case HCRC:
746
return true;
747
default:
748
return false;
749
}
750
}
751
}
752
753