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
1311
1312
1313
1314
1315
1316
1317 strm.msg = null;
1318
1319 if (level == JZlib.Z_DEFAULT_COMPRESSION) {
1320 level = 6;
1321 }
1322
1323 if (windowBits < 0) {
1324 throw new IllegalArgumentException("windowBits: " + windowBits);
1325 }
1326
1327 if (memLevel < 1 || memLevel > JZlib.MAX_MEM_LEVEL ||
1328 method != JZlib.Z_DEFLATED || windowBits < 9 ||
1329 windowBits > 15 || level < 0 || level > 9 || strategy < 0 ||
1330 strategy > JZlib.Z_HUFFMAN_ONLY) {
1331 return JZlib.Z_STREAM_ERROR;
1332 }
1333
1334 strm.dstate = this;
1335
1336 this.wrapperType = wrapperType;
1337 w_bits = windowBits;
1338 w_size = 1 << w_bits;
1339 w_mask = w_size - 1;
1340
1341 hash_bits = memLevel + 7;
1342 hash_size = 1 << hash_bits;
1343 hash_mask = hash_size - 1;
1344 hash_shift = (hash_bits + MIN_MATCH - 1) / MIN_MATCH;
1345
1346 window = new byte[w_size * 2];
1347 prev = new short[w_size];
1348 head = new short[hash_size];
1349
1350 lit_bufsize = 1 << memLevel + 6;
1351
1352
1353
1354 pending_buf = new byte[lit_bufsize * 4];
1355 pending_buf_size = lit_bufsize * 4;
1356
1357 d_buf = lit_bufsize / 2;
1358 l_buf = (1 + 2) * lit_bufsize;
1359
1360 this.level = level;
1361
1362
1363
1364 this.strategy = strategy;
1365
1366 return deflateReset(strm);
1367 }
1368
1369 private int deflateReset(ZStream strm) {
1370 strm.total_in = strm.total_out = 0;
1371 strm.msg = null;
1372
1373 pending = 0;
1374 pending_out = 0;
1375
1376 wroteTrailer = false;
1377 status = wrapperType == WrapperType.NONE? BUSY_STATE : INIT_STATE;
1378 strm.adler = Adler32.adler32(0, null, 0, 0);
1379 strm.crc32 = 0;
1380 gzipUncompressedBytes = 0;
1381
1382 last_flush = JZlib.Z_NO_FLUSH;
1383
1384 tr_init();
1385 lm_init();
1386 return JZlib.Z_OK;
1387 }
1388
1389 int deflateEnd() {
1390 if (status != INIT_STATE && status != BUSY_STATE &&
1391 status != FINISH_STATE) {
1392 return JZlib.Z_STREAM_ERROR;
1393 }
1394
1395 pending_buf = null;
1396 head = null;
1397 prev = null;
1398 window = null;
1399
1400
1401 return status == BUSY_STATE? JZlib.Z_DATA_ERROR : JZlib.Z_OK;
1402 }
1403
1404 int deflateParams(ZStream strm, int _level, int _strategy) {
1405 int err = JZlib.Z_OK;
1406
1407 if (_level == JZlib.Z_DEFAULT_COMPRESSION) {
1408 _level = 6;
1409 }
1410 if (_level < 0 || _level > 9 || _strategy < 0 ||
1411 _strategy > JZlib.Z_HUFFMAN_ONLY) {
1412 return JZlib.Z_STREAM_ERROR;
1413 }
1414
1415 if (config_table[level].func != config_table[_level].func &&
1416 strm.total_in != 0) {
1417
1418 err = strm.deflate(JZlib.Z_PARTIAL_FLUSH);
1419 }
1420
1421 if (level != _level) {
1422 level = _level;
1423 max_lazy_match = config_table[level].max_lazy;
1424 good_match = config_table[level].good_length;
1425 nice_match = config_table[level].nice_length;
1426 max_chain_length = config_table[level].max_chain;
1427 }
1428 strategy = _strategy;
1429 return err;
1430 }
1431
1432 int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) {
1433 int length = dictLength;
1434 int index = 0;
1435
1436 if (dictionary == null || status != INIT_STATE) {
1437 return JZlib.Z_STREAM_ERROR;
1438 }
1439
1440 strm.adler = Adler32.adler32(strm.adler, dictionary, 0, dictLength);
1441
1442 if (length < MIN_MATCH) {
1443 return JZlib.Z_OK;
1444 }
1445 if (length > w_size - MIN_LOOKAHEAD) {
1446 length = w_size - MIN_LOOKAHEAD;
1447 index = dictLength - length;
1448 }
1449 System.arraycopy(dictionary, index, window, 0, length);
1450 strstart = length;
1451 block_start = length;
1452
1453
1454
1455
1456
1457 ins_h = window[0] & 0xff;
1458 ins_h = (ins_h << hash_shift ^ window[1] & 0xff) & hash_mask;
1459
1460 for (int n = 0; n <= length - MIN_MATCH; n ++) {
1461 ins_h = (ins_h << hash_shift ^ window[n + MIN_MATCH - 1] & 0xff) &
1462 hash_mask;
1463 prev[n & w_mask] = head[ins_h];
1464 head[ins_h] = (short) n;
1465 }
1466 return JZlib.Z_OK;
1467 }
1468
1469 int deflate(ZStream strm, int flush) {
1470 int old_flush;
1471
1472 if (flush > JZlib.Z_FINISH || flush < 0) {
1473 return JZlib.Z_STREAM_ERROR;
1474 }
1475
1476 if (strm.next_out == null || strm.next_in == null &&
1477 strm.avail_in != 0 || status == FINISH_STATE &&
1478 flush != JZlib.Z_FINISH) {
1479 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_STREAM_ERROR];
1480 return JZlib.Z_STREAM_ERROR;
1481 }
1482 if (strm.avail_out == 0) {
1483 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1484 return JZlib.Z_BUF_ERROR;
1485 }
1486
1487 this.strm = strm;
1488 old_flush = last_flush;
1489 last_flush = flush;
1490
1491
1492 if (status == INIT_STATE) {
1493 switch (wrapperType) {
1494 case ZLIB:
1495 int header = JZlib.Z_DEFLATED + (w_bits - 8 << 4) << 8;
1496 int level_flags = (level - 1 & 0xff) >> 1;
1497
1498 if (level_flags > 3) {
1499 level_flags = 3;
1500 }
1501 header |= level_flags << 6;
1502 if (strstart != 0) {
1503 header |= JZlib.PRESET_DICT;
1504 }
1505 header += 31 - header % 31;
1506
1507 putShortMSB(header);
1508
1509
1510 if (strstart != 0) {
1511 putShortMSB((int) (strm.adler >>> 16));
1512 putShortMSB((int) (strm.adler & 0xffff));
1513 }
1514 strm.adler = Adler32.adler32(0, null, 0, 0);
1515 break;
1516 case GZIP:
1517
1518 put_byte((byte) 0x1f);
1519 put_byte((byte) 0x8b);
1520
1521 put_byte((byte) 8);
1522
1523 put_byte((byte) 0);
1524
1525 put_byte((byte) 0);
1526 put_byte((byte) 0);
1527 put_byte((byte) 0);
1528 put_byte((byte) 0);
1529
1530 switch (config_table[level].func) {
1531 case FAST:
1532 put_byte((byte) 4);
1533 break;
1534 case SLOW:
1535 put_byte((byte) 2);
1536 break;
1537 default:
1538 put_byte((byte) 0);
1539 break;
1540 }
1541
1542 put_byte((byte) 255);
1543
1544 strm.crc32 = 0;
1545 break;
1546 }
1547
1548 status = BUSY_STATE;
1549 }
1550
1551
1552 if (pending != 0) {
1553 strm.flush_pending();
1554 if (strm.avail_out == 0) {
1555
1556
1557
1558
1559
1560
1561 last_flush = -1;
1562 return JZlib.Z_OK;
1563 }
1564
1565
1566
1567
1568 } else if (strm.avail_in == 0 && flush <= old_flush &&
1569 flush != JZlib.Z_FINISH) {
1570 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1571 return JZlib.Z_BUF_ERROR;
1572 }
1573
1574
1575 if (status == FINISH_STATE && strm.avail_in != 0) {
1576 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1577 return JZlib.Z_BUF_ERROR;
1578 }
1579
1580
1581 int old_next_in_index = strm.next_in_index;
1582 try {
1583 if (strm.avail_in != 0 || lookahead != 0 || flush != JZlib.Z_NO_FLUSH &&
1584 status != FINISH_STATE) {
1585 int bstate = -1;
1586 switch (config_table[level].func) {
1587 case STORED:
1588 bstate = deflate_stored(flush);
1589 break;
1590 case FAST:
1591 bstate = deflate_fast(flush);
1592 break;
1593 case SLOW:
1594 bstate = deflate_slow(flush);
1595 break;
1596 default:
1597 }
1598
1599 if (bstate == FinishStarted || bstate == FinishDone) {
1600 status = FINISH_STATE;
1601 }
1602 if (bstate == NeedMore || bstate == FinishStarted) {
1603 if (strm.avail_out == 0) {
1604 last_flush = -1;
1605 }
1606 return JZlib.Z_OK;
1607
1608
1609
1610
1611
1612
1613 }
1614
1615 if (bstate == BlockDone) {
1616 if (flush == JZlib.Z_PARTIAL_FLUSH) {
1617 _tr_align();
1618 } else {
1619 _tr_stored_block(0, 0, false);
1620
1621
1622 if (flush == JZlib.Z_FULL_FLUSH) {
1623
1624 for (int i = 0; i < hash_size
1625 head[i] = 0;
1626 }
1627 }
1628 }
1629 strm.flush_pending();
1630 if (strm.avail_out == 0) {
1631 last_flush = -1;
1632 return JZlib.Z_OK;
1633 }
1634 }
1635 }
1636 } finally {
1637 gzipUncompressedBytes += strm.next_in_index - old_next_in_index;
1638 }
1639
1640 if (flush != JZlib.Z_FINISH) {
1641 return JZlib.Z_OK;
1642 }
1643
1644 if (wrapperType == WrapperType.NONE || wroteTrailer) {
1645 return JZlib.Z_STREAM_END;
1646 }
1647
1648 switch (wrapperType) {
1649 case ZLIB:
1650
1651 putShortMSB((int) (strm.adler >>> 16));
1652 putShortMSB((int) (strm.adler & 0xffff));
1653 break;
1654 case GZIP:
1655
1656 put_byte((byte) (strm.crc32 & 0xFF));
1657 put_byte((byte) (strm.crc32 >>> 8 & 0xFF));
1658 put_byte((byte) (strm.crc32 >>> 16 & 0xFF));
1659 put_byte((byte) (strm.crc32 >>> 24 & 0xFF));
1660 put_byte((byte) (gzipUncompressedBytes & 0xFF));
1661 put_byte((byte) (gzipUncompressedBytes >>> 8 & 0xFF));
1662 put_byte((byte) (gzipUncompressedBytes >>> 16 & 0xFF));
1663 put_byte((byte) (gzipUncompressedBytes >>> 24 & 0xFF));
1664 break;
1665 }
1666
1667 strm.flush_pending();
1668
1669
1670 wroteTrailer = true;
1671 return pending != 0? JZlib.Z_OK : JZlib.Z_STREAM_END;
1672 }
1673 }