1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 package org.jboss.netty.util.internal.jzlib;
50
51 import org.jboss.netty.util.internal.jzlib.JZlib.WrapperType;
52
53 final class Deflate {
54
55 private static final class Config {
56 final int good_length;
57 final int max_lazy;
58 final int nice_length;
59 final int max_chain;
60 final int func;
61
62 Config(int good_length, int max_lazy, int nice_length, int max_chain,
63 int func) {
64 this.good_length = good_length;
65 this.max_lazy = max_lazy;
66 this.nice_length = nice_length;
67 this.max_chain = max_chain;
68 this.func = func;
69 }
70 }
71
72 private static final int STORED = 0;
73 private static final int FAST = 1;
74 private static final int SLOW = 2;
75
76 private static final Config[] config_table;
77 static {
78 config_table = new Config[10];
79 config_table[0] = new Config(0, 0, 0, 0, STORED);
80 config_table[1] = new Config(4, 4, 8, 4, FAST);
81 config_table[2] = new Config(4, 5, 16, 8, FAST);
82 config_table[3] = new Config(4, 6, 32, 32, FAST);
83
84 config_table[4] = new Config(4, 4, 16, 16, SLOW);
85 config_table[5] = new Config(8, 16, 32, 32, SLOW);
86 config_table[6] = new Config(8, 16, 128, 128, SLOW);
87 config_table[7] = new Config(8, 32, 128, 256, SLOW);
88 config_table[8] = new Config(32, 128, 258, 1024, SLOW);
89 config_table[9] = new Config(32, 258, 258, 4096, SLOW);
90 }
91
92 private static final String[] z_errmsg = { "need dictionary",
93 "stream end",
94 "",
95 "file error",
96 "stream error",
97 "data error",
98 "insufficient memory",
99 "buffer error",
100 "incompatible version",
101 "" };
102
103
104 private static final int NeedMore = 0;
105
106 private static final int BlockDone = 1;
107
108 private static final int FinishStarted = 2;
109
110 private static final int FinishDone = 3;
111 private static final int INIT_STATE = 42;
112 private static final int BUSY_STATE = 113;
113 private static final int FINISH_STATE = 666;
114 private static final int STORED_BLOCK = 0;
115 private static final int STATIC_TREES = 1;
116 private static final int DYN_TREES = 2;
117
118 private static final int Z_BINARY = 0;
119 private static final int Z_ASCII = 1;
120 private static final int Z_UNKNOWN = 2;
121 private static final int Buf_size = 8 * 2;
122
123 private static final int REP_3_6 = 16;
124
125 private static final int REPZ_3_10 = 17;
126
127 private static final int REPZ_11_138 = 18;
128 private static final int MIN_MATCH = 3;
129 private static final int MAX_MATCH = 258;
130 private static final int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
131 private static final int END_BLOCK = 256;
132 ZStream strm;
133 int status;
134 byte[] pending_buf;
135 int pending_buf_size;
136 int pending_out;
137 int pending;
138 WrapperType wrapperType;
139 private boolean wroteTrailer;
140 byte data_type;
141 int last_flush;
142 int w_size;
143 int w_bits;
144 int w_mask;
145 byte[] window;
146
147
148
149
150
151
152
153 int window_size;
154
155
156 short[] prev;
157
158
159
160 short[] head;
161 int ins_h;
162 int hash_size;
163 int hash_bits;
164 int hash_mask;
165
166
167
168
169 int hash_shift;
170
171
172 int block_start;
173 int match_length;
174 int prev_match;
175 int match_available;
176 int strstart;
177 int match_start;
178 int lookahead;
179
180
181 int prev_length;
182
183
184 int max_chain_length;
185
186
187
188 int max_lazy_match;
189
190
191
192 int level;
193 int strategy;
194
195 int good_match;
196
197 int nice_match;
198 short[] dyn_ltree;
199 short[] dyn_dtree;
200 short[] bl_tree;
201 Tree l_desc = new Tree();
202 Tree d_desc = new Tree();
203 Tree bl_desc = new Tree();
204
205 short[] bl_count = new short[JZlib.MAX_BITS + 1];
206
207 int[] heap = new int[2 * JZlib.L_CODES + 1];
208 int heap_len;
209 int heap_max;
210
211
212
213 byte[] depth = new byte[2 * JZlib.L_CODES + 1];
214 int l_buf;
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 int lit_bufsize;
233 int last_lit;
234
235
236
237 int d_buf;
238 int opt_len;
239 int static_len;
240 int matches;
241 int last_eob_len;
242
243
244 short bi_buf;
245
246
247 int bi_valid;
248 private int gzipUncompressedBytes;
249
250 Deflate() {
251 dyn_ltree = new short[JZlib.HEAP_SIZE * 2];
252 dyn_dtree = new short[(2 * JZlib.D_CODES + 1) * 2];
253 bl_tree = new short[(2 * JZlib.BL_CODES + 1) * 2];
254 }
255
256 private void lm_init() {
257 window_size = 2 * w_size;
258
259
260 max_lazy_match = Deflate.config_table[level].max_lazy;
261 good_match = Deflate.config_table[level].good_length;
262 nice_match = Deflate.config_table[level].nice_length;
263 max_chain_length = Deflate.config_table[level].max_chain;
264
265 strstart = 0;
266 block_start = 0;
267 lookahead = 0;
268 match_length = prev_length = MIN_MATCH - 1;
269 match_available = 0;
270 ins_h = 0;
271 }
272
273
274 private void tr_init() {
275
276 l_desc.dyn_tree = dyn_ltree;
277 l_desc.stat_desc = StaticTree.static_l_desc;
278
279 d_desc.dyn_tree = dyn_dtree;
280 d_desc.stat_desc = StaticTree.static_d_desc;
281
282 bl_desc.dyn_tree = bl_tree;
283 bl_desc.stat_desc = StaticTree.static_bl_desc;
284
285 bi_buf = 0;
286 bi_valid = 0;
287 last_eob_len = 8;
288
289
290 init_block();
291 }
292
293 private void init_block() {
294
295 for (int i = 0; i < JZlib.L_CODES; i ++) {
296 dyn_ltree[i * 2] = 0;
297 }
298 for (int i = 0; i < JZlib.D_CODES; i ++) {
299 dyn_dtree[i * 2] = 0;
300 }
301 for (int i = 0; i < JZlib.BL_CODES; i ++) {
302 bl_tree[i * 2] = 0;
303 }
304
305 dyn_ltree[END_BLOCK * 2] = 1;
306 opt_len = static_len = 0;
307 last_lit = matches = 0;
308 }
309
310
311
312
313
314 void pqdownheap(short[] tree,
315 int k
316 ) {
317 int v = heap[k];
318 int j = k << 1;
319 while (j <= heap_len) {
320
321 if (j < heap_len && smaller(tree, heap[j + 1], heap[j], depth)) {
322 j ++;
323 }
324
325 if (smaller(tree, v, heap[j], depth)) {
326 break;
327 }
328
329
330 heap[k] = heap[j];
331 k = j;
332
333 j <<= 1;
334 }
335 heap[k] = v;
336 }
337
338 private static boolean smaller(short[] tree, int n, int m, byte[] depth) {
339 short tn2 = tree[n * 2];
340 short tm2 = tree[m * 2];
341 return tn2 < tm2 || tn2 == tm2 && depth[n] <= depth[m];
342 }
343
344
345
346 private void scan_tree(short[] tree,
347 int max_code
348 ) {
349 int n;
350 int prevlen = -1;
351 int curlen;
352 int nextlen = tree[0 * 2 + 1];
353 int count = 0;
354 int max_count = 7;
355 int min_count = 4;
356
357 if (nextlen == 0) {
358 max_count = 138;
359 min_count = 3;
360 }
361 tree[(max_code + 1) * 2 + 1] = (short) 0xffff;
362
363 for (n = 0; n <= max_code; n ++) {
364 curlen = nextlen;
365 nextlen = tree[(n + 1) * 2 + 1];
366 if (++ count < max_count && curlen == nextlen) {
367 continue;
368 } else if (count < min_count) {
369 bl_tree[curlen * 2] += count;
370 } else if (curlen != 0) {
371 if (curlen != prevlen) {
372 bl_tree[curlen * 2] ++;
373 }
374 bl_tree[REP_3_6 * 2] ++;
375 } else if (count <= 10) {
376 bl_tree[REPZ_3_10 * 2] ++;
377 } else {
378 bl_tree[REPZ_11_138 * 2] ++;
379 }
380 count = 0;
381 prevlen = curlen;
382 if (nextlen == 0) {
383 max_count = 138;
384 min_count = 3;
385 } else if (curlen == nextlen) {
386 max_count = 6;
387 min_count = 3;
388 } else {
389 max_count = 7;
390 min_count = 4;
391 }
392 }
393 }
394
395
396
397 private int build_bl_tree() {
398 int max_blindex;
399
400
401 scan_tree(dyn_ltree, l_desc.max_code);
402 scan_tree(dyn_dtree, d_desc.max_code);
403
404
405 bl_desc.build_tree(this);
406
407
408
409
410
411
412 for (max_blindex = JZlib.BL_CODES - 1; max_blindex >= 3; max_blindex --) {
413 if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0) {
414 break;
415 }
416 }
417
418 opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
419
420 return max_blindex;
421 }
422
423
424
425
426 private void send_all_trees(int lcodes, int dcodes, int blcodes) {
427 int rank;
428
429 send_bits(lcodes - 257, 5);
430 send_bits(dcodes - 1, 5);
431 send_bits(blcodes - 4, 4);
432 for (rank = 0; rank < blcodes; rank ++) {
433 send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
434 }
435 send_tree(dyn_ltree, lcodes - 1);
436 send_tree(dyn_dtree, dcodes - 1);
437 }
438
439
440
441 private void send_tree(short[] tree,
442 int max_code
443 ) {
444 int n;
445 int prevlen = -1;
446 int curlen;
447 int nextlen = tree[0 * 2 + 1];
448 int count = 0;
449 int max_count = 7;
450 int min_count = 4;
451
452 if (nextlen == 0) {
453 max_count = 138;
454 min_count = 3;
455 }
456
457 for (n = 0; n <= max_code; n ++) {
458 curlen = nextlen;
459 nextlen = tree[(n + 1) * 2 + 1];
460 if (++ count < max_count && curlen == nextlen) {
461 continue;
462 } else if (count < min_count) {
463 do {
464 send_code(curlen, bl_tree);
465 } while (-- count != 0);
466 } else if (curlen != 0) {
467 if (curlen != prevlen) {
468 send_code(curlen, bl_tree);
469 count --;
470 }
471 send_code(REP_3_6, bl_tree);
472 send_bits(count - 3, 2);
473 } else if (count <= 10) {
474 send_code(REPZ_3_10, bl_tree);
475 send_bits(count - 3, 3);
476 } else {
477 send_code(REPZ_11_138, bl_tree);
478 send_bits(count - 11, 7);
479 }
480 count = 0;
481 prevlen = curlen;
482 if (nextlen == 0) {
483 max_count = 138;
484 min_count = 3;
485 } else if (curlen == nextlen) {
486 max_count = 6;
487 min_count = 3;
488 } else {
489 max_count = 7;
490 min_count = 4;
491 }
492 }
493 }
494
495
496
497 private final void put_byte(byte[] p, int start, int len) {
498 System.arraycopy(p, start, pending_buf, pending, len);
499 pending += len;
500 }
501
502 private final void put_byte(byte c) {
503 pending_buf[pending ++] = c;
504 }
505
506 private final void put_short(int w) {
507 put_byte((byte) w
508 put_byte((byte) (w >>> 8));
509 }
510
511 private final void putShortMSB(int b) {
512 put_byte((byte) (b >> 8));
513 put_byte((byte) b
514 }
515
516 private final void send_code(int c, short[] tree) {
517 int c2 = c * 2;
518 send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff));
519 }
520
521 private void send_bits(int value, int length) {
522 int len = length;
523 if (bi_valid > Buf_size - len) {
524 int val = value;
525
526 bi_buf |= val << bi_valid & 0xffff;
527 put_short(bi_buf);
528 bi_buf = (short) (val >>> Buf_size - bi_valid);
529 bi_valid += len - Buf_size;
530 } else {
531
532 bi_buf |= value << bi_valid & 0xffff;
533 bi_valid += len;
534 }
535 }
536
537
538
539
540
541
542
543
544
545
546 private void _tr_align() {
547 send_bits(STATIC_TREES << 1, 3);
548 send_code(END_BLOCK, StaticTree.static_ltree);
549
550 bi_flush();
551
552
553
554
555
556 if (1 + last_eob_len + 10 - bi_valid < 9) {
557 send_bits(STATIC_TREES << 1, 3);
558 send_code(END_BLOCK, StaticTree.static_ltree);
559 bi_flush();
560 }
561 last_eob_len = 7;
562 }
563
564
565
566 private boolean _tr_tally(int dist,
567 int lc
568 ) {
569
570 pending_buf[d_buf + last_lit * 2] = (byte) (dist >>> 8);
571 pending_buf[d_buf + last_lit * 2 + 1] = (byte) dist;
572
573 pending_buf[l_buf + last_lit] = (byte) lc;
574 last_lit ++;
575
576 if (dist == 0) {
577
578 dyn_ltree[lc * 2] ++;
579 } else {
580 matches ++;
581
582 dist --;
583 dyn_ltree[(Tree._length_code[lc] + JZlib.LITERALS + 1) * 2] ++;
584 dyn_dtree[Tree.d_code(dist) * 2] ++;
585 }
586
587 if ((last_lit & 0x1fff) == 0 && level > 2) {
588
589 int out_length = last_lit * 8;
590 int in_length = strstart - block_start;
591 int dcode;
592 for (dcode = 0; dcode < JZlib.D_CODES; dcode ++) {
593 out_length += dyn_dtree[dcode * 2] *
594 (5L + Tree.extra_dbits[dcode]);
595 }
596 out_length >>>= 3;
597 if (matches < last_lit / 2 && out_length < in_length / 2) {
598 return true;
599 }
600 }
601
602 return last_lit == lit_bufsize - 1;
603
604
605
606 }
607
608
609 private void compress_block(short[] ltree, short[] dtree) {
610 int dist;
611 int lc;
612 int lx = 0;
613 int code;
614 int extra;
615
616 if (last_lit != 0) {
617 do {
618 dist = pending_buf[d_buf + lx * 2] << 8 & 0xff00 |
619 pending_buf[d_buf + lx * 2 + 1] & 0xff;
620 lc = pending_buf[l_buf + lx] & 0xff;
621 lx ++;
622
623 if (dist == 0) {
624 send_code(lc, ltree);
625 } else {
626
627 code = Tree._length_code[lc];
628
629 send_code(code + JZlib.LITERALS + 1, ltree);
630 extra = Tree.extra_lbits[code];
631 if (extra != 0) {
632 lc -= Tree.base_length[code];
633 send_bits(lc, extra);
634 }
635 dist --;
636 code = Tree.d_code(dist);
637
638 send_code(code, dtree);
639 extra = Tree.extra_dbits[code];
640 if (extra != 0) {
641 dist -= Tree.base_dist[code];
642 send_bits(dist, extra);
643 }
644 }
645
646
647 } while (lx < last_lit);
648 }
649
650 send_code(END_BLOCK, ltree);
651 last_eob_len = ltree[END_BLOCK * 2 + 1];
652 }
653
654
655
656
657
658 private void set_data_type() {
659 int n = 0;
660 int ascii_freq = 0;
661 int bin_freq = 0;
662 while (n < 7) {
663 bin_freq += dyn_ltree[n * 2];
664 n ++;
665 }
666 while (n < 128) {
667 ascii_freq += dyn_ltree[n * 2];
668 n ++;
669 }
670 while (n < JZlib.LITERALS) {
671 bin_freq += dyn_ltree[n * 2];
672 n ++;
673 }
674 data_type = (byte) (bin_freq > ascii_freq >>> 2? Z_BINARY : Z_ASCII);
675 }
676
677
678 private void bi_flush() {
679 if (bi_valid == 16) {
680 put_short(bi_buf);
681 bi_buf = 0;
682 bi_valid = 0;
683 } else if (bi_valid >= 8) {
684 put_byte((byte) bi_buf);
685 bi_buf >>>= 8;
686 bi_valid -= 8;
687 }
688 }
689
690
691 private void bi_windup() {
692 if (bi_valid > 8) {
693 put_short(bi_buf);
694 } else if (bi_valid > 0) {
695 put_byte((byte) bi_buf);
696 }
697 bi_buf = 0;
698 bi_valid = 0;
699 }
700
701
702
703 private void copy_block(int buf,
704 int len,
705 boolean header
706 ) {
707 bi_windup();
708 last_eob_len = 8;
709
710 if (header) {
711 put_short((short) len);
712 put_short((short) ~len);
713 }
714
715
716
717
718
719 put_byte(window, buf, len);
720 }
721
722 private void flush_block_only(boolean eof) {
723 _tr_flush_block(block_start >= 0? block_start : -1, strstart -
724 block_start, eof);
725 block_start = strstart;
726 strm.flush_pending();
727 }
728
729
730
731
732
733
734
735
736 private int deflate_stored(int flush) {
737
738
739
740 int max_block_size = 0xffff;
741 int max_start;
742
743 if (max_block_size > pending_buf_size - 5) {
744 max_block_size = pending_buf_size - 5;
745 }
746
747
748 while (true) {
749
750 if (lookahead <= 1) {
751 fill_window();
752 if (lookahead == 0 && flush == JZlib.Z_NO_FLUSH) {
753 return NeedMore;
754 }
755 if (lookahead == 0) {
756 break;
757 }
758 }
759
760 strstart += lookahead;
761 lookahead = 0;
762
763
764 max_start = block_start + max_block_size;
765 if (strstart == 0 || strstart >= max_start) {
766
767 lookahead = strstart - max_start;
768 strstart = max_start;
769
770 flush_block_only(false);
771 if (strm.avail_out == 0) {
772 return NeedMore;
773 }
774
775 }
776
777
778
779 if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
780 flush_block_only(false);
781 if (strm.avail_out == 0) {
782 return NeedMore;
783 }
784 }
785 }
786
787 flush_block_only(flush == JZlib.Z_FINISH);
788 if (strm.avail_out == 0) {
789 return flush == JZlib.Z_FINISH? FinishStarted : NeedMore;
790 }
791
792 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
793 }
794
795
796 private void _tr_stored_block(int buf,
797 int stored_len,
798 boolean eof
799 ) {
800 send_bits((STORED_BLOCK << 1) + (eof? 1 : 0), 3);
801 copy_block(buf, stored_len, true);
802 }
803
804
805
806 private void _tr_flush_block(int buf,
807 int stored_len,
808 boolean eof
809 ) {
810 int opt_lenb, static_lenb;
811 int max_blindex = 0;
812
813
814 if (level > 0) {
815
816 if (data_type == Z_UNKNOWN) {
817 set_data_type();
818 }
819
820
821 l_desc.build_tree(this);
822
823 d_desc.build_tree(this);
824
825
826
827
828
829
830 max_blindex = build_bl_tree();
831
832
833 opt_lenb = opt_len + 3 + 7 >>> 3;
834 static_lenb = static_len + 3 + 7 >>> 3;
835
836 if (static_lenb <= opt_lenb) {
837 opt_lenb = static_lenb;
838 }
839 } else {
840 opt_lenb = static_lenb = stored_len + 5;
841 }
842
843 if (stored_len + 4 <= opt_lenb && buf != -1) {
844
845
846
847
848
849
850 _tr_stored_block(buf, stored_len, eof);
851 } else if (static_lenb == opt_lenb) {
852 send_bits((STATIC_TREES << 1) + (eof? 1 : 0), 3);
853 compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
854 } else {
855 send_bits((DYN_TREES << 1) + (eof? 1 : 0), 3);
856 send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1,
857 max_blindex + 1);
858 compress_block(dyn_ltree, dyn_dtree);
859 }
860
861
862
863
864 init_block();
865
866 if (eof) {
867 bi_windup();
868 }
869 }
870
871
872
873
874
875
876
877
878
879 private void fill_window() {
880 int n, m;
881 int p;
882 int more;
883
884 do {
885 more = window_size - lookahead - strstart;
886
887
888 if (more == 0 && strstart == 0 && lookahead == 0) {
889 more = w_size;
890 } else if (more == -1) {
891
892
893 more --;
894
895
896
897 } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
898 System.arraycopy(window, w_size, window, 0, w_size);
899 match_start -= w_size;
900 strstart -= w_size;
901 block_start -= w_size;
902
903
904
905
906
907
908
909 n = hash_size;
910 p = n;
911 do {
912 m = head[-- p] & 0xffff;
913 head[p] = m >= w_size? (short) (m - w_size) : 0;
914 } while (-- n != 0);
915
916 n = w_size;
917 p = n;
918 do {
919 m = prev[-- p] & 0xffff;
920 prev[p] = m >= w_size? (short) (m - w_size) : 0;
921
922
923 } while (-- n != 0);
924 more += w_size;
925 }
926
927 if (strm.avail_in == 0) {
928 return;
929 }
930
931
932
933
934
935
936
937
938
939
940
941
942 n = strm.read_buf(window, strstart + lookahead, more);
943 lookahead += n;
944
945
946 if (lookahead >= MIN_MATCH) {
947 ins_h = window[strstart] & 0xff;
948 ins_h = (ins_h << hash_shift ^ window[strstart + 1] & 0xff) &
949 hash_mask;
950 }
951
952
953 } while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0);
954 }
955
956
957
958
959
960
961 private int deflate_fast(int flush) {
962
963 int hash_head = 0;
964 boolean bflush;
965
966 while (true) {
967
968
969
970
971 if (lookahead < MIN_LOOKAHEAD) {
972 fill_window();
973 if (lookahead < MIN_LOOKAHEAD && flush == JZlib.Z_NO_FLUSH) {
974 return NeedMore;
975 }
976 if (lookahead == 0) {
977 break;
978 }
979 }
980
981
982
983 if (lookahead >= MIN_MATCH) {
984 ins_h = (ins_h << hash_shift ^ window[strstart + MIN_MATCH - 1] & 0xff) &
985 hash_mask;
986
987
988 hash_head = head[ins_h] & 0xffff;
989 prev[strstart & w_mask] = head[ins_h];
990 head[ins_h] = (short) strstart;
991 }
992
993
994
995
996 if (hash_head != 0L &&
997 (strstart - hash_head & 0xffff) <= w_size - MIN_LOOKAHEAD) {
998
999
1000
1001 if (strategy != JZlib.Z_HUFFMAN_ONLY) {
1002 match_length = longest_match(hash_head);
1003 }
1004
1005 }
1006 if (match_length >= MIN_MATCH) {
1007
1008
1009 bflush = _tr_tally(strstart - match_start, match_length -
1010 MIN_MATCH);
1011
1012 lookahead -= match_length;
1013
1014
1015
1016 if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
1017 match_length --;
1018 do {
1019 strstart ++;
1020
1021 ins_h = (ins_h << hash_shift ^ window[strstart +
1022 MIN_MATCH - 1] & 0xff) &
1023 hash_mask;
1024
1025 hash_head = head[ins_h] & 0xffff;
1026 prev[strstart & w_mask] = head[ins_h];
1027 head[ins_h] = (short) strstart;
1028
1029
1030
1031 } while (-- match_length != 0);
1032 strstart ++;
1033 } else {
1034 strstart += match_length;
1035 match_length = 0;
1036 ins_h = window[strstart] & 0xff;
1037
1038 ins_h = (ins_h << hash_shift ^ window[strstart + 1] & 0xff) &
1039 hash_mask;
1040
1041
1042 }
1043 } else {
1044
1045
1046 bflush = _tr_tally(0, window[strstart] & 0xff);
1047 lookahead --;
1048 strstart ++;
1049 }
1050 if (bflush) {
1051
1052 flush_block_only(false);
1053 if (strm.avail_out == 0) {
1054 return NeedMore;
1055 }
1056 }
1057 }
1058
1059 flush_block_only(flush == JZlib.Z_FINISH);
1060 if (strm.avail_out == 0) {
1061 if (flush == JZlib.Z_FINISH) {
1062 return FinishStarted;
1063 } else {
1064 return NeedMore;
1065 }
1066 }
1067 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
1068 }
1069
1070
1071
1072
1073 private int deflate_slow(int flush) {
1074
1075 int hash_head = 0;
1076 boolean bflush;
1077
1078
1079 while (true) {
1080
1081
1082
1083
1084
1085 if (lookahead < MIN_LOOKAHEAD) {
1086 fill_window();
1087 if (lookahead < MIN_LOOKAHEAD && flush == JZlib.Z_NO_FLUSH) {
1088 return NeedMore;
1089 }
1090 if (lookahead == 0) {
1091 break;
1092 }
1093 }
1094
1095
1096
1097
1098 if (lookahead >= MIN_MATCH) {
1099 ins_h = (ins_h << hash_shift ^ window[strstart + MIN_MATCH - 1] & 0xff) &
1100 hash_mask;
1101
1102 hash_head = head[ins_h] & 0xffff;
1103 prev[strstart & w_mask] = head[ins_h];
1104 head[ins_h] = (short) strstart;
1105 }
1106
1107
1108 prev_length = match_length;
1109 prev_match = match_start;
1110 match_length = MIN_MATCH - 1;
1111
1112 if (hash_head != 0 && prev_length < max_lazy_match &&
1113 (strstart - hash_head & 0xffff) <= w_size - MIN_LOOKAHEAD) {
1114
1115
1116
1117
1118 if (strategy != JZlib.Z_HUFFMAN_ONLY) {
1119 match_length = longest_match(hash_head);
1120 }
1121
1122
1123 if (match_length <= 5 &&
1124 (strategy == JZlib.Z_FILTERED || match_length == MIN_MATCH &&
1125 strstart - match_start > 4096)) {
1126
1127
1128
1129 match_length = MIN_MATCH - 1;
1130 }
1131 }
1132
1133
1134
1135 if (prev_length >= MIN_MATCH && match_length <= prev_length) {
1136 int max_insert = strstart + lookahead - MIN_MATCH;
1137
1138
1139
1140
1141 bflush = _tr_tally(strstart - 1 - prev_match, prev_length -
1142 MIN_MATCH);
1143
1144
1145
1146
1147
1148 lookahead -= prev_length - 1;
1149 prev_length -= 2;
1150 do {
1151 if (++ strstart <= max_insert) {
1152 ins_h = (ins_h << hash_shift ^ window[strstart +
1153 MIN_MATCH - 1] & 0xff) &
1154 hash_mask;
1155
1156 hash_head = head[ins_h] & 0xffff;
1157 prev[strstart & w_mask] = head[ins_h];
1158 head[ins_h] = (short) strstart;
1159 }
1160 } while (-- prev_length != 0);
1161 match_available = 0;
1162 match_length = MIN_MATCH - 1;
1163 strstart ++;
1164
1165 if (bflush) {
1166 flush_block_only(false);
1167 if (strm.avail_out == 0) {
1168 return NeedMore;
1169 }
1170 }
1171 } else if (match_available != 0) {
1172
1173
1174
1175
1176
1177 bflush = _tr_tally(0, window[strstart - 1] & 0xff);
1178
1179 if (bflush) {
1180 flush_block_only(false);
1181 }
1182 strstart ++;
1183 lookahead --;
1184 if (strm.avail_out == 0) {
1185 return NeedMore;
1186 }
1187 } else {
1188
1189
1190
1191 match_available = 1;
1192 strstart ++;
1193 lookahead --;
1194 }
1195 }
1196
1197 if (match_available != 0) {
1198 _tr_tally(0, window[strstart - 1] & 0xff);
1199 match_available = 0;
1200 }
1201 flush_block_only(flush == JZlib.Z_FINISH);
1202
1203 if (strm.avail_out == 0) {
1204 if (flush == JZlib.Z_FINISH) {
1205 return FinishStarted;
1206 } else {
1207 return NeedMore;
1208 }
1209 }
1210
1211 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
1212 }
1213
1214 private int longest_match(int cur_match) {
1215 int chain_length = max_chain_length;
1216 int scan = strstart;
1217 int match;
1218 int len;
1219 int best_len = prev_length;
1220 int limit = strstart > w_size - MIN_LOOKAHEAD? strstart -
1221 (w_size - MIN_LOOKAHEAD) : 0;
1222 int nice_match = this.nice_match;
1223
1224
1225
1226
1227 int wmask = w_mask;
1228
1229 int strend = strstart + MAX_MATCH;
1230 byte scan_end1 = window[scan + best_len - 1];
1231 byte scan_end = window[scan + best_len];
1232
1233
1234
1235
1236
1237 if (prev_length >= good_match) {
1238 chain_length >>= 2;
1239 }
1240
1241
1242
1243 if (nice_match > lookahead) {
1244 nice_match = lookahead;
1245 }
1246
1247 do {
1248 match = cur_match;
1249
1250
1251
1252 if (window[match + best_len] != scan_end ||
1253 window[match + best_len - 1] != scan_end1 ||
1254 window[match] != window[scan] ||
1255 window[++ match] != window[scan + 1]) {
1256 continue;
1257 }
1258
1259
1260
1261
1262
1263
1264 scan += 2;
1265 match ++;
1266
1267
1268
1269 while (window[++ scan] == window[++ match] &&
1270 window[++ scan] == window[++ match] &&
1271 window[++ scan] == window[++ match] &&
1272 window[++ scan] == window[++ match] &&
1273 window[++ scan] == window[++ match] &&
1274 window[++ scan] == window[++ match] &&
1275 window[++ scan] == window[++ match] &&
1276 window[++ scan] == window[++ match] && scan < strend) {
1277 continue;
1278 }
1279
1280 len = MAX_MATCH - (strend - scan);
1281 scan = strend - MAX_MATCH;
1282
1283 if (len > best_len) {
1284 match_start = cur_match;
1285 best_len = len;
1286 if (len >= nice_match) {
1287 break;
1288 }
1289 scan_end1 = window[scan + best_len - 1];
1290 scan_end = window[scan + best_len];
1291 }
1292
1293 } while ((cur_match = prev[cur_match & wmask] & 0xffff) > limit &&
1294 -- chain_length != 0);
1295
1296 if (best_len <= lookahead) {
1297 return best_len;
1298 }
1299 return lookahead;
1300 }
1301
1302 int deflateInit(ZStream strm, int level, int bits, WrapperType wrapperType) {
1303 return deflateInit2(strm, level, JZlib.Z_DEFLATED, bits,
1304 JZlib.DEF_MEM_LEVEL, JZlib.Z_DEFAULT_STRATEGY, wrapperType);
1305 }
1306
1307 private int deflateInit2(ZStream strm, int level, int method, int windowBits,
1308 int memLevel, int strategy, WrapperType wrapperType) {
1309
1310 if (wrapperType == WrapperType.ZLIB_OR_NONE) {
1311 throw new IllegalArgumentException("ZLIB_OR_NONE allowed only for inflate");
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 strm.msg = null;
1323
1324 if (level == JZlib.Z_DEFAULT_COMPRESSION) {
1325 level = 6;
1326 }
1327
1328 if (windowBits < 0) {
1329 throw new IllegalArgumentException("windowBits: " + windowBits);
1330 }
1331
1332 if (memLevel < 1 || memLevel > JZlib.MAX_MEM_LEVEL ||
1333 method != JZlib.Z_DEFLATED || windowBits < 9 ||
1334 windowBits > 15 || level < 0 || level > 9 || strategy < 0 ||
1335 strategy > JZlib.Z_HUFFMAN_ONLY) {
1336 return JZlib.Z_STREAM_ERROR;
1337 }
1338
1339 strm.dstate = this;
1340
1341 this.wrapperType = wrapperType;
1342 w_bits = windowBits;
1343 w_size = 1 << w_bits;
1344 w_mask = w_size - 1;
1345
1346 hash_bits = memLevel + 7;
1347 hash_size = 1 << hash_bits;
1348 hash_mask = hash_size - 1;
1349 hash_shift = (hash_bits + MIN_MATCH - 1) / MIN_MATCH;
1350
1351 window = new byte[w_size * 2];
1352 prev = new short[w_size];
1353 head = new short[hash_size];
1354
1355 lit_bufsize = 1 << memLevel + 6;
1356
1357
1358
1359 pending_buf = new byte[lit_bufsize * 4];
1360 pending_buf_size = lit_bufsize * 4;
1361
1362 d_buf = lit_bufsize / 2;
1363 l_buf = (1 + 2) * lit_bufsize;
1364
1365 this.level = level;
1366
1367
1368
1369 this.strategy = strategy;
1370
1371 return deflateReset(strm);
1372 }
1373
1374 private int deflateReset(ZStream strm) {
1375 strm.total_in = strm.total_out = 0;
1376 strm.msg = null;
1377
1378 pending = 0;
1379 pending_out = 0;
1380
1381 wroteTrailer = false;
1382 status = wrapperType == WrapperType.NONE? BUSY_STATE : INIT_STATE;
1383 strm.adler = Adler32.adler32(0, null, 0, 0);
1384 strm.crc32 = 0;
1385 gzipUncompressedBytes = 0;
1386
1387 last_flush = JZlib.Z_NO_FLUSH;
1388
1389 tr_init();
1390 lm_init();
1391 return JZlib.Z_OK;
1392 }
1393
1394 int deflateEnd() {
1395 if (status != INIT_STATE && status != BUSY_STATE &&
1396 status != FINISH_STATE) {
1397 return JZlib.Z_STREAM_ERROR;
1398 }
1399
1400 pending_buf = null;
1401 head = null;
1402 prev = null;
1403 window = null;
1404
1405
1406 return status == BUSY_STATE? JZlib.Z_DATA_ERROR : JZlib.Z_OK;
1407 }
1408
1409 int deflateParams(ZStream strm, int _level, int _strategy) {
1410 int err = JZlib.Z_OK;
1411
1412 if (_level == JZlib.Z_DEFAULT_COMPRESSION) {
1413 _level = 6;
1414 }
1415 if (_level < 0 || _level > 9 || _strategy < 0 ||
1416 _strategy > JZlib.Z_HUFFMAN_ONLY) {
1417 return JZlib.Z_STREAM_ERROR;
1418 }
1419
1420 if (config_table[level].func != config_table[_level].func &&
1421 strm.total_in != 0) {
1422
1423 err = strm.deflate(JZlib.Z_PARTIAL_FLUSH);
1424 }
1425
1426 if (level != _level) {
1427 level = _level;
1428 max_lazy_match = config_table[level].max_lazy;
1429 good_match = config_table[level].good_length;
1430 nice_match = config_table[level].nice_length;
1431 max_chain_length = config_table[level].max_chain;
1432 }
1433 strategy = _strategy;
1434 return err;
1435 }
1436
1437 int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) {
1438 int length = dictLength;
1439 int index = 0;
1440
1441 if (dictionary == null || status != INIT_STATE) {
1442 return JZlib.Z_STREAM_ERROR;
1443 }
1444
1445 strm.adler = Adler32.adler32(strm.adler, dictionary, 0, dictLength);
1446
1447 if (length < MIN_MATCH) {
1448 return JZlib.Z_OK;
1449 }
1450 if (length > w_size - MIN_LOOKAHEAD) {
1451 length = w_size - MIN_LOOKAHEAD;
1452 index = dictLength - length;
1453 }
1454 System.arraycopy(dictionary, index, window, 0, length);
1455 strstart = length;
1456 block_start = length;
1457
1458
1459
1460
1461
1462 ins_h = window[0] & 0xff;
1463 ins_h = (ins_h << hash_shift ^ window[1] & 0xff) & hash_mask;
1464
1465 for (int n = 0; n <= length - MIN_MATCH; n ++) {
1466 ins_h = (ins_h << hash_shift ^ window[n + MIN_MATCH - 1] & 0xff) &
1467 hash_mask;
1468 prev[n & w_mask] = head[ins_h];
1469 head[ins_h] = (short) n;
1470 }
1471 return JZlib.Z_OK;
1472 }
1473
1474 int deflate(ZStream strm, int flush) {
1475 int old_flush;
1476
1477 if (flush > JZlib.Z_FINISH || flush < 0) {
1478 return JZlib.Z_STREAM_ERROR;
1479 }
1480
1481 if (strm.next_out == null || strm.next_in == null &&
1482 strm.avail_in != 0 || status == FINISH_STATE &&
1483 flush != JZlib.Z_FINISH) {
1484 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_STREAM_ERROR];
1485 return JZlib.Z_STREAM_ERROR;
1486 }
1487 if (strm.avail_out == 0) {
1488 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1489 return JZlib.Z_BUF_ERROR;
1490 }
1491
1492 this.strm = strm;
1493 old_flush = last_flush;
1494 last_flush = flush;
1495
1496
1497 if (status == INIT_STATE) {
1498 switch (wrapperType) {
1499 case ZLIB:
1500 int header = JZlib.Z_DEFLATED + (w_bits - 8 << 4) << 8;
1501 int level_flags = (level - 1 & 0xff) >> 1;
1502
1503 if (level_flags > 3) {
1504 level_flags = 3;
1505 }
1506 header |= level_flags << 6;
1507 if (strstart != 0) {
1508 header |= JZlib.PRESET_DICT;
1509 }
1510 header += 31 - header % 31;
1511
1512 putShortMSB(header);
1513
1514
1515 if (strstart != 0) {
1516 putShortMSB((int) (strm.adler >>> 16));
1517 putShortMSB((int) (strm.adler & 0xffff));
1518 }
1519 strm.adler = Adler32.adler32(0, null, 0, 0);
1520 break;
1521 case GZIP:
1522
1523 put_byte((byte) 0x1f);
1524 put_byte((byte) 0x8b);
1525
1526 put_byte((byte) 8);
1527
1528 put_byte((byte) 0);
1529
1530 put_byte((byte) 0);
1531 put_byte((byte) 0);
1532 put_byte((byte) 0);
1533 put_byte((byte) 0);
1534
1535 switch (config_table[level].func) {
1536 case FAST:
1537 put_byte((byte) 4);
1538 break;
1539 case SLOW:
1540 put_byte((byte) 2);
1541 break;
1542 default:
1543 put_byte((byte) 0);
1544 break;
1545 }
1546
1547 put_byte((byte) 255);
1548
1549 strm.crc32 = 0;
1550 break;
1551 }
1552
1553 status = BUSY_STATE;
1554 }
1555
1556
1557 if (pending != 0) {
1558 strm.flush_pending();
1559 if (strm.avail_out == 0) {
1560
1561
1562
1563
1564
1565
1566 last_flush = -1;
1567 return JZlib.Z_OK;
1568 }
1569
1570
1571
1572
1573 } else if (strm.avail_in == 0 && flush <= old_flush &&
1574 flush != JZlib.Z_FINISH) {
1575 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1576 return JZlib.Z_BUF_ERROR;
1577 }
1578
1579
1580 if (status == FINISH_STATE && strm.avail_in != 0) {
1581 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1582 return JZlib.Z_BUF_ERROR;
1583 }
1584
1585
1586 int old_next_in_index = strm.next_in_index;
1587 try {
1588 if (strm.avail_in != 0 || lookahead != 0 || flush != JZlib.Z_NO_FLUSH &&
1589 status != FINISH_STATE) {
1590 int bstate = -1;
1591 switch (config_table[level].func) {
1592 case STORED:
1593 bstate = deflate_stored(flush);
1594 break;
1595 case FAST:
1596 bstate = deflate_fast(flush);
1597 break;
1598 case SLOW:
1599 bstate = deflate_slow(flush);
1600 break;
1601 default:
1602 }
1603
1604 if (bstate == FinishStarted || bstate == FinishDone) {
1605 status = FINISH_STATE;
1606 }
1607 if (bstate == NeedMore || bstate == FinishStarted) {
1608 if (strm.avail_out == 0) {
1609 last_flush = -1;
1610 }
1611 return JZlib.Z_OK;
1612
1613
1614
1615
1616
1617
1618 }
1619
1620 if (bstate == BlockDone) {
1621 if (flush == JZlib.Z_PARTIAL_FLUSH) {
1622 _tr_align();
1623 } else {
1624 _tr_stored_block(0, 0, false);
1625
1626
1627 if (flush == JZlib.Z_FULL_FLUSH) {
1628
1629 for (int i = 0; i < hash_size
1630 head[i] = 0;
1631 }
1632 }
1633 }
1634 strm.flush_pending();
1635 if (strm.avail_out == 0) {
1636 last_flush = -1;
1637 return JZlib.Z_OK;
1638 }
1639 }
1640 }
1641 } finally {
1642 gzipUncompressedBytes += strm.next_in_index - old_next_in_index;
1643 }
1644
1645 if (flush != JZlib.Z_FINISH) {
1646 return JZlib.Z_OK;
1647 }
1648
1649 if (wrapperType == WrapperType.NONE || wroteTrailer) {
1650 return JZlib.Z_STREAM_END;
1651 }
1652
1653 switch (wrapperType) {
1654 case ZLIB:
1655
1656 putShortMSB((int) (strm.adler >>> 16));
1657 putShortMSB((int) (strm.adler & 0xffff));
1658 break;
1659 case GZIP:
1660
1661 put_byte((byte) (strm.crc32 & 0xFF));
1662 put_byte((byte) (strm.crc32 >>> 8 & 0xFF));
1663 put_byte((byte) (strm.crc32 >>> 16 & 0xFF));
1664 put_byte((byte) (strm.crc32 >>> 24 & 0xFF));
1665 put_byte((byte) (gzipUncompressedBytes & 0xFF));
1666 put_byte((byte) (gzipUncompressedBytes >>> 8 & 0xFF));
1667 put_byte((byte) (gzipUncompressedBytes >>> 16 & 0xFF));
1668 put_byte((byte) (gzipUncompressedBytes >>> 24 & 0xFF));
1669 break;
1670 }
1671
1672 strm.flush_pending();
1673
1674
1675 wroteTrailer = true;
1676 return pending != 0? JZlib.Z_OK : JZlib.Z_STREAM_END;
1677 }
1678 }