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