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 final short[] dyn_ltree;
198 final short[] dyn_dtree;
199 final short[] bl_tree;
200 final Tree l_desc = new Tree();
201 final Tree d_desc = new Tree();
202 final Tree bl_desc = new Tree();
203
204 final short[] bl_count = new short[JZlib.MAX_BITS + 1];
205
206 final int[] heap = new int[2 * JZlib.L_CODES + 1];
207 int heap_len;
208 int heap_max;
209
210
211
212 final 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[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 }
368 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[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 }
463 if (count < min_count) {
464 do {
465 send_code(curlen, bl_tree);
466 } while (-- count != 0);
467 } else if (curlen != 0) {
468 if (curlen != prevlen) {
469 send_code(curlen, bl_tree);
470 count --;
471 }
472 send_code(REP_3_6, bl_tree);
473 send_bits(count - 3, 2);
474 } else if (count <= 10) {
475 send_code(REPZ_3_10, bl_tree);
476 send_bits(count - 3, 3);
477 } else {
478 send_code(REPZ_11_138, bl_tree);
479 send_bits(count - 11, 7);
480 }
481 count = 0;
482 prevlen = curlen;
483 if (nextlen == 0) {
484 max_count = 138;
485 min_count = 3;
486 } else if (curlen == nextlen) {
487 max_count = 6;
488 min_count = 3;
489 } else {
490 max_count = 7;
491 min_count = 4;
492 }
493 }
494 }
495
496
497
498 private void put_byte(byte[] p, int start, int len) {
499 System.arraycopy(p, start, pending_buf, pending, len);
500 pending += len;
501 }
502
503 private void put_byte(byte c) {
504 pending_buf[pending ++] = c;
505 }
506
507 private void put_short(int w) {
508 put_byte((byte) w);
509 put_byte((byte) (w >>> 8));
510 }
511
512 private void putShortMSB(int b) {
513 put_byte((byte) (b >> 8));
514 put_byte((byte) b);
515 }
516
517 private void send_code(int c, short[] tree) {
518 int c2 = c * 2;
519 send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
520 }
521
522 private void send_bits(int value, int length) {
523 int len = length;
524 if (bi_valid > Buf_size - len) {
525 int val = value;
526
527 bi_buf |= val << bi_valid & 0xffff;
528 put_short(bi_buf);
529 bi_buf = (short) (val >>> Buf_size - bi_valid);
530 bi_valid += len - Buf_size;
531 } else {
532
533 bi_buf |= value << bi_valid & 0xffff;
534 bi_valid += len;
535 }
536 }
537
538
539
540
541
542
543
544
545
546
547 private void _tr_align() {
548 send_bits(STATIC_TREES << 1, 3);
549 send_code(END_BLOCK, StaticTree.static_ltree);
550
551 bi_flush();
552
553
554
555
556
557 if (1 + last_eob_len + 10 - bi_valid < 9) {
558 send_bits(STATIC_TREES << 1, 3);
559 send_code(END_BLOCK, StaticTree.static_ltree);
560 bi_flush();
561 }
562 last_eob_len = 7;
563 }
564
565
566
567 private boolean _tr_tally(int dist,
568 int lc
569 ) {
570
571 pending_buf[d_buf + last_lit * 2] = (byte) (dist >>> 8);
572 pending_buf[d_buf + last_lit * 2 + 1] = (byte) dist;
573
574 pending_buf[l_buf + last_lit] = (byte) lc;
575 last_lit ++;
576
577 if (dist == 0) {
578
579 dyn_ltree[lc * 2] ++;
580 } else {
581 matches ++;
582
583 dist --;
584 dyn_ltree[(Tree._length_code[lc] + JZlib.LITERALS + 1) * 2] ++;
585 dyn_dtree[Tree.d_code(dist) * 2] ++;
586 }
587
588 if ((last_lit & 0x1fff) == 0 && level > 2) {
589
590 int out_length = last_lit * 8;
591 int in_length = strstart - block_start;
592 int dcode;
593 for (dcode = 0; dcode < JZlib.D_CODES; dcode ++) {
594 out_length += dyn_dtree[dcode * 2] *
595 (5L + Tree.extra_dbits[dcode]);
596 }
597 out_length >>>= 3;
598 if (matches < last_lit / 2 && out_length < in_length / 2) {
599 return true;
600 }
601 }
602
603 return last_lit == lit_bufsize - 1;
604
605
606
607 }
608
609
610 private void compress_block(short[] ltree, short[] dtree) {
611 int dist;
612 int lc;
613 int lx = 0;
614 int code;
615 int extra;
616
617 if (last_lit != 0) {
618 do {
619 dist = pending_buf[d_buf + lx * 2] << 8 & 0xff00 |
620 pending_buf[d_buf + lx * 2 + 1] & 0xff;
621 lc = pending_buf[l_buf + lx] & 0xff;
622 lx ++;
623
624 if (dist == 0) {
625 send_code(lc, ltree);
626 } else {
627
628 code = Tree._length_code[lc];
629
630 send_code(code + JZlib.LITERALS + 1, ltree);
631 extra = Tree.extra_lbits[code];
632 if (extra != 0) {
633 lc -= Tree.base_length[code];
634 send_bits(lc, extra);
635 }
636 dist --;
637 code = Tree.d_code(dist);
638
639 send_code(code, dtree);
640 extra = Tree.extra_dbits[code];
641 if (extra != 0) {
642 dist -= Tree.base_dist[code];
643 send_bits(dist, extra);
644 }
645 }
646
647
648 } while (lx < last_lit);
649 }
650
651 send_code(END_BLOCK, ltree);
652 last_eob_len = ltree[END_BLOCK * 2 + 1];
653 }
654
655
656
657
658
659 private void set_data_type() {
660 int n = 0;
661 int ascii_freq = 0;
662 int bin_freq = 0;
663 while (n < 7) {
664 bin_freq += dyn_ltree[n * 2];
665 n ++;
666 }
667 while (n < 128) {
668 ascii_freq += dyn_ltree[n * 2];
669 n ++;
670 }
671 while (n < JZlib.LITERALS) {
672 bin_freq += dyn_ltree[n * 2];
673 n ++;
674 }
675 data_type = (byte) (bin_freq > ascii_freq >>> 2? Z_BINARY : Z_ASCII);
676 }
677
678
679 private void bi_flush() {
680 if (bi_valid == 16) {
681 put_short(bi_buf);
682 bi_buf = 0;
683 bi_valid = 0;
684 } else if (bi_valid >= 8) {
685 put_byte((byte) bi_buf);
686 bi_buf >>>= 8;
687 bi_valid -= 8;
688 }
689 }
690
691
692 private void bi_windup() {
693 if (bi_valid > 8) {
694 put_short(bi_buf);
695 } else if (bi_valid > 0) {
696 put_byte((byte) bi_buf);
697 }
698 bi_buf = 0;
699 bi_valid = 0;
700 }
701
702
703
704 private void copy_block(int buf,
705 int len,
706 boolean header
707 ) {
708 bi_windup();
709 last_eob_len = 8;
710
711 if (header) {
712 put_short((short) len);
713 put_short((short) ~len);
714 }
715
716
717
718
719
720 put_byte(window, buf, len);
721 }
722
723 private void flush_block_only(boolean eof) {
724 _tr_flush_block(block_start >= 0? block_start : -1, strstart -
725 block_start, eof);
726 block_start = strstart;
727 strm.flush_pending();
728 }
729
730
731
732
733
734
735
736
737 private int deflate_stored(int flush) {
738
739
740
741 int max_block_size = 0xffff;
742 int max_start;
743
744 if (max_block_size > pending_buf_size - 5) {
745 max_block_size = pending_buf_size - 5;
746 }
747
748
749 while (true) {
750
751 if (lookahead <= 1) {
752 fill_window();
753 if (lookahead == 0 && flush == JZlib.Z_NO_FLUSH) {
754 return NeedMore;
755 }
756 if (lookahead == 0) {
757 break;
758 }
759 }
760
761 strstart += lookahead;
762 lookahead = 0;
763
764
765 max_start = block_start + max_block_size;
766 if (strstart == 0 || strstart >= max_start) {
767
768 lookahead = strstart - max_start;
769 strstart = max_start;
770
771 flush_block_only(false);
772 if (strm.avail_out == 0) {
773 return NeedMore;
774 }
775
776 }
777
778
779
780 if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
781 flush_block_only(false);
782 if (strm.avail_out == 0) {
783 return NeedMore;
784 }
785 }
786 }
787
788 flush_block_only(flush == JZlib.Z_FINISH);
789 if (strm.avail_out == 0) {
790 return flush == JZlib.Z_FINISH? FinishStarted : NeedMore;
791 }
792
793 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
794 }
795
796
797 private void _tr_stored_block(int buf,
798 int stored_len,
799 boolean eof
800 ) {
801
802 send_bits((STORED_BLOCK << 1) + (eof? 1 : 0), 3);
803 copy_block(buf, stored_len, true);
804 }
805
806
807
808 private void _tr_flush_block(int buf,
809 int stored_len,
810 boolean eof
811 ) {
812 int opt_lenb, static_lenb;
813 int max_blindex = 0;
814
815
816 if (level > 0) {
817
818 if (data_type == Z_UNKNOWN) {
819 set_data_type();
820 }
821
822
823 l_desc.build_tree(this);
824
825 d_desc.build_tree(this);
826
827
828
829
830
831
832 max_blindex = build_bl_tree();
833
834
835 opt_lenb = opt_len + 3 + 7 >>> 3;
836 static_lenb = static_len + 3 + 7 >>> 3;
837
838 if (static_lenb <= opt_lenb) {
839 opt_lenb = static_lenb;
840 }
841 } else {
842 opt_lenb = static_lenb = stored_len + 5;
843 }
844
845 if (stored_len + 4 <= opt_lenb && buf != -1) {
846
847
848
849
850
851
852 _tr_stored_block(buf, stored_len, eof);
853 } else if (static_lenb == opt_lenb) {
854 send_bits((STATIC_TREES << 1) + (eof? 1 : 0), 3);
855 compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
856 } else {
857 send_bits((DYN_TREES << 1) + (eof? 1 : 0), 3);
858 send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1,
859 max_blindex + 1);
860 compress_block(dyn_ltree, dyn_dtree);
861 }
862
863
864
865
866 init_block();
867
868 if (eof) {
869 bi_windup();
870 }
871 }
872
873
874
875
876
877
878
879
880
881 private void fill_window() {
882 int n, m;
883 int p;
884 int more;
885
886 do {
887 more = window_size - lookahead - strstart;
888
889
890 if (more == 0 && strstart == 0 && lookahead == 0) {
891 more = w_size;
892 } else if (more == -1) {
893
894
895 more --;
896
897
898
899 } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
900 System.arraycopy(window, w_size, window, 0, w_size);
901 match_start -= w_size;
902 strstart -= w_size;
903 block_start -= w_size;
904
905
906
907
908
909
910
911 n = hash_size;
912 p = n;
913 do {
914 m = head[-- p] & 0xffff;
915 head[p] = m >= w_size? (short) (m - w_size) : 0;
916 } while (-- n != 0);
917
918 n = w_size;
919 p = n;
920 do {
921 m = prev[-- p] & 0xffff;
922 prev[p] = m >= w_size? (short) (m - w_size) : 0;
923
924
925 } while (-- n != 0);
926 more += w_size;
927 }
928
929 if (strm.avail_in == 0) {
930 return;
931 }
932
933
934
935
936
937
938
939
940
941
942
943
944 n = strm.read_buf(window, strstart + lookahead, more);
945 lookahead += n;
946
947
948 if (lookahead >= MIN_MATCH) {
949 ins_h = window[strstart] & 0xff;
950 ins_h = (ins_h << hash_shift ^ window[strstart + 1] & 0xff) &
951 hash_mask;
952 }
953
954
955 } while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0);
956 }
957
958
959
960
961
962
963 private int deflate_fast(int flush) {
964
965 int hash_head = 0;
966 boolean bflush;
967
968 while (true) {
969
970
971
972
973 if (lookahead < MIN_LOOKAHEAD) {
974 fill_window();
975 if (lookahead < MIN_LOOKAHEAD && flush == JZlib.Z_NO_FLUSH) {
976 return NeedMore;
977 }
978 if (lookahead == 0) {
979 break;
980 }
981 }
982
983
984
985 if (lookahead >= MIN_MATCH) {
986 ins_h = (ins_h << hash_shift ^ window[strstart + MIN_MATCH - 1] & 0xff) &
987 hash_mask;
988
989
990 hash_head = head[ins_h] & 0xffff;
991 prev[strstart & w_mask] = head[ins_h];
992 head[ins_h] = (short) strstart;
993 }
994
995
996
997
998 if (hash_head != 0L &&
999 (strstart - hash_head & 0xffff) <= w_size - MIN_LOOKAHEAD) {
1000
1001
1002
1003 if (strategy != JZlib.Z_HUFFMAN_ONLY) {
1004 match_length = longest_match(hash_head);
1005 }
1006
1007 }
1008 if (match_length >= MIN_MATCH) {
1009
1010
1011 bflush = _tr_tally(strstart - match_start, match_length -
1012 MIN_MATCH);
1013
1014 lookahead -= match_length;
1015
1016
1017
1018 if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
1019 match_length --;
1020 do {
1021 strstart ++;
1022
1023 ins_h = (ins_h << hash_shift ^ window[strstart +
1024 MIN_MATCH - 1] & 0xff) &
1025 hash_mask;
1026
1027 hash_head = head[ins_h] & 0xffff;
1028 prev[strstart & w_mask] = head[ins_h];
1029 head[ins_h] = (short) strstart;
1030
1031
1032
1033 } while (-- match_length != 0);
1034 strstart ++;
1035 } else {
1036 strstart += match_length;
1037 match_length = 0;
1038 ins_h = window[strstart] & 0xff;
1039
1040 ins_h = (ins_h << hash_shift ^ window[strstart + 1] & 0xff) &
1041 hash_mask;
1042
1043
1044 }
1045 } else {
1046
1047
1048 bflush = _tr_tally(0, window[strstart] & 0xff);
1049 lookahead --;
1050 strstart ++;
1051 }
1052 if (bflush) {
1053
1054 flush_block_only(false);
1055 if (strm.avail_out == 0) {
1056 return NeedMore;
1057 }
1058 }
1059 }
1060
1061 flush_block_only(flush == JZlib.Z_FINISH);
1062 if (strm.avail_out == 0) {
1063 if (flush == JZlib.Z_FINISH) {
1064 return FinishStarted;
1065 } else {
1066 return NeedMore;
1067 }
1068 }
1069 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
1070 }
1071
1072
1073
1074
1075 private int deflate_slow(int flush) {
1076
1077 int hash_head = 0;
1078 boolean bflush;
1079
1080
1081 while (true) {
1082
1083
1084
1085
1086
1087 if (lookahead < MIN_LOOKAHEAD) {
1088 fill_window();
1089 if (lookahead < MIN_LOOKAHEAD && flush == JZlib.Z_NO_FLUSH) {
1090 return NeedMore;
1091 }
1092 if (lookahead == 0) {
1093 break;
1094 }
1095 }
1096
1097
1098
1099
1100 if (lookahead >= MIN_MATCH) {
1101 ins_h = (ins_h << hash_shift ^ window[strstart + MIN_MATCH - 1] & 0xff) &
1102 hash_mask;
1103
1104 hash_head = head[ins_h] & 0xffff;
1105 prev[strstart & w_mask] = head[ins_h];
1106 head[ins_h] = (short) strstart;
1107 }
1108
1109
1110 prev_length = match_length;
1111 prev_match = match_start;
1112 match_length = MIN_MATCH - 1;
1113
1114 if (hash_head != 0 && prev_length < max_lazy_match &&
1115 (strstart - hash_head & 0xffff) <= w_size - MIN_LOOKAHEAD) {
1116
1117
1118
1119
1120 if (strategy != JZlib.Z_HUFFMAN_ONLY) {
1121 match_length = longest_match(hash_head);
1122 }
1123
1124
1125 if (match_length <= 5 &&
1126 (strategy == JZlib.Z_FILTERED || match_length == MIN_MATCH &&
1127 strstart - match_start > 4096)) {
1128
1129
1130
1131 match_length = MIN_MATCH - 1;
1132 }
1133 }
1134
1135
1136
1137 if (prev_length >= MIN_MATCH && match_length <= prev_length) {
1138 int max_insert = strstart + lookahead - MIN_MATCH;
1139
1140
1141
1142
1143 bflush = _tr_tally(strstart - 1 - prev_match, prev_length -
1144 MIN_MATCH);
1145
1146
1147
1148
1149
1150 lookahead -= prev_length - 1;
1151 prev_length -= 2;
1152 do {
1153 if (++ strstart <= max_insert) {
1154 ins_h = (ins_h << hash_shift ^ window[strstart +
1155 MIN_MATCH - 1] & 0xff) &
1156 hash_mask;
1157
1158 hash_head = head[ins_h] & 0xffff;
1159 prev[strstart & w_mask] = head[ins_h];
1160 head[ins_h] = (short) strstart;
1161 }
1162 } while (-- prev_length != 0);
1163 match_available = 0;
1164 match_length = MIN_MATCH - 1;
1165 strstart ++;
1166
1167 if (bflush) {
1168 flush_block_only(false);
1169 if (strm.avail_out == 0) {
1170 return NeedMore;
1171 }
1172 }
1173 } else if (match_available != 0) {
1174
1175
1176
1177
1178
1179 bflush = _tr_tally(0, window[strstart - 1] & 0xff);
1180
1181 if (bflush) {
1182 flush_block_only(false);
1183 }
1184 strstart ++;
1185 lookahead --;
1186 if (strm.avail_out == 0) {
1187 return NeedMore;
1188 }
1189 } else {
1190
1191
1192
1193 match_available = 1;
1194 strstart ++;
1195 lookahead --;
1196 }
1197 }
1198
1199 if (match_available != 0) {
1200 _tr_tally(0, window[strstart - 1] & 0xff);
1201 match_available = 0;
1202 }
1203 flush_block_only(flush == JZlib.Z_FINISH);
1204
1205 if (strm.avail_out == 0) {
1206 if (flush == JZlib.Z_FINISH) {
1207 return FinishStarted;
1208 } else {
1209 return NeedMore;
1210 }
1211 }
1212
1213 return flush == JZlib.Z_FINISH? FinishDone : BlockDone;
1214 }
1215
1216 private int longest_match(int cur_match) {
1217 int chain_length = max_chain_length;
1218 int scan = strstart;
1219 int match;
1220 int len;
1221 int best_len = prev_length;
1222 int limit = strstart > w_size - MIN_LOOKAHEAD? strstart -
1223 (w_size - MIN_LOOKAHEAD) : 0;
1224 int nice_match = this.nice_match;
1225
1226
1227
1228
1229 int wmask = w_mask;
1230
1231 int strend = strstart + MAX_MATCH;
1232 byte scan_end1 = window[scan + best_len - 1];
1233 byte scan_end = window[scan + best_len];
1234
1235
1236
1237
1238
1239 if (prev_length >= good_match) {
1240 chain_length >>= 2;
1241 }
1242
1243
1244
1245 if (nice_match > lookahead) {
1246 nice_match = lookahead;
1247 }
1248
1249 do {
1250 match = cur_match;
1251
1252
1253
1254 if (window[match + best_len] != scan_end ||
1255 window[match + best_len - 1] != scan_end1 ||
1256 window[match] != window[scan] ||
1257 window[++ match] != window[scan + 1]) {
1258 continue;
1259 }
1260
1261
1262
1263
1264
1265
1266 scan += 2;
1267 match ++;
1268
1269
1270
1271 while (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] &&
1277 window[++ scan] == window[++ match] &&
1278 window[++ scan] == window[++ match] && scan < strend) {
1279 continue;
1280 }
1281
1282 len = MAX_MATCH - (strend - scan);
1283 scan = strend - MAX_MATCH;
1284
1285 if (len > best_len) {
1286 match_start = cur_match;
1287 best_len = len;
1288 if (len >= nice_match) {
1289 break;
1290 }
1291 scan_end1 = window[scan + best_len - 1];
1292 scan_end = window[scan + best_len];
1293 }
1294
1295 } while ((cur_match = prev[cur_match & wmask] & 0xffff) > limit &&
1296 -- chain_length != 0);
1297
1298 if (best_len <= lookahead) {
1299 return best_len;
1300 }
1301 return lookahead;
1302 }
1303
1304 int deflateInit(ZStream strm, int level, int bits, int memLevel, WrapperType wrapperType) {
1305 return deflateInit2(strm, level, JZlib.Z_DEFLATED, bits,
1306 memLevel, JZlib.Z_DEFAULT_STRATEGY, wrapperType);
1307 }
1308
1309 private int deflateInit2(ZStream strm, int level, int method, int windowBits,
1310 int memLevel, int strategy, WrapperType wrapperType) {
1311
1312 if (wrapperType == WrapperType.ZLIB_OR_NONE) {
1313 throw new IllegalArgumentException("ZLIB_OR_NONE allowed only for inflate");
1314 }
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 strm.msg = null;
1325
1326 if (level == JZlib.Z_DEFAULT_COMPRESSION) {
1327 level = 6;
1328 }
1329
1330 if (windowBits < 0) {
1331 throw new IllegalArgumentException("windowBits: " + windowBits);
1332 }
1333
1334 if (memLevel < 1 || memLevel > JZlib.MAX_MEM_LEVEL ||
1335 method != JZlib.Z_DEFLATED || windowBits < 9 ||
1336 windowBits > 15 || level < 0 || level > 9 || strategy < 0 ||
1337 strategy > JZlib.Z_HUFFMAN_ONLY) {
1338 return JZlib.Z_STREAM_ERROR;
1339 }
1340
1341 strm.dstate = this;
1342
1343 this.wrapperType = wrapperType;
1344 w_bits = windowBits;
1345 w_size = 1 << w_bits;
1346 w_mask = w_size - 1;
1347
1348 hash_bits = memLevel + 7;
1349 hash_size = 1 << hash_bits;
1350 hash_mask = hash_size - 1;
1351 hash_shift = (hash_bits + MIN_MATCH - 1) / MIN_MATCH;
1352
1353 window = new byte[w_size * 2];
1354 prev = new short[w_size];
1355 head = new short[hash_size];
1356
1357 lit_bufsize = 1 << memLevel + 6;
1358
1359
1360
1361 pending_buf = new byte[lit_bufsize * 4];
1362 pending_buf_size = lit_bufsize * 4;
1363
1364 d_buf = lit_bufsize / 2;
1365 l_buf = (1 + 2) * lit_bufsize;
1366
1367 this.level = level;
1368
1369
1370
1371 this.strategy = strategy;
1372
1373 return deflateReset(strm);
1374 }
1375
1376 private int deflateReset(ZStream strm) {
1377 strm.total_in = strm.total_out = 0;
1378 strm.msg = null;
1379
1380 pending = 0;
1381 pending_out = 0;
1382
1383 wroteTrailer = false;
1384 status = wrapperType == WrapperType.NONE? BUSY_STATE : INIT_STATE;
1385 strm.adler = Adler32.adler32(0, null, 0, 0);
1386 strm.crc32 = 0;
1387 gzipUncompressedBytes = 0;
1388
1389 last_flush = JZlib.Z_NO_FLUSH;
1390
1391 tr_init();
1392 lm_init();
1393 return JZlib.Z_OK;
1394 }
1395
1396 int deflateEnd() {
1397 if (status != INIT_STATE && status != BUSY_STATE &&
1398 status != FINISH_STATE) {
1399 return JZlib.Z_STREAM_ERROR;
1400 }
1401
1402 pending_buf = null;
1403 head = null;
1404 prev = null;
1405 window = null;
1406
1407
1408 return status == BUSY_STATE? JZlib.Z_DATA_ERROR : JZlib.Z_OK;
1409 }
1410
1411 int deflateParams(ZStream strm, int _level, int _strategy) {
1412 int err = JZlib.Z_OK;
1413
1414 if (_level == JZlib.Z_DEFAULT_COMPRESSION) {
1415 _level = 6;
1416 }
1417 if (_level < 0 || _level > 9 || _strategy < 0 ||
1418 _strategy > JZlib.Z_HUFFMAN_ONLY) {
1419 return JZlib.Z_STREAM_ERROR;
1420 }
1421
1422 if (config_table[level].func != config_table[_level].func &&
1423 strm.total_in != 0) {
1424
1425 err = strm.deflate(JZlib.Z_PARTIAL_FLUSH);
1426 }
1427
1428 if (level != _level) {
1429 level = _level;
1430 max_lazy_match = config_table[level].max_lazy;
1431 good_match = config_table[level].good_length;
1432 nice_match = config_table[level].nice_length;
1433 max_chain_length = config_table[level].max_chain;
1434 }
1435 strategy = _strategy;
1436 return err;
1437 }
1438
1439 int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) {
1440 int length = dictLength;
1441 int index = 0;
1442
1443 if (dictionary == null || status != INIT_STATE) {
1444 return JZlib.Z_STREAM_ERROR;
1445 }
1446
1447 strm.adler = Adler32.adler32(strm.adler, dictionary, 0, dictLength);
1448
1449 if (length < MIN_MATCH) {
1450 return JZlib.Z_OK;
1451 }
1452 if (length > w_size - MIN_LOOKAHEAD) {
1453 length = w_size - MIN_LOOKAHEAD;
1454 index = dictLength - length;
1455 }
1456 System.arraycopy(dictionary, index, window, 0, length);
1457 strstart = length;
1458 block_start = length;
1459
1460
1461
1462
1463
1464 ins_h = window[0] & 0xff;
1465 ins_h = (ins_h << hash_shift ^ window[1] & 0xff) & hash_mask;
1466
1467 for (int n = 0; n <= length - MIN_MATCH; n ++) {
1468 ins_h = (ins_h << hash_shift ^ window[n + MIN_MATCH - 1] & 0xff) &
1469 hash_mask;
1470 prev[n & w_mask] = head[ins_h];
1471 head[ins_h] = (short) n;
1472 }
1473 return JZlib.Z_OK;
1474 }
1475
1476 int deflate(ZStream strm, int flush) {
1477 int old_flush;
1478
1479 if (flush > JZlib.Z_FINISH || flush < 0) {
1480 return JZlib.Z_STREAM_ERROR;
1481 }
1482
1483 if (strm.next_out == null || strm.next_in == null &&
1484 strm.avail_in != 0 || status == FINISH_STATE &&
1485 flush != JZlib.Z_FINISH) {
1486 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_STREAM_ERROR];
1487 return JZlib.Z_STREAM_ERROR;
1488 }
1489 if (strm.avail_out == 0) {
1490 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1491 return JZlib.Z_BUF_ERROR;
1492 }
1493
1494 this.strm = strm;
1495 old_flush = last_flush;
1496 last_flush = flush;
1497
1498
1499 if (status == INIT_STATE) {
1500 switch (wrapperType) {
1501 case ZLIB:
1502 int header = JZlib.Z_DEFLATED + (w_bits - 8 << 4) << 8;
1503 int level_flags = (level - 1 & 0xff) >> 1;
1504
1505 if (level_flags > 3) {
1506 level_flags = 3;
1507 }
1508 header |= level_flags << 6;
1509 if (strstart != 0) {
1510 header |= JZlib.PRESET_DICT;
1511 }
1512 header += 31 - header % 31;
1513
1514 putShortMSB(header);
1515
1516
1517 if (strstart != 0) {
1518 putShortMSB((int) (strm.adler >>> 16));
1519 putShortMSB((int) (strm.adler & 0xffff));
1520 }
1521 strm.adler = Adler32.adler32(0, null, 0, 0);
1522 break;
1523 case GZIP:
1524
1525 put_byte((byte) 0x1f);
1526 put_byte((byte) 0x8b);
1527
1528 put_byte((byte) 8);
1529
1530 put_byte((byte) 0);
1531
1532 put_byte((byte) 0);
1533 put_byte((byte) 0);
1534 put_byte((byte) 0);
1535 put_byte((byte) 0);
1536
1537 switch (config_table[level].func) {
1538 case FAST:
1539 put_byte((byte) 4);
1540 break;
1541 case SLOW:
1542 put_byte((byte) 2);
1543 break;
1544 default:
1545 put_byte((byte) 0);
1546 break;
1547 }
1548
1549 put_byte((byte) 255);
1550
1551 strm.crc32 = 0;
1552 break;
1553 }
1554
1555 status = BUSY_STATE;
1556 }
1557
1558
1559 if (pending != 0) {
1560 strm.flush_pending();
1561 if (strm.avail_out == 0) {
1562
1563
1564
1565
1566
1567
1568 last_flush = -1;
1569 return JZlib.Z_OK;
1570 }
1571
1572
1573
1574
1575 } else if (strm.avail_in == 0 && flush <= old_flush &&
1576 flush != JZlib.Z_FINISH) {
1577 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1578 return JZlib.Z_BUF_ERROR;
1579 }
1580
1581
1582 if (status == FINISH_STATE && strm.avail_in != 0) {
1583 strm.msg = z_errmsg[JZlib.Z_NEED_DICT - JZlib.Z_BUF_ERROR];
1584 return JZlib.Z_BUF_ERROR;
1585 }
1586
1587
1588 int old_next_in_index = strm.next_in_index;
1589 try {
1590 if (strm.avail_in != 0 || lookahead != 0 || flush != JZlib.Z_NO_FLUSH &&
1591 status != FINISH_STATE) {
1592 int bstate = -1;
1593 switch (config_table[level].func) {
1594 case STORED:
1595 bstate = deflate_stored(flush);
1596 break;
1597 case FAST:
1598 bstate = deflate_fast(flush);
1599 break;
1600 case SLOW:
1601 bstate = deflate_slow(flush);
1602 break;
1603 default:
1604 }
1605
1606 if (bstate == FinishStarted || bstate == FinishDone) {
1607 status = FINISH_STATE;
1608 }
1609 if (bstate == NeedMore || bstate == FinishStarted) {
1610 if (strm.avail_out == 0) {
1611 last_flush = -1;
1612 }
1613 return JZlib.Z_OK;
1614
1615
1616
1617
1618
1619
1620 }
1621
1622 if (bstate == BlockDone) {
1623 if (flush == JZlib.Z_PARTIAL_FLUSH) {
1624 _tr_align();
1625 } else {
1626 _tr_stored_block(0, 0, false);
1627
1628
1629 if (flush == JZlib.Z_FULL_FLUSH) {
1630
1631 for (int i = 0; i < hash_size; i ++) {
1632 head[i] = 0;
1633 }
1634 }
1635 }
1636 strm.flush_pending();
1637 if (strm.avail_out == 0) {
1638 last_flush = -1;
1639 return JZlib.Z_OK;
1640 }
1641 }
1642 }
1643 } finally {
1644 gzipUncompressedBytes += strm.next_in_index - old_next_in_index;
1645 }
1646
1647 if (flush != JZlib.Z_FINISH) {
1648 return JZlib.Z_OK;
1649 }
1650
1651 if (wrapperType == WrapperType.NONE || wroteTrailer) {
1652 return JZlib.Z_STREAM_END;
1653 }
1654
1655 switch (wrapperType) {
1656 case ZLIB:
1657
1658 putShortMSB((int) (strm.adler >>> 16));
1659 putShortMSB((int) (strm.adler & 0xffff));
1660 break;
1661 case GZIP:
1662
1663 put_byte((byte) (strm.crc32 & 0xFF));
1664 put_byte((byte) (strm.crc32 >>> 8 & 0xFF));
1665 put_byte((byte) (strm.crc32 >>> 16 & 0xFF));
1666 put_byte((byte) (strm.crc32 >>> 24 & 0xFF));
1667 put_byte((byte) (gzipUncompressedBytes & 0xFF));
1668 put_byte((byte) (gzipUncompressedBytes >>> 8 & 0xFF));
1669 put_byte((byte) (gzipUncompressedBytes >>> 16 & 0xFF));
1670 put_byte((byte) (gzipUncompressedBytes >>> 24 & 0xFF));
1671 break;
1672 }
1673
1674 strm.flush_pending();
1675
1676
1677 wroteTrailer = true;
1678 return pending != 0? JZlib.Z_OK : JZlib.Z_STREAM_END;
1679 }
1680 }