00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include <config.h>
00070 #include <ctype.h>
00071
00072 #include "tailor.h"
00073 #include "gzip.h"
00074
00075 #ifdef RCSID
00076 static char rcsid[] = "$Id: trees.c,v 1.4 2006/11/20 08:40:33 eggert Exp $";
00077 #endif
00078
00079
00080
00081
00082
00083 #define MAX_BITS 15
00084
00085
00086 #define MAX_BL_BITS 7
00087
00088
00089 #define LENGTH_CODES 29
00090
00091
00092 #define LITERALS 256
00093
00094
00095 #define END_BLOCK 256
00096
00097
00098 #define L_CODES (LITERALS+1+LENGTH_CODES)
00099
00100
00101 #define D_CODES 30
00102
00103
00104 #define BL_CODES 19
00105
00106
00107
00108 local int near extra_lbits[LENGTH_CODES]
00109 = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
00110
00111 local int near extra_dbits[D_CODES]
00112 = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
00113
00114 local int near extra_blbits[BL_CODES]
00115 = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
00116
00117 #define STORED_BLOCK 0
00118 #define STATIC_TREES 1
00119 #define DYN_TREES 2
00120
00121
00122 #ifndef LIT_BUFSIZE
00123 # ifdef SMALL_MEM
00124 # define LIT_BUFSIZE 0x2000
00125 # else
00126 # ifdef MEDIUM_MEM
00127 # define LIT_BUFSIZE 0x4000
00128 # else
00129 # define LIT_BUFSIZE 0x8000
00130 # endif
00131 # endif
00132 #endif
00133 #ifndef DIST_BUFSIZE
00134 # define DIST_BUFSIZE LIT_BUFSIZE
00135 #endif
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #if LIT_BUFSIZE > INBUFSIZ
00157 error cannot overlay l_buf and inbuf
00158 #endif
00159
00160 #define REP_3_6 16
00161
00162
00163 #define REPZ_3_10 17
00164
00165
00166 #define REPZ_11_138 18
00167
00168
00169
00170
00171
00172
00173
00174 typedef struct ct_data {
00175 union {
00176 ush freq;
00177 ush code;
00178 } fc;
00179 union {
00180 ush dad;
00181 ush len;
00182 } dl;
00183 } ct_data;
00184
00185 #define Freq fc.freq
00186 #define Code fc.code
00187 #define Dad dl.dad
00188 #define Len dl.len
00189
00190 #define HEAP_SIZE (2*L_CODES+1)
00191
00192
00193 local ct_data near dyn_ltree[HEAP_SIZE];
00194 local ct_data near dyn_dtree[2*D_CODES+1];
00195
00196 local ct_data near static_ltree[L_CODES+2];
00197
00198
00199
00200
00201
00202
00203 local ct_data near static_dtree[D_CODES];
00204
00205
00206
00207
00208 local ct_data near bl_tree[2*BL_CODES+1];
00209
00210
00211 typedef struct tree_desc {
00212 ct_data near *dyn_tree;
00213 ct_data near *static_tree;
00214 int near *extra_bits;
00215 int extra_base;
00216 int elems;
00217 int max_length;
00218 int max_code;
00219 } tree_desc;
00220
00221 local tree_desc near l_desc =
00222 {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0};
00223
00224 local tree_desc near d_desc =
00225 {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0};
00226
00227 local tree_desc near bl_desc =
00228 {bl_tree, (ct_data near *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0};
00229
00230
00231 local ush near bl_count[MAX_BITS+1];
00232
00233
00234 local uch near bl_order[BL_CODES]
00235 = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
00236
00237
00238
00239
00240 local int near heap[2*L_CODES+1];
00241 local int heap_len;
00242 local int heap_max;
00243
00244
00245
00246
00247 local uch near depth[2*L_CODES+1];
00248
00249
00250 local uch length_code[MAX_MATCH-MIN_MATCH+1];
00251
00252
00253 local uch dist_code[512];
00254
00255
00256
00257
00258
00259 local int near base_length[LENGTH_CODES];
00260
00261
00262 local int near base_dist[D_CODES];
00263
00264
00265 #define l_buf inbuf
00266
00267
00268
00269
00270 local uch near flag_buf[(LIT_BUFSIZE/8)];
00271
00272
00273
00274
00275 local unsigned last_lit;
00276 local unsigned last_dist;
00277 local unsigned last_flags;
00278 local uch flags;
00279 local uch flag_bit;
00280
00281
00282
00283
00284
00285 local ulg opt_len;
00286 local ulg static_len;
00287
00288 local off_t compressed_len;
00289
00290 local off_t input_len;
00291
00292
00293 ush *file_type;
00294 int *file_method;
00295
00296 #ifdef DEBUG
00297 extern off_t bits_sent;
00298 #endif
00299
00300 extern long block_start;
00301 extern unsigned near strstart;
00302
00303
00304
00305
00306
00307 local void init_block OF((void));
00308 local void pqdownheap OF((ct_data near *tree, int k));
00309 local void gen_bitlen OF((tree_desc near *desc));
00310 local void gen_codes OF((ct_data near *tree, int max_code));
00311 local void build_tree OF((tree_desc near *desc));
00312 local void scan_tree OF((ct_data near *tree, int max_code));
00313 local void send_tree OF((ct_data near *tree, int max_code));
00314 local int build_bl_tree OF((void));
00315 local void send_all_trees OF((int lcodes, int dcodes, int blcodes));
00316 local void compress_block OF((ct_data near *ltree, ct_data near *dtree));
00317 local void set_file_type OF((void));
00318
00319
00320 #ifndef DEBUG
00321 # define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len)
00322
00323
00324 #else
00325 # define send_code(c, tree) \
00326 { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \
00327 send_bits(tree[c].Code, tree[c].Len); }
00328 #endif
00329
00330 #define d_code(dist) \
00331 ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
00332
00333
00334
00335
00336
00337 #define MAX(a,b) (a >= b ? a : b)
00338
00339
00340
00341
00342
00343
00344
00345 void ct_init(attr, methodp)
00346 ush *attr;
00347 int *methodp;
00348 {
00349 int n;
00350 int bits;
00351 int length;
00352 int code;
00353 int dist;
00354
00355 file_type = attr;
00356 file_method = methodp;
00357 compressed_len = input_len = 0L;
00358
00359 if (static_dtree[0].Len != 0) return;
00360
00361
00362 length = 0;
00363 for (code = 0; code < LENGTH_CODES-1; code++) {
00364 base_length[code] = length;
00365 for (n = 0; n < (1<<extra_lbits[code]); n++) {
00366 length_code[length++] = (uch)code;
00367 }
00368 }
00369 Assert (length == 256, "ct_init: length != 256");
00370
00371
00372
00373
00374 length_code[length-1] = (uch)code;
00375
00376
00377 dist = 0;
00378 for (code = 0 ; code < 16; code++) {
00379 base_dist[code] = dist;
00380 for (n = 0; n < (1<<extra_dbits[code]); n++) {
00381 dist_code[dist++] = (uch)code;
00382 }
00383 }
00384 Assert (dist == 256, "ct_init: dist != 256");
00385 dist >>= 7;
00386 for ( ; code < D_CODES; code++) {
00387 base_dist[code] = dist << 7;
00388 for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
00389 dist_code[256 + dist++] = (uch)code;
00390 }
00391 }
00392 Assert (dist == 256, "ct_init: 256+dist != 512");
00393
00394
00395 for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
00396 n = 0;
00397 while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
00398 while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
00399 while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
00400 while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
00401
00402
00403
00404
00405 gen_codes((ct_data near *)static_ltree, L_CODES+1);
00406
00407
00408 for (n = 0; n < D_CODES; n++) {
00409 static_dtree[n].Len = 5;
00410 static_dtree[n].Code = bi_reverse(n, 5);
00411 }
00412
00413
00414 init_block();
00415 }
00416
00417
00418
00419
00420 local void init_block()
00421 {
00422 int n;
00423
00424
00425 for (n = 0; n < L_CODES; n++) dyn_ltree[n].Freq = 0;
00426 for (n = 0; n < D_CODES; n++) dyn_dtree[n].Freq = 0;
00427 for (n = 0; n < BL_CODES; n++) bl_tree[n].Freq = 0;
00428
00429 dyn_ltree[END_BLOCK].Freq = 1;
00430 opt_len = static_len = 0L;
00431 last_lit = last_dist = last_flags = 0;
00432 flags = 0; flag_bit = 1;
00433 }
00434
00435 #define SMALLEST 1
00436
00437
00438
00439
00440
00441
00442
00443 #define pqremove(tree, top) \
00444 {\
00445 top = heap[SMALLEST]; \
00446 heap[SMALLEST] = heap[heap_len--]; \
00447 pqdownheap(tree, SMALLEST); \
00448 }
00449
00450
00451
00452
00453
00454 #define smaller(tree, n, m) \
00455 (tree[n].Freq < tree[m].Freq || \
00456 (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
00457
00458
00459
00460
00461
00462
00463
00464 local void pqdownheap(tree, k)
00465 ct_data near *tree;
00466 int k;
00467 {
00468 int v = heap[k];
00469 int j = k << 1;
00470 while (j <= heap_len) {
00471
00472 if (j < heap_len && smaller(tree, heap[j+1], heap[j])) j++;
00473
00474
00475 if (smaller(tree, v, heap[j])) break;
00476
00477
00478 heap[k] = heap[j]; k = j;
00479
00480
00481 j <<= 1;
00482 }
00483 heap[k] = v;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 local void gen_bitlen(desc)
00497 tree_desc near *desc;
00498 {
00499 ct_data near *tree = desc->dyn_tree;
00500 int near *extra = desc->extra_bits;
00501 int base = desc->extra_base;
00502 int max_code = desc->max_code;
00503 int max_length = desc->max_length;
00504 ct_data near *stree = desc->static_tree;
00505 int h;
00506 int n, m;
00507 int bits;
00508 int xbits;
00509 ush f;
00510 int overflow = 0;
00511
00512 for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
00513
00514
00515
00516
00517 tree[heap[heap_max]].Len = 0;
00518
00519 for (h = heap_max+1; h < HEAP_SIZE; h++) {
00520 n = heap[h];
00521 bits = tree[tree[n].Dad].Len + 1;
00522 if (bits > max_length) bits = max_length, overflow++;
00523 tree[n].Len = (ush)bits;
00524
00525
00526 if (n > max_code) continue;
00527
00528 bl_count[bits]++;
00529 xbits = 0;
00530 if (n >= base) xbits = extra[n-base];
00531 f = tree[n].Freq;
00532 opt_len += (ulg)f * (bits + xbits);
00533 if (stree) static_len += (ulg)f * (stree[n].Len + xbits);
00534 }
00535 if (overflow == 0) return;
00536
00537 Trace((stderr,"\nbit length overflow\n"));
00538
00539
00540
00541 do {
00542 bits = max_length-1;
00543 while (bl_count[bits] == 0) bits--;
00544 bl_count[bits]--;
00545 bl_count[bits+1] += 2;
00546 bl_count[max_length]--;
00547
00548
00549
00550 overflow -= 2;
00551 } while (overflow > 0);
00552
00553
00554
00555
00556
00557
00558 for (bits = max_length; bits != 0; bits--) {
00559 n = bl_count[bits];
00560 while (n != 0) {
00561 m = heap[--h];
00562 if (m > max_code) continue;
00563 if (tree[m].Len != (unsigned) bits) {
00564 Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
00565 opt_len += ((long)bits-(long)tree[m].Len)*(long)tree[m].Freq;
00566 tree[m].Len = (ush)bits;
00567 }
00568 n--;
00569 }
00570 }
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 local void gen_codes (tree, max_code)
00582 ct_data near *tree;
00583 int max_code;
00584 {
00585 ush next_code[MAX_BITS+1];
00586 ush code = 0;
00587 int bits;
00588 int n;
00589
00590
00591
00592
00593 for (bits = 1; bits <= MAX_BITS; bits++) {
00594 next_code[bits] = code = (code + bl_count[bits-1]) << 1;
00595 }
00596
00597
00598
00599 Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
00600 "inconsistent bit counts");
00601 Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
00602
00603 for (n = 0; n <= max_code; n++) {
00604 int len = tree[n].Len;
00605 if (len == 0) continue;
00606
00607 tree[n].Code = bi_reverse(next_code[len]++, len);
00608
00609 Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
00610 n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
00611 }
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 local void build_tree(desc)
00623 tree_desc near *desc;
00624 {
00625 ct_data near *tree = desc->dyn_tree;
00626 ct_data near *stree = desc->static_tree;
00627 int elems = desc->elems;
00628 int n, m;
00629 int max_code = -1;
00630 int node = elems;
00631
00632
00633
00634
00635
00636 heap_len = 0, heap_max = HEAP_SIZE;
00637
00638 for (n = 0; n < elems; n++) {
00639 if (tree[n].Freq != 0) {
00640 heap[++heap_len] = max_code = n;
00641 depth[n] = 0;
00642 } else {
00643 tree[n].Len = 0;
00644 }
00645 }
00646
00647
00648
00649
00650
00651
00652 while (heap_len < 2) {
00653 int new = heap[++heap_len] = (max_code < 2 ? ++max_code : 0);
00654 tree[new].Freq = 1;
00655 depth[new] = 0;
00656 opt_len--; if (stree) static_len -= stree[new].Len;
00657
00658 }
00659 desc->max_code = max_code;
00660
00661
00662
00663
00664 for (n = heap_len/2; n >= 1; n--) pqdownheap(tree, n);
00665
00666
00667
00668
00669 do {
00670 pqremove(tree, n);
00671 m = heap[SMALLEST];
00672
00673 heap[--heap_max] = n;
00674 heap[--heap_max] = m;
00675
00676
00677 tree[node].Freq = tree[n].Freq + tree[m].Freq;
00678 depth[node] = (uch) (MAX(depth[n], depth[m]) + 1);
00679 tree[n].Dad = tree[m].Dad = (ush)node;
00680 #ifdef DUMP_BL_TREE
00681 if (tree == bl_tree) {
00682 fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
00683 node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
00684 }
00685 #endif
00686
00687 heap[SMALLEST] = node++;
00688 pqdownheap(tree, SMALLEST);
00689
00690 } while (heap_len >= 2);
00691
00692 heap[--heap_max] = heap[SMALLEST];
00693
00694
00695
00696
00697 gen_bitlen((tree_desc near *)desc);
00698
00699
00700 gen_codes ((ct_data near *)tree, max_code);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709 local void scan_tree (tree, max_code)
00710 ct_data near *tree;
00711 int max_code;
00712 {
00713 int n;
00714 int prevlen = -1;
00715 int curlen;
00716 int nextlen = tree[0].Len;
00717 int count = 0;
00718 int max_count = 7;
00719 int min_count = 4;
00720
00721 if (nextlen == 0) max_count = 138, min_count = 3;
00722 tree[max_code+1].Len = (ush)0xffff;
00723
00724 for (n = 0; n <= max_code; n++) {
00725 curlen = nextlen; nextlen = tree[n+1].Len;
00726 if (++count < max_count && curlen == nextlen) {
00727 continue;
00728 } else if (count < min_count) {
00729 bl_tree[curlen].Freq += count;
00730 } else if (curlen != 0) {
00731 if (curlen != prevlen) bl_tree[curlen].Freq++;
00732 bl_tree[REP_3_6].Freq++;
00733 } else if (count <= 10) {
00734 bl_tree[REPZ_3_10].Freq++;
00735 } else {
00736 bl_tree[REPZ_11_138].Freq++;
00737 }
00738 count = 0; prevlen = curlen;
00739 if (nextlen == 0) {
00740 max_count = 138, min_count = 3;
00741 } else if (curlen == nextlen) {
00742 max_count = 6, min_count = 3;
00743 } else {
00744 max_count = 7, min_count = 4;
00745 }
00746 }
00747 }
00748
00749
00750
00751
00752
00753 local void send_tree (tree, max_code)
00754 ct_data near *tree;
00755 int max_code;
00756 {
00757 int n;
00758 int prevlen = -1;
00759 int curlen;
00760 int nextlen = tree[0].Len;
00761 int count = 0;
00762 int max_count = 7;
00763 int min_count = 4;
00764
00765
00766 if (nextlen == 0) max_count = 138, min_count = 3;
00767
00768 for (n = 0; n <= max_code; n++) {
00769 curlen = nextlen; nextlen = tree[n+1].Len;
00770 if (++count < max_count && curlen == nextlen) {
00771 continue;
00772 } else if (count < min_count) {
00773 do { send_code(curlen, bl_tree); } while (--count != 0);
00774
00775 } else if (curlen != 0) {
00776 if (curlen != prevlen) {
00777 send_code(curlen, bl_tree); count--;
00778 }
00779 Assert(count >= 3 && count <= 6, " 3_6?");
00780 send_code(REP_3_6, bl_tree); send_bits(count-3, 2);
00781
00782 } else if (count <= 10) {
00783 send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3);
00784
00785 } else {
00786 send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7);
00787 }
00788 count = 0; prevlen = curlen;
00789 if (nextlen == 0) {
00790 max_count = 138, min_count = 3;
00791 } else if (curlen == nextlen) {
00792 max_count = 6, min_count = 3;
00793 } else {
00794 max_count = 7, min_count = 4;
00795 }
00796 }
00797 }
00798
00799
00800
00801
00802
00803 local int build_bl_tree()
00804 {
00805 int max_blindex;
00806
00807
00808 scan_tree((ct_data near *)dyn_ltree, l_desc.max_code);
00809 scan_tree((ct_data near *)dyn_dtree, d_desc.max_code);
00810
00811
00812 build_tree((tree_desc near *)(&bl_desc));
00813
00814
00815
00816
00817
00818
00819
00820
00821 for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
00822 if (bl_tree[bl_order[max_blindex]].Len != 0) break;
00823 }
00824
00825 opt_len += 3*(max_blindex+1) + 5+5+4;
00826 Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", opt_len, static_len));
00827
00828 return max_blindex;
00829 }
00830
00831
00832
00833
00834
00835
00836 local void send_all_trees(lcodes, dcodes, blcodes)
00837 int lcodes, dcodes, blcodes;
00838 {
00839 int rank;
00840
00841 Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
00842 Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
00843 "too many codes");
00844 Tracev((stderr, "\nbl counts: "));
00845 send_bits(lcodes-257, 5);
00846 send_bits(dcodes-1, 5);
00847 send_bits(blcodes-4, 4);
00848 for (rank = 0; rank < blcodes; rank++) {
00849 Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
00850 send_bits(bl_tree[bl_order[rank]].Len, 3);
00851 }
00852
00853 send_tree((ct_data near *)dyn_ltree, lcodes-1);
00854
00855 send_tree((ct_data near *)dyn_dtree, dcodes-1);
00856 }
00857
00858
00859
00860
00861
00862
00863 off_t flush_block(buf, stored_len, eof)
00864 char *buf;
00865 ulg stored_len;
00866 int eof;
00867 {
00868 ulg opt_lenb, static_lenb;
00869 int max_blindex;
00870
00871 flag_buf[last_flags] = flags;
00872
00873
00874 if (*file_type == (ush)UNKNOWN) set_file_type();
00875
00876
00877 build_tree((tree_desc near *)(&l_desc));
00878 Tracev((stderr, "\nlit data: dyn %lu, stat %lu", opt_len, static_len));
00879
00880 build_tree((tree_desc near *)(&d_desc));
00881 Tracev((stderr, "\ndist data: dyn %lu, stat %lu", opt_len, static_len));
00882
00883
00884
00885
00886
00887
00888
00889 max_blindex = build_bl_tree();
00890
00891
00892 opt_lenb = (opt_len+3+7)>>3;
00893 static_lenb = (static_len+3+7)>>3;
00894 input_len += stored_len;
00895
00896 Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
00897 opt_lenb, opt_len, static_lenb, static_len, stored_len,
00898 last_lit, last_dist));
00899
00900 if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
00901
00902
00903
00904
00905
00906 #ifdef FORCE_METHOD
00907 if (level == 1 && eof && compressed_len == 0L) {
00908 #else
00909 if (stored_len <= opt_lenb && eof && compressed_len == 0L && seekable()) {
00910 #endif
00911
00912 if (!buf)
00913 gzip_error ("block vanished");
00914
00915 copy_block(buf, (unsigned)stored_len, 0);
00916 compressed_len = stored_len << 3;
00917 *file_method = STORED;
00918
00919 #ifdef FORCE_METHOD
00920 } else if (level == 2 && buf != (char*)0) {
00921 #else
00922 } else if (stored_len+4 <= opt_lenb && buf != (char*)0) {
00923
00924 #endif
00925
00926
00927
00928
00929
00930
00931 send_bits((STORED_BLOCK<<1)+eof, 3);
00932 compressed_len = (compressed_len + 3 + 7) & ~7L;
00933 compressed_len += (stored_len + 4) << 3;
00934
00935 copy_block(buf, (unsigned)stored_len, 1);
00936
00937 #ifdef FORCE_METHOD
00938 } else if (level == 3) {
00939 #else
00940 } else if (static_lenb == opt_lenb) {
00941 #endif
00942 send_bits((STATIC_TREES<<1)+eof, 3);
00943 compress_block((ct_data near *)static_ltree, (ct_data near *)static_dtree);
00944 compressed_len += 3 + static_len;
00945 } else {
00946 send_bits((DYN_TREES<<1)+eof, 3);
00947 send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1);
00948 compress_block((ct_data near *)dyn_ltree, (ct_data near *)dyn_dtree);
00949 compressed_len += 3 + opt_len;
00950 }
00951 Assert (compressed_len == bits_sent, "bad compressed size");
00952 init_block();
00953
00954 if (eof) {
00955 Assert (input_len == bytes_in, "bad input size");
00956 bi_windup();
00957 compressed_len += 7;
00958 }
00959
00960 return compressed_len >> 3;
00961 }
00962
00963
00964
00965
00966
00967 int ct_tally (dist, lc)
00968 int dist;
00969 int lc;
00970 {
00971 l_buf[last_lit++] = (uch)lc;
00972 if (dist == 0) {
00973
00974 dyn_ltree[lc].Freq++;
00975 } else {
00976
00977 dist--;
00978 Assert((ush)dist < (ush)MAX_DIST &&
00979 (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
00980 (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match");
00981
00982 dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
00983 dyn_dtree[d_code(dist)].Freq++;
00984
00985 d_buf[last_dist++] = (ush)dist;
00986 flags |= flag_bit;
00987 }
00988 flag_bit <<= 1;
00989
00990
00991 if ((last_lit & 7) == 0) {
00992 flag_buf[last_flags++] = flags;
00993 flags = 0, flag_bit = 1;
00994 }
00995
00996 if (level > 2 && (last_lit & 0xfff) == 0) {
00997
00998 ulg out_length = (ulg)last_lit*8L;
00999 ulg in_length = (ulg)strstart-block_start;
01000 int dcode;
01001 for (dcode = 0; dcode < D_CODES; dcode++) {
01002 out_length += (ulg)dyn_dtree[dcode].Freq*(5L+extra_dbits[dcode]);
01003 }
01004 out_length >>= 3;
01005 Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
01006 last_lit, last_dist, in_length, out_length,
01007 100L - out_length*100L/in_length));
01008 if (last_dist < last_lit/2 && out_length < in_length/2) return 1;
01009 }
01010 return (last_lit == LIT_BUFSIZE-1 || last_dist == DIST_BUFSIZE);
01011
01012
01013
01014
01015 }
01016
01017
01018
01019
01020 local void compress_block(ltree, dtree)
01021 ct_data near *ltree;
01022 ct_data near *dtree;
01023 {
01024 unsigned dist;
01025 int lc;
01026 unsigned lx = 0;
01027 unsigned dx = 0;
01028 unsigned fx = 0;
01029 uch flag = 0;
01030 unsigned code;
01031 int extra;
01032
01033 if (last_lit != 0) do {
01034 if ((lx & 7) == 0) flag = flag_buf[fx++];
01035 lc = l_buf[lx++];
01036 if ((flag & 1) == 0) {
01037 send_code(lc, ltree);
01038 Tracecv(isgraph(lc), (stderr," '%c' ", lc));
01039 } else {
01040
01041 code = length_code[lc];
01042 send_code(code+LITERALS+1, ltree);
01043 extra = extra_lbits[code];
01044 if (extra != 0) {
01045 lc -= base_length[code];
01046 send_bits(lc, extra);
01047 }
01048 dist = d_buf[dx++];
01049