Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | #include "stdafx.h" |
2 | #pragma hdrstop |
||
3 | //#if defined(_USE_ASM_) && (__BORLANDC__ < 0x0570) |
||
4 | //#pragma inline |
||
5 | //#endif |
||
6 | |||
7 | #include "ZipDflt.h" |
||
8 | #include "dz_errs.h" |
||
9 | |||
10 | #undef _DZ_FILE_ |
||
11 | #define _DZ_FILE_ DZ_ZTREES_CPP |
||
12 | |||
13 | /* Trees.c |
||
14 | * Copyright (C) 1990-1996 Mark Adler, Richard B. Wales, Jean-loup Gailly, |
||
15 | * Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. |
||
16 | * This version modified by Chris Vleghert and Eric Engler for BCB/Delphi Zip. |
||
17 | ** distributed under LGPL license ** see license.txt for details |
||
18 | */ |
||
19 | /* Trees.c by Jean-loup Gailly |
||
20 | * This is a new version of im_ctree.c originally written by Richard B. Wales |
||
21 | * for the defunct implosion method. |
||
22 | * |
||
23 | * PURPOSE |
||
24 | * Encode various sets of source values using variable-length |
||
25 | * binary code trees. |
||
26 | * |
||
27 | * DISCUSSION |
||
28 | * The PKZIP "deflation" process uses several Huffman trees. The more |
||
29 | * common source values are represented by shorter bit sequences. |
||
30 | * |
||
31 | * Each code tree is stored in the ZIP file in a compressed form |
||
32 | * which is itself a Huffman encoding of the lengths of |
||
33 | * all the code strings (in ascending order by source values). |
||
34 | * The actual code strings are reconstructed from the lengths in |
||
35 | * the UNZIP process, as described in the "application note" |
||
36 | * (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program. |
||
37 | * |
||
38 | * REFERENCES |
||
39 | * Lynch, Thomas J. |
||
40 | * Data Compression: Techniques and Applications, pp. 53-55. |
||
41 | * Lifetime Learning Publications, 1985. ISBN 0-534-03418-7. |
||
42 | * |
||
43 | * Storer, James A. |
||
44 | * Data Compression: Methods and Theory, pp. 49-50. |
||
45 | * Computer Science Press, 1988. ISBN 0-7167-8156-5. |
||
46 | * |
||
47 | * Sedgewick, R. |
||
48 | * Algorithms, p290. |
||
49 | * Addison-Wesley, 1983. ISBN 0-201-06672-6. |
||
50 | * |
||
51 | * INTERFACE |
||
52 | * void ct_init(ush *attr, int *method) |
||
53 | * Allocate the match buffer, initialize the various tables and save |
||
54 | * the location of the internal file attribute (ascii/binary) and |
||
55 | * method (DEFLATE/STORE) |
||
56 | * |
||
57 | * void ct_tally(int dist, int lc); |
||
58 | * Save the match info and tally the frequency counts. |
||
59 | * |
||
60 | * long flush_block(char *buf, ulg stored_len, int eof) |
||
61 | * Determine the best encoding for the current block: dynamic trees, |
||
62 | * static trees or store, and output the encoded block to the zip |
||
63 | * file. Returns the total compressed length for the file so far. |
||
64 | */ |
||
65 | /* |
||
66 | |||
67 | Copyright (c) 1990-2007 Info-ZIP. All rights reserved. |
||
68 | |||
69 | See the accompanying file LICENSE, version 2007-Mar-4 or later |
||
70 | (the contents of which are also included in zip.h) for terms of use. |
||
71 | If, for some reason, all these files are missing, the Info-ZIP license |
||
72 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
||
73 | |||
74 | parts Copyright (C) 1997 Mike White, Eric W. Engler |
||
75 | ************************************************************************ |
||
76 | Copyright (C) 2009, 2010 by Russell J. Peters, Roger Aelbrecht |
||
77 | |||
78 | This file is part of TZipMaster Version 1.9. |
||
79 | |||
80 | TZipMaster is free software: you can redistribute it and/or modify |
||
81 | it under the terms of the GNU Lesser General Public License as published by |
||
82 | the Free Software Foundation, either version 3 of the License, or |
||
83 | (at your option) any later version. |
||
84 | |||
85 | TZipMaster is distributed in the hope that it will be useful, |
||
86 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
87 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
88 | GNU Lesser General Public License for more details. |
||
89 | |||
90 | You should have received a copy of the GNU Lesser General Public License |
||
91 | along with TZipMaster. If not, see <http://www.gnu.org/licenses/>. |
||
92 | |||
93 | contact: problems@delphizip.org (include ZipMaster in the subject). |
||
94 | updates: http://www.delphizip.org |
||
95 | DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip |
||
96 | ************************************************************************/ |
||
97 | #include <ctype.h> |
||
98 | |||
99 | #define d_code(dist) \ |
||
100 | ((dist) < 256 ? fdist_code[dist] : fdist_code[256 + ((dist) >> 7)]) |
||
101 | |||
102 | #define send_code(c, tree) send_bits(tree[c].Code, tree[c].Len) |
||
103 | |||
104 | #define STORED_BLOCK 0 |
||
105 | #define STATIC_TREES 1 |
||
106 | #define DYN_TREES 2 |
||
107 | |||
108 | /* |
||
109 | // Local (static) data |
||
110 | int extra_lbits[LENGTH_CODES] // extra bits for each length code |
||
111 | = |
||
112 | { |
||
113 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, |
||
114 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; |
||
115 | |||
116 | int extra_dbits[D_CODES] // extra bits for each distance code |
||
117 | = |
||
118 | { |
||
119 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
||
120 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 |
||
121 | }; |
||
122 | |||
123 | int extra_blbits[BL_CODES] // extra bits for each bit length code |
||
124 | = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 }; |
||
125 | */ |
||
126 | static uch bl_order[BL_CODES] = |
||
127 | { |
||
128 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, |
||
129 | 13, 2, 14, 1, 15 |
||
130 | }; |
||
131 | |||
132 | // The lengths of the bit length codes are sent in order of decreasing |
||
133 | // probability, to avoid transmitting the lengths for unused bit length |
||
134 | // codes. |
||
135 | |||
136 | // Allocate the match buffer, initialize the various tables and save the |
||
137 | // location of the internal file attribute (ascii/binary) and method |
||
138 | // (DEFLATE/STORE). attr :: Pointer to internal file attribute. method :: |
||
139 | // Pointer to compression method. |
||
140 | void ZipDflt::ct_init(ush *attr, int *method) |
||
141 | { |
||
142 | int n; // iterates over tree elements |
||
143 | int bits; // bit counter |
||
144 | int length; // length value |
||
145 | int code; // code value |
||
146 | int dist; // distance index |
||
147 | ffile_type = attr; |
||
148 | ffile_method = method; |
||
149 | fcompressed_len = 0;//ui64; // v1.6018 |
||
150 | #ifdef DEBUG |
||
151 | finput_len = 0L; |
||
152 | #endif |
||
153 | |||
154 | if (fstatic_dtree[0].Len != 0) |
||
155 | return; // ct_init already called |
||
156 | |||
157 | // Initialize the mapping length (0..255) -> length code (0..28) |
||
158 | length = 0; |
||
159 | |||
160 | for (code = 0; code < LENGTH_CODES - 1; code++) |
||
161 | { |
||
162 | fbase_length[code] = length; |
||
163 | |||
164 | for (n = 0; n < (1 << extra_lbits[code]); n++) |
||
165 | flength_code[length++] = (uch) code; |
||
166 | } |
||
167 | |||
168 | Assert(length == 256, _T("ct_init: length != 256")); |
||
169 | |||
170 | // Note that the length 255 (match length 258) can be represented in two |
||
171 | // different ways: code 284 + 5 bits or code 285, so we overwrite |
||
172 | // length_code[255] to use the best encoding: |
||
173 | flength_code[length - 1] = (uch) code; |
||
174 | |||
175 | // Initialize the mapping dist (0..32K) -> dist code (0..29) |
||
176 | dist = 0; |
||
177 | |||
178 | for (code = 0; code < 16; code++) |
||
179 | { |
||
180 | fbase_dist[code] = dist; |
||
181 | |||
182 | for (n = 0; n < (1 << extra_dbits[code]); n++) |
||
183 | fdist_code[dist++] = (uch) code; |
||
184 | } |
||
185 | |||
186 | Assert(dist == 256, _T("ct_init: dist != 256")); |
||
187 | |||
188 | dist >>= 7; // from now on, all distances are divided by 128 |
||
189 | |||
190 | for (; code < D_CODES; code++) |
||
191 | { |
||
192 | fbase_dist[code] = dist << 7; |
||
193 | |||
194 | for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) |
||
195 | fdist_code[256 + dist++] = (uch) code; |
||
196 | } |
||
197 | |||
198 | Assert(dist == 256, _T("ct_init: 256 + dist != 512")); |
||
199 | |||
200 | // Construct the codes of the static literal tree |
||
201 | |||
202 | for (bits = 0; bits <= MAX_BITS; bits++) |
||
203 | fbl_count[bits] = 0; |
||
204 | |||
205 | n = 0; |
||
206 | |||
207 | while (n <= 143) |
||
208 | fstatic_ltree[n++].Len = 8, fbl_count[8]++; |
||
209 | |||
210 | while (n <= 255) |
||
211 | fstatic_ltree[n++].Len = 9, fbl_count[9]++; |
||
212 | |||
213 | while (n <= 279) |
||
214 | fstatic_ltree[n++].Len = 7, fbl_count[7]++; |
||
215 | |||
216 | while (n <= 287) |
||
217 | fstatic_ltree[n++].Len = 8, fbl_count[8]++; |
||
218 | |||
219 | // Codes 286 and 287 do not exist, but we must include them in the tree |
||
220 | // construction to get a canonical Huffman tree (longest code all ones) |
||
221 | gen_codes((ct_data *)fstatic_ltree, L_CODES + 1); |
||
222 | |||
223 | // The static distance tree is trivial: |
||
224 | for (n = 0; n < D_CODES; n++) |
||
225 | { |
||
226 | fstatic_dtree[n].Len = 5; |
||
227 | fstatic_dtree[n].Code = (ush)(bi_reverse(n, 5)); // RCV Added (ush) |
||
228 | } |
||
229 | |||
230 | // Initialize the first block of the first file: |
||
231 | init_block(); |
||
232 | } |
||
233 | |||
234 | // Initialize a new block. |
||
235 | void ZipDflt::init_block(void) |
||
236 | { |
||
237 | int n; // iterates over tree elements |
||
238 | |||
239 | // Initialize the trees. |
||
240 | |||
241 | for (n = 0; n < L_CODES; n++) |
||
242 | fdyn_ltree[n].Freq = 0; |
||
243 | |||
244 | for (n = 0; n < D_CODES; n++) |
||
245 | fdyn_dtree[n].Freq = 0; |
||
246 | |||
247 | for (n = 0; n < BL_CODES; n++) |
||
248 | fbl_tree[n].Freq = 0; |
||
249 | |||
250 | fdyn_ltree[END_BLOCK].Freq = 1; |
||
251 | fopt_len = fstatic_len = 0L; |
||
252 | flast_lit = flast_dist = flast_flags = 0; |
||
253 | fflags = 0; |
||
254 | fflag_bit = 1; |
||
255 | } |
||
256 | |||
257 | #define SMALLEST 1 |
||
258 | |||
259 | // Index within the heap array of least frequent node in the Huffman tree |
||
260 | // Remove the smallest element from the heap and recreate the heap with one |
||
261 | // less element. Updates heap and heap_len. |
||
262 | #define pqremove(tree, top) \ |
||
263 | { \ |
||
264 | top = fheap[SMALLEST]; \ |
||
265 | fheap[SMALLEST] = fheap[fheap_len--]; \ |
||
266 | pqdownheap(tree, SMALLEST); \ |
||
267 | } |
||
268 | |||
269 | #ifndef _USE_ASM_ |
||
270 | // Compares to subtrees, using the tree depth as tie breaker when the |
||
271 | // subtrees have equal frequency. This minimizes the worst case length. |
||
272 | #define smaller(tree, n, m) \ |
||
273 | ( \ |
||
274 | tree[n].Freq < tree[m].Freq \ |
||
275 | || (tree[n].Freq == tree[m].Freq && fdepth[n] <= fdepth[m]) \ |
||
276 | ) |
||
277 | |||
278 | // Restore the heap property by moving down the tree starting at node k, |
||
279 | // exchanging a node with the smallest of its two sons if necessary, stopping |
||
280 | // when the heap property is re-established (each father smaller than its two |
||
281 | // sons). tree :: The tree to restore. k :: Node to move down. |
||
282 | void __fastcall ZipDflt::pqdownheap(ct_data *tree, int k) |
||
283 | { |
||
284 | int v = fheap[k]; |
||
285 | int j = k << 1; // left son of k |
||
286 | int htemp; // required because of bug in SASC compiler |
||
287 | |||
288 | while (j <= fheap_len) |
||
289 | { |
||
290 | // Set j to the smallest of the two sons: |
||
291 | if (j < fheap_len && smaller(tree, fheap[j + 1], fheap[j])) |
||
292 | j++; |
||
293 | |||
294 | // Exit if v is smaller than both sons |
||
295 | htemp = fheap[j]; |
||
296 | |||
297 | if (smaller(tree, v, htemp)) |
||
298 | break; |
||
299 | |||
300 | // Exchange v with the smallest son |
||
301 | fheap[k] = htemp; |
||
302 | |||
303 | k = j; |
||
304 | |||
305 | // And continue down the tree, setting j to the left son of k |
||
306 | j <<= 1; |
||
307 | } |
||
308 | |||
309 | fheap[k] = v; |
||
310 | } |
||
311 | /* |
||
312 | #else |
||
313 | |||
314 | void __fastcall ZipDflt::pqdownheap(ct_data *tree, int k) |
||
315 | { |
||
316 | #pragma warn - rvl |
||
317 | #pragma argsused |
||
318 | // int v, j, b; |
||
319 | int v = fheap[k]; |
||
320 | int j = k << 1; // left son of k |
||
321 | int htemp; |
||
322 | asm |
||
323 | { |
||
324 | |||
325 | l1: |
||
326 | mov ebx, this |
||
327 | // ebx = this |
||
328 | // While (j <= fheap_len) |
||
329 | mov edx, j |
||
330 | cmp edx, dword ptr [ebx .fheap_len] |
||
331 | jg lx |
||
332 | // if (J < fheap_len |
||
333 | jge l3 |
||
334 | // && smaller |
||
335 | // tree[j + 1].Freq < tree[j].Freq |
||
336 | mov ecx, tree |
||
337 | mov edx, j |
||
338 | mov edx, dword ptr [ebx+4*edx .fheap+4] |
||
339 | mov ax, word ptr [ecx+4*edx] |
||
340 | mov edx, j |
||
341 | mov edx, dword ptr [ebx+4*edx .fheap] |
||
342 | cmp ax, word ptr [ecx+4*edx] |
||
343 | jb short l2 |
||
344 | // || (tree[n].Freq == tree[m].Freq |
||
345 | jne short l3 |
||
346 | // && fdepth[j + 1] <= fdepth[j]) |
||
347 | mov eax, j |
||
348 | mov edx, this |
||
349 | mov eax, dword ptr [ebx+4*eax .fheap+4] |
||
350 | mov cl, byte ptr [ebx+eax .fdepth] |
||
351 | mov eax, j |
||
352 | mov eax, dword ptr [ebx+4*eax .fheap] |
||
353 | cmp cl, byte ptr [ebx+eax .fdepth] |
||
354 | ja short l3 |
||
355 | |||
356 | l2: |
||
357 | // j++ |
||
358 | inc j |
||
359 | |||
360 | l3: |
||
361 | // Exit if v is smaller than both sons |
||
362 | // htemp = fheap[j]; |
||
363 | mov ecx, j |
||
364 | mov edx, dword ptr [ebx+4*ecx .fheap] |
||
365 | mov htemp, edx |
||
366 | // if (smaller(tree, v, htemp) |
||
367 | // tree[v].Freq < tree[htemp].Freq |
||
368 | mov ecx, tree |
||
369 | mov eax, v |
||
370 | mov dx, word ptr [ecx+4*eax] |
||
371 | mov eax, htemp |
||
372 | cmp dx, word ptr [ecx+4*eax] |
||
373 | jb short lx |
||
374 | // || (tree[v].Freq == tree[htemp].Freq |
||
375 | jne short l4 |
||
376 | // && fdepth[v] <= fdepth[htemp]) |
||
377 | mov eax, v |
||
378 | mov cl, byte ptr [ebx+eax .fdepth] |
||
379 | mov eax, htemp |
||
380 | cmp cl, byte ptr [ebx+eax .fdepth] |
||
381 | jbe short lx |
||
382 | |||
383 | l4: |
||
384 | // Exchange v with the smallest son |
||
385 | // fheap[k] = htemp; |
||
386 | mov ecx, k |
||
387 | mov edx, htemp |
||
388 | mov dword ptr [ebx+4*ecx .fheap], edx |
||
389 | |||
390 | // k = j; |
||
391 | mov ecx, j |
||
392 | mov k, ecx |
||
393 | |||
394 | // And continue down the tree, setting j to the left son of k |
||
395 | // j <<= 1; |
||
396 | shl j, 1 |
||
397 | jmp short l1 |
||
398 | // } while |
||
399 | |||
400 | lx: |
||
401 | // fheap[k] = v; |
||
402 | mov ecx, k |
||
403 | mov eax, this |
||
404 | mov edx, v |
||
405 | mov dword ptr [eax+4*ecx .fheap], edx |
||
406 | // fini |
||
407 | }; |
||
408 | }; |
||
409 | */ |
||
410 | #endif |
||
411 | |||
412 | // Compute the optimal bit lengths for a tree and update the total bit |
||
413 | // length for the current block. IN assertion: the fields freq and dad are |
||
414 | // set, heap[heap_max] and above are the tree nodes sorted by increasing |
||
415 | // frequency. OUT assertions: the field len is set to the optimal bit length, |
||
416 | // the array bl_count contains the frequencies for each bit length. The |
||
417 | // length opt_len is updated; static_len is also updated if stree is not |
||
418 | // null. desc :: The tree descriptor. |
||
419 | void __fastcall ZipDflt::gen_bitlen(tree_desc *desc) |
||
420 | { |
||
421 | ct_data *tree = desc->dyn_tree; |
||
422 | int *extra = desc->extra_bits; |
||
423 | int base = desc->extra_base; |
||
424 | int max_code = desc->max_code; |
||
425 | int max_length = desc->max_length; |
||
426 | ct_data *stree = desc->static_tree; |
||
427 | int h; // heap index |
||
428 | int n, |
||
429 | m; // iterate over the tree elements |
||
430 | int bits; // bit length |
||
431 | int xbits; // extra bits |
||
432 | ush f; // frequency |
||
433 | int overflow = 0; // number of elements with bit length too large |
||
434 | |||
435 | for (bits = 0; bits <= MAX_BITS; bits++) |
||
436 | fbl_count[bits] = 0; |
||
437 | |||
438 | // In a first pass, compute the optimal bit lengths (which may overflow in |
||
439 | // the case of the bit length tree). |
||
440 | tree[fheap[fheap_max]].Len = 0; // root of the heap |
||
441 | |||
442 | for (h = fheap_max + 1; h < HEAP_SIZE; h++) |
||
443 | { |
||
444 | n = fheap[h]; |
||
445 | bits = tree[tree[n].Dad].Len + 1; |
||
446 | |||
447 | if (bits > max_length) |
||
448 | bits = max_length, overflow++; |
||
449 | |||
450 | tree[n].Len = (ush) bits; // RCV Added (ush) |
||
451 | |||
452 | // We overwrite tree[n].Dad which is no longer needed |
||
453 | if (n > max_code) |
||
454 | continue; // not a leaf node |
||
455 | |||
456 | fbl_count[bits]++; |
||
457 | xbits = 0; |
||
458 | |||
459 | if (n >= base) |
||
460 | xbits = extra[n - base]; |
||
461 | |||
462 | f = tree[n].Freq; |
||
463 | fopt_len += (ulg) f * (bits + xbits); |
||
464 | |||
465 | if (stree) |
||
466 | fstatic_len += (ulg) f * (stree[n].Len + xbits); |
||
467 | } |
||
468 | |||
469 | if (overflow == 0) |
||
470 | return; |
||
471 | |||
472 | // Trace(("\nbit length overflow\n", 0)); |
||
473 | |||
474 | // This happens for example on obj2 and pic of the Calgary corpus |
||
475 | // Find the first bit length which could increase: |
||
476 | do |
||
477 | { |
||
478 | bits = max_length - 1; |
||
479 | while (fbl_count[bits] == 0) |
||
480 | bits--; |
||
481 | |||
482 | fbl_count[bits]--; // move one leaf down the tree |
||
483 | fbl_count[bits + 1] += (ush) 2; // move one overflow item as its brother |
||
484 | fbl_count[max_length]--; |
||
485 | |||
486 | // The brother of the overflow item also moves one step up, but this |
||
487 | // does not affect bl_count[max_length] |
||
488 | overflow -= 2; |
||
489 | } |
||
490 | while (overflow > 0); |
||
491 | |||
492 | // Now recompute all bit lengths, scanning in increasing frequency. h is |
||
493 | // still equal to HEAP_SIZE. (It is simpler to reconstruct all lengths |
||
494 | // instead of fixing only the wrong ones. This idea is taken from 'ar' |
||
495 | // written by Haruhiko Okumura.) |
||
496 | for (bits = max_length; bits != 0; bits--) |
||
497 | { |
||
498 | n = fbl_count[bits]; |
||
499 | |||
500 | while (n != 0) |
||
501 | { |
||
502 | m = fheap[--h]; |
||
503 | |||
504 | if (m > max_code) |
||
505 | continue; |
||
506 | |||
507 | if (tree[m].Len != (ush) bits) |
||
508 | { // RCV Changed (unsigned) in (ush) |
||
509 | // Trace(("code %d bits %d->%d"), m, tree[m].Len, bits); |
||
510 | fopt_len += ((long)bits - (long)tree[m].Len) * (long)tree[m].Freq; |
||
511 | tree[m].Len = (ush) bits; // RCV Added (ush) |
||
512 | } |
||
513 | |||
514 | n--; |
||
515 | } |
||
516 | } |
||
517 | } |
||
518 | |||
519 | // Generate the codes for a given tree and bit counts (which need not be |
||
520 | // optimal). IN assertion: the array bl_count contains the bit length |
||
521 | // statistics for the given tree and the field len is set for all tree |
||
522 | // elements. OUT assertion: the field code is set for all tree elements of |
||
523 | // non zero code length. tree :: The tree to decorate max_code :: Largest |
||
524 | // code with non zero frequency. |
||
525 | void __fastcall ZipDflt::gen_codes(ct_data *tree, int max_code) |
||
526 | { |
||
527 | ush next_code[MAX_BITS + 1]; // next code value for each bit length |
||
528 | ush code = 0; // running code value |
||
529 | int bits; // bit index |
||
530 | int n; // code index |
||
531 | |||
532 | // The distribution counts are first used to generate the code values |
||
533 | // without bit reversal. |
||
534 | |||
535 | for (bits = 1; bits <= MAX_BITS; bits++) |
||
536 | { |
||
537 | next_code[bits] = code = (ush)((code + fbl_count[bits - 1]) << 1); // RCV Added (ush) |
||
538 | } |
||
539 | |||
540 | // Check that the bit counts in bl_count are consistent. The last code |
||
541 | // must be all ones. |
||
542 | Assert(code + fbl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, |
||
543 | _T("inconsistent bit counts")); |
||
544 | |||
545 | // Tracev(("\ngen_codes: max_code %d "), (max_code)); |
||
546 | |||
547 | for (n = 0; n <= max_code; n++) |
||
548 | { |
||
549 | int len = tree[n].Len; |
||
550 | |||
551 | if (len == 0) |
||
552 | continue; |
||
553 | |||
554 | // Now reverse the bits |
||
555 | tree[n].Code = (ush)(bi_reverse(next_code[len]++, len)); // RCV Added (ush) |
||
556 | |||
557 | // Tracec(tree != fstatic_ltree, ("\nn %3d %c l %2d c %4x (%x) "),(n, |
||
558 | // (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); |
||
559 | } |
||
560 | } |
||
561 | |||
562 | // Construct one Huffman tree and assigns the code bit strings and lengths. |
||
563 | // Update the total bit length for the current block. IN assertion: the field |
||
564 | // freq is set for all tree elements. OUT assertions: the fields len and code |
||
565 | // are set to the optimal bit length and corresponding code. The length |
||
566 | // opt_len is updated; static_len is also updated if stree is not null. The |
||
567 | // field max_code is set. desc :: The tree descriptor. |
||
568 | void __fastcall ZipDflt::build_tree(tree_desc *desc) |
||
569 | { |
||
570 | ct_data *tree = desc->dyn_tree; |
||
571 | ct_data *stree = desc->static_tree; |
||
572 | int elems = desc->elems; |
||
573 | int n, |
||
574 | m; // iterate over heap elements |
||
575 | int max_code = -1; // largest code with non zero frequency |
||
576 | int node = elems; // next internal node of the tree |
||
577 | |||
578 | // Construct the initial heap, with least frequent element in |
||
579 | // heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
||
580 | // heap[0] is not used. |
||
581 | fheap_len = 0, fheap_max = HEAP_SIZE; |
||
582 | |||
583 | for (n = 0; n < elems; n++) |
||
584 | { |
||
585 | if (tree[n].Freq != 0) |
||
586 | { |
||
587 | fheap[++fheap_len] = max_code = n; |
||
588 | fdepth[n] = 0; |
||
589 | } |
||
590 | else |
||
591 | tree[n].Len = 0; |
||
592 | } |
||
593 | |||
594 | // The pkzip format requires that at least one distance code exists, and |
||
595 | // that at least one bit should be sent even if there is only one possible |
||
596 | // code. So to avoid special checks later on we force at least two codes of |
||
597 | // non zero frequency. |
||
598 | while (fheap_len < 2) |
||
599 | { |
||
600 | int nw = fheap[++fheap_len] = ((max_code < 2) ? ++max_code : 0); |
||
601 | |||
602 | tree[nw].Freq = 1; |
||
603 | fdepth[nw] = 0; |
||
604 | fopt_len--; |
||
605 | |||
606 | if (stree) |
||
607 | fstatic_len -= stree[nw].Len; |
||
608 | |||
609 | // new is 0 or 1 so it does not have extra bits |
||
610 | } |
||
611 | |||
612 | desc->max_code = max_code; |
||
613 | |||
614 | // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
||
615 | // establish sub-heaps of increasing lengths: |
||
616 | |||
617 | for (n = fheap_len / 2; n >= 1; n--) |
||
618 | pqdownheap(tree, n); |
||
619 | |||
620 | // Construct the Huffman tree by repeatedly combining the least two |
||
621 | // frequent nodes. |
||
622 | do |
||
623 | { |
||
624 | pqremove(tree, n); // n = node of least frequency |
||
625 | m = fheap[SMALLEST]; // m = node of next least frequency |
||
626 | fheap[--fheap_max] = n; // keep the nodes sorted by frequency |
||
627 | fheap[--fheap_max] = m; |
||
628 | |||
629 | // Create a new node father of n and m |
||
630 | tree[node].Freq = (ush)(tree[n].Freq + tree[m].Freq); // RCV Added (ush) |
||
631 | fdepth[node] = (uch)(Max(fdepth[n], fdepth[m]) + 1); |
||
632 | tree[n].Dad = tree[m].Dad = (ush) node; // RCV Added (ush) |
||
633 | #ifdef DUMP_BL_TREE |
||
634 | if (tree == bl_tree) |
||
635 | { |
||
636 | DLLprintf("\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, |
||
637 | tree[n].Freq, m, tree[m].Freq); |
||
638 | } |
||
639 | #endif |
||
640 | |||
641 | // and insert the new node in the heap |
||
642 | fheap[SMALLEST] = node++; |
||
643 | |||
644 | pqdownheap(tree, SMALLEST); |
||
645 | } |
||
646 | while (fheap_len >= 2); |
||
647 | |||
648 | fheap[--fheap_max] = fheap[SMALLEST]; |
||
649 | |||
650 | // At this point, the fields freq and dad are set. We can now generate the |
||
651 | // bit lengths. |
||
652 | gen_bitlen((tree_desc *)desc); |
||
653 | |||
654 | // The field len is now set, we can generate the bit codes |
||
655 | gen_codes((ct_data *)tree, max_code); |
||
656 | } |
||
657 | |||
658 | // Scan a literal or distance tree to determine the frequencies of the codes |
||
659 | // in the bit length tree. Updates opt_len to take into account the repeat |
||
660 | // counts. (The contribution of the bit length codes will be added later |
||
661 | // during the construction of bl_tree.) tree :: The tree to be scanned. |
||
662 | // max_code :: And its largest code of non zero frequency. |
||
663 | void __fastcall ZipDflt::scan_tree(ct_data *tree, int max_code) |
||
664 | { |
||
665 | int n; // iterates over all tree elements |
||
666 | int prevlen = -1; // last emitted length |
||
667 | int curlen; // length of current code |
||
668 | int nextlen = tree[0].Len; // length of next code |
||
669 | int count = 0; // repeat count of the current code |
||
670 | int max_count = 7; // max repeat count |
||
671 | int min_count = 4; // min repeat count |
||
672 | |||
673 | if (nextlen == 0) |
||
674 | max_count = 138, min_count = 3; |
||
675 | |||
676 | tree[max_code + 1].Len = (ush) - 1; // guard |
||
677 | |||
678 | for (n = 0; n <= max_code; n++) |
||
679 | { |
||
680 | curlen = nextlen; |
||
681 | nextlen = tree[n + 1].Len; |
||
682 | |||
683 | if (++count < max_count && curlen == nextlen) |
||
684 | { |
||
685 | continue; |
||
686 | } |
||
687 | else |
||
688 | if (count < min_count) |
||
689 | { |
||
690 | fbl_tree[curlen].Freq += (ush) count; // RCV Added (ush) |
||
691 | } |
||
692 | else |
||
693 | if (curlen != 0) |
||
694 | { |
||
695 | if (curlen != prevlen) |
||
696 | fbl_tree[curlen].Freq++; |
||
697 | |||
698 | fbl_tree[REP_3_6].Freq++; |
||
699 | } |
||
700 | else |
||
701 | if (count <= 10) |
||
702 | { |
||
703 | fbl_tree[REPZ_3_10].Freq++; |
||
704 | } |
||
705 | else |
||
706 | { |
||
707 | fbl_tree[REPZ_11_138].Freq++; |
||
708 | } |
||
709 | |||
710 | count = 0; |
||
711 | prevlen = curlen; |
||
712 | if (nextlen == 0) |
||
713 | { |
||
714 | max_count = 138, min_count = 3; |
||
715 | } |
||
716 | else |
||
717 | if (curlen == nextlen) |
||
718 | { |
||
719 | max_count = 6, min_count = 3; |
||
720 | } |
||
721 | else |
||
722 | { |
||
723 | max_count = 7, min_count = 4; |
||
724 | } |
||
725 | } |
||
726 | } |
||
727 | |||
728 | // Send a literal or distance tree in compressed form, using the codes in |
||
729 | // bl_tree. tree :: The tree to be scanned. max_code :: And its largest code |
||
730 | // of non zero frequency. |
||
731 | void __fastcall ZipDflt::send_tree(ct_data *tree, int max_code) |
||
732 | { |
||
733 | int n; // iterates over all tree elements |
||
734 | int prevlen = -1; // last emitted length |
||
735 | int curlen; // length of current code |
||
736 | int nextlen = tree[0].Len; // length of next code |
||
737 | int count = 0; // repeat count of the current code |
||
738 | int max_count = 7; // max repeat count |
||
739 | int min_count = 4; // min repeat count |
||
740 | |||
741 | // tree[max_code+1].Len = -1; |
||
742 | // guard already set |
||
743 | |||
744 | if (!nextlen) |
||
745 | max_count = 138, min_count = 3; |
||
746 | |||
747 | for (n = 0; n <= max_code; n++) |
||
748 | { |
||
749 | curlen = nextlen; |
||
750 | nextlen = tree[n + 1].Len; |
||
751 | |||
752 | if (++count < max_count && curlen == nextlen) |
||
753 | { |
||
754 | continue; |
||
755 | } |
||
756 | else |
||
757 | if (count < min_count) |
||
758 | { |
||
759 | do |
||
760 | { |
||
761 | send_code(curlen, fbl_tree); |
||
762 | } |
||
763 | while (--count != 0); |
||
764 | } |
||
765 | else |
||
766 | if (curlen != 0) |
||
767 | { |
||
768 | if (curlen != prevlen) |
||
769 | { |
||
770 | send_code(curlen, fbl_tree); |
||
771 | count--; |
||
772 | } |
||
773 | |||
774 | Assert(count >= 3 && count <= 6, _T(" 3_6?")); |
||
775 | |||
776 | send_code(REP_3_6, fbl_tree); |
||
777 | send_bits(count - 3, 2); |
||
778 | } |
||
779 | else |
||
780 | if (count <= 10) |
||
781 | { |
||
782 | send_code(REPZ_3_10, fbl_tree); |
||
783 | send_bits(count - 3, 3); |
||
784 | } |
||
785 | else |
||
786 | { |
||
787 | send_code(REPZ_11_138, fbl_tree); |
||
788 | send_bits(count - 11, 7); |
||
789 | } |
||
790 | |||
791 | count = 0; |
||
792 | |||
793 | prevlen = curlen; |
||
794 | |||
795 | if (!nextlen) |
||
796 | { |
||
797 | max_count = 138, min_count = 3; |
||
798 | } |
||
799 | else |
||
800 | if (curlen == nextlen) |
||
801 | { |
||
802 | max_count = 6, min_count = 3; |
||
803 | } |
||
804 | else |
||
805 | { |
||
806 | max_count = 7, min_count = 4; |
||
807 | } |
||
808 | } |
||
809 | } |
||
810 | |||
811 | // Construct the Huffman tree for the bit lengths and return the index in |
||
812 | // bl_order of the last bit length code to send. |
||
813 | int __fastcall ZipDflt::build_bl_tree(void) |
||
814 | { |
||
815 | int max_blindex; // index of last bit length code of non zero freq |
||
816 | |||
817 | // Determine the bit length frequencies for literal and distance trees |
||
818 | scan_tree((ct_data *)fdyn_ltree, fl_desc.max_code); |
||
819 | scan_tree((ct_data *)fdyn_dtree, fd_desc.max_code); |
||
820 | |||
821 | // Build the bit length tree: |
||
822 | build_tree((tree_desc *)(&fbl_desc)); |
||
823 | |||
824 | // opt_len now includes the length of the tree representations, except the |
||
825 | // lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
||
826 | // Determine the number of bit length codes to send. The pkzip format |
||
827 | // requires that at least 4 bit length codes be sent. (appnote.txt says 3 |
||
828 | // but the actual value used is 4.) |
||
829 | |||
830 | for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) |
||
831 | { |
||
832 | if (fbl_tree[bl_order[max_blindex]].Len != 0) |
||
833 | break; |
||
834 | } |
||
835 | |||
836 | // Update opt_len to include the bit length tree and counts |
||
837 | fopt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; |
||
838 | // Tracev(("\ndyn trees: dyn %ld, stat %ld"), (fopt_len, fstatic_len)); |
||
839 | |||
840 | return max_blindex; |
||
841 | } |
||
842 | |||
843 | // Send the header for a block using dynamic Huffman trees: the counts, the |
||
844 | // lengths of the bit length codes, the literal tree and the distance tree. |
||
845 | // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. lcodes, dcodes, |
||
846 | // blcodes :: Number of codes for each tree. |
||
847 | void ZipDflt::send_all_trees(int lcodes, int dcodes, int blcodes) |
||
848 | { |
||
849 | int rank; // index in bl_order |
||
850 | /* Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); |
||
851 | Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, |
||
852 | "too many codes"); |
||
853 | Tracev(("\nbl counts: "), 0); */ |
||
854 | send_bits(lcodes - 257, 5); |
||
855 | |||
856 | // not +255 as stated in appnote.txt 1.93a or -256 in 2.04c |
||
857 | send_bits(dcodes - 1, 5); |
||
858 | send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt |
||
859 | |||
860 | for (rank = 0; rank < blcodes; rank++) |
||
861 | { |
||
862 | // Tracev(("\nbl code %2d "), (bl_order[rank])); |
||
863 | send_bits(fbl_tree[bl_order[rank]].Len, 3); |
||
864 | } |
||
865 | |||
866 | // Tracev(("\nbl tree: sent %ld"), (fbits_sent)); |
||
867 | send_tree((ct_data *)fdyn_ltree, lcodes - 1); // send the literal tree |
||
868 | // Tracev(("\nlit tree: sent %ld"), (fbits_sent)); |
||
869 | send_tree((ct_data *)fdyn_dtree, dcodes - 1); // send the distance tree |
||
870 | // Tracev(("\ndist tree: sent %ld"), (fbits_sent)); |
||
871 | } |
||
872 | |||
873 | // Determine the best encoding for the current block: dynamic trees, static |
||
874 | // trees or store, and output the encoded block to the zip file. This |
||
875 | // function returns the total compressed length for the file so far. buf :: |
||
876 | // Input block, or NULL if too old. stored_len :: Length of input block. eof; |
||
877 | // :: true if this is the last block for a file. |
||
878 | //ulg |
||
879 | |||
880 | // strstart is set to the end of the current match. |
||
881 | //#define FLUSH_BLOCK(eof) |
||
882 | // flush_block(fblock_start >= 0L ? (uch *) &fwindow[(unsigned)fblock_start] : |
||
883 | // (uch *)NULL, (ulg)fstrstart - (ulg)fblock_start, (eof)) |
||
884 | ZInt64 __fastcall ZipDflt::FlushBlock(int eof) |
||
885 | { |
||
886 | ulg opt_lenb, static_lenb; // opt_len and static_len in bytes |
||
887 | int max_blindex; // index of last bit length code of non zero freq |
||
888 | fflag_buf[flast_flags] = fflags; // Save the flags for the last 8 items |
||
889 | const uch *buf = fblock_start >= 0L ? (uch *) & fwindow[(unsigned)fblock_start] : |
||
890 | (uch *)NULL; |
||
891 | ulg stored_len = (ulg)fstrstart - (ulg)fblock_start; |
||
892 | |||
893 | // Check if the file is ascii or binary |
||
894 | if (*ffile_type == (ush) UNKNOWN) |
||
895 | set_file_type(); |
||
896 | |||
897 | // Construct the literal and distance trees |
||
898 | build_tree((tree_desc *)(&fl_desc)); |
||
899 | // Tracev(("\nlit data: dyn %ld, stat %ld"), (fopt_len, fstatic_len)); |
||
900 | build_tree((tree_desc *)(&fd_desc)); |
||
901 | // Tracev(("\ndist data: dyn %ld, stat %ld"), (fopt_len, fstatic_len)); |
||
902 | |||
903 | // At this point, opt_len and static_len are the total bit lengths of the |
||
904 | // compressed block data, excluding the tree representations. |
||
905 | // Build the bit length tree for the above two trees, and get the index in |
||
906 | // bl_order of the last bit length code to send. |
||
907 | max_blindex = build_bl_tree(); |
||
908 | |||
909 | // Determine the best encoding. Compute first the block length in bytes |
||
910 | opt_lenb = (fopt_len + 3 + 7) >> 3; |
||
911 | static_lenb = (fstatic_len + 3 + 7) >> 3; |
||
912 | |||
913 | #ifdef DEBUG |
||
914 | finput_len += stored_len; // for debugging only |
||
915 | #endif |
||
916 | // Trace(("\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", |
||
917 | // opt_lenb, fopt_len, static_lenb, fstatic_len, |
||
918 | // stored_len, flast_lit, flast_dist)); |
||
919 | |||
920 | if (static_lenb <= opt_lenb) |
||
921 | opt_lenb = static_lenb; |
||
922 | |||
923 | // If compression failed and this is the first and last block, and if the |
||
924 | // zip file can be seeked (to rewrite the local header), the whole file is |
||
925 | // transformed into a stored file: |
||
926 | #ifdef FORCE_METHOD |
||
927 | if (flevel == 1 && eof && fcompressed_len == 0ui64) |
||
928 | { // force stored file v1.6018 |
||
929 | #else |
||
930 | if (stored_len <= opt_lenb |
||
931 | && eof |
||
932 | && fcompressed_len == 0//ui64 |
||
933 | && fZipOutfile->IsSeekable) |
||
934 | // && (fCanSeek || seekable())) // 1.75 only need to check once |
||
935 | { // v1.6018 |
||
936 | #endif |
||
937 | |||
938 | // Since LIT_BUFSIZE <= 2 * ZWSIZE, the input data must be there: |
||
939 | if (buf == NULL) |
||
940 | throw DZException(DZ_ERM_LOGIC_ERROR); |
||
941 | |||
942 | // FatalError(ZEN_LOGIC07); |
||
943 | |||
944 | copy_block(buf, (unsigned)stored_len, 0); // without header |
||
945 | fcompressed_len = ((unsigned __int64)stored_len) << 3;//ui64; // v1.6018 |
||
946 | *ffile_method = STORE; |
||
947 | } |
||
948 | else |
||
949 | #ifdef FORCE_METHOD |
||
950 | if (flevel == 2 && buf != (uch *)NULL) |
||
951 | { // force stored block |
||
952 | #else |
||
953 | if (stored_len + 4 <= opt_lenb && buf != (uch *)NULL) |
||
954 | { |
||
955 | // 4: two words for the lengths |
||
956 | #endif |
||
957 | // The test buf != NULL is only necessary if LIT_BUFSIZE > ZWSIZE. |
||
958 | // Otherwise we can't have processed more than WSIZE input bytes |
||
959 | // since the last block flush, because compression would have been |
||
960 | // successful. If LIT_BUFSIZE <= ZWSIZE, it is never too late to |
||
961 | // transform a block into a stored block. |
||
962 | send_bits((STORED_BLOCK << 1) + eof, 3); // send block type |
||
963 | fcompressed_len = (fcompressed_len + 3 + 7) & ~7ui64; // v1.6018 |
||
964 | fcompressed_len += ((unsigned __int64)(stored_len + 4)) << 3; // v1.6018 |
||
965 | copy_block(buf, (unsigned)stored_len, 1); // with header |
||
966 | #ifdef FORCE_METHOD |
||
967 | } |
||
968 | else |
||
969 | if (flevel == 3) |
||
970 | { // force static trees |
||
971 | #else |
||
972 | } |
||
973 | else |
||
974 | if (static_lenb == opt_lenb) |
||
975 | { |
||
976 | #endif |
||
977 | send_bits((STATIC_TREES << 1) + eof, 3); |
||
978 | compress_block((ct_data *)fstatic_ltree, (ct_data *)fstatic_dtree); |
||
979 | fcompressed_len += 3 + fstatic_len; |
||
980 | } |
||
981 | else |
||
982 | { |
||
983 | send_bits((DYN_TREES << 1) + eof, 3); |
||
984 | send_all_trees(fl_desc.max_code + 1, fd_desc.max_code + 1, max_blindex + 1); |
||
985 | compress_block((ct_data *)fdyn_ltree, (ct_data *)fdyn_dtree); |
||
986 | fcompressed_len += 3 + fopt_len; |
||
987 | } |
||
988 | |||
989 | // Assert(fcompressed_len == (unsigned __int64)fbits_sent, "bad compressed size"); |
||
990 | init_block(); |
||
991 | |||
992 | if (eof) |
||
993 | { |
||
994 | Assert(finput_len == fisize, _T("bad input size")); |
||
995 | bi_windup(); |
||
996 | fcompressed_len += 7; // align on byte boundary |
||
997 | } |
||
998 | |||
999 | // Tracev(("\ncomprlen %Lu(%Lu) "), (fcompressed_len >> 3, |
||
1000 | // fcompressed_len - 7 * eof)); |
||
1001 | |||
1002 | return (fcompressed_len >> 3); |
||
1003 | } |
||
1004 | |||
1005 | // Save the match info and tally the frequency counts. Return true if |
||
1006 | // the current block must be flushed. dist :: Distance of matched string. |
||
1007 | // lc :: Match length-MIN_MATCH or unmatched char (if dist==0) |
||
1008 | int __fastcall ZipDflt::ct_tally(int dist, int lc) |
||
1009 | { |
||
1010 | fl_buf[flast_lit++] = (uch) lc; |
||
1011 | |||
1012 | if (!dist) |
||
1013 | { |
||
1014 | // lc is the unmatched char |
||
1015 | fdyn_ltree[lc].Freq++; |
||
1016 | } |
||
1017 | else |
||
1018 | { |
||
1019 | // Here, lc is the match length - MIN_MATCH |
||
1020 | dist--; // dist = match distance - 1 |
||
1021 | Assert((ush) dist < (ush) MAX_DIST && (ush) lc <= (ush)(MAX_MATCH - MIN_MATCH) |
||
1022 | && (ush) d_code(dist) < (ush) D_CODES, _T("ct_tally: bad match")); |
||
1023 | |||
1024 | fdyn_ltree[flength_code[lc] + LITERALS + 1].Freq++; |
||
1025 | fdyn_dtree[d_code(dist)].Freq++; |
||
1026 | |||
1027 | fd_buf[flast_dist++] = (ush) dist; // RCV Added (ush) |
||
1028 | fflags |= fflag_bit; |
||
1029 | } |
||
1030 | |||
1031 | fflag_bit <<= 1; |
||
1032 | |||
1033 | // Output the flags if they fill a byte: |
||
1034 | |||
1035 | if ((flast_lit & 7) == 0) |
||
1036 | { |
||
1037 | fflag_buf[flast_flags++] = fflags; |
||
1038 | fflags = 0, fflag_bit = 1; |
||
1039 | } |
||
1040 | |||
1041 | // Try to guess if it is profitable to stop the current block here |
||
1042 | if (flevel > 2 && (flast_lit & 0xFFF) == 0) |
||
1043 | { |
||
1044 | // Compute an upper bound for the compressed length |
||
1045 | ulg out_length = (ulg) flast_lit * 8L; |
||
1046 | ulg in_length = (ulg) fstrstart - fblock_start; |
||
1047 | int dcode; |
||
1048 | |||
1049 | for (dcode = 0; dcode < D_CODES; dcode++) |
||
1050 | { |
||
1051 | out_length += (ulg) fdyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]); |
||
1052 | } |
||
1053 | |||
1054 | out_length >>= 3; |
||
1055 | |||
1056 | /* Trace(("\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) "), (flast_lit, f |
||
1057 | last_dist, in_length, out_length, 100L - out_length * 100L / in_length |
||
1058 | ));*/ |
||
1059 | |||
1060 | if (flast_dist < flast_lit / 2 && out_length < in_length / 2) |
||
1061 | return 1; |
||
1062 | } |
||
1063 | |||
1064 | return (flast_lit == LIT_BUFSIZE - 1 || flast_dist == DIST_BUFSIZE); |
||
1065 | |||
1066 | // We avoid equality with LIT_BUFSIZE because of wraparound at 64K on |
||
1067 | // 16 bit machines and because stored blocks are restricted to 64K-1 |
||
1068 | // bytes. |
||
1069 | } |
||
1070 | |||
1071 | // Send the block data compressed using the given Huffman trees ltree :: |
||
1072 | // Literal tree. dtree :: Distance tree. |
||
1073 | void ZipDflt::compress_block(ct_data *ltree, ct_data *dtree) |
||
1074 | { |
||
1075 | unsigned dist; // distance of matched string |
||
1076 | int lc; // match length or unmatched char (if dist == 0) |
||
1077 | unsigned lx = 0; // running index in l_buf |
||
1078 | unsigned dx = 0; // running index in d_buf |
||
1079 | unsigned fx = 0; // running index in flag_buf |
||
1080 | uch flag = 0; // current flags |
||
1081 | unsigned code; // the code to send |
||
1082 | int extra; // number of extra bits to send |
||
1083 | |||
1084 | if (flast_lit != 0) |
||
1085 | { |
||
1086 | do |
||
1087 | { |
||
1088 | if ((lx & 7) == 0) |
||
1089 | flag = fflag_buf[fx++]; |
||
1090 | |||
1091 | lc = fl_buf[lx++]; |
||
1092 | |||
1093 | if ((flag & 1) == 0) |
||
1094 | { |
||
1095 | send_code(lc, ltree); // send a literal byte |
||
1096 | // Tracecv(isgraph(lc), (" '%c' "), (lc)); |
||
1097 | } |
||
1098 | else |
||
1099 | { |
||
1100 | // Here, lc is the match length - MIN_MATCH |
||
1101 | code = flength_code[lc]; |
||
1102 | send_code(code + LITERALS + 1, ltree); // send the length code |
||
1103 | extra = extra_lbits[code]; |
||
1104 | |||
1105 | if (extra != 0) |
||
1106 | { |
||
1107 | lc -= fbase_length[code]; |
||
1108 | send_bits(lc, extra); // send the extra length bits |
||
1109 | } |
||
1110 | |||
1111 | dist = fd_buf[dx++]; |
||
1112 | |||
1113 | // Here, dist is the match distance - 1 |
||
1114 | code = d_code(dist); |
||
1115 | Assert(code < D_CODES, _T("bad d_code")); |
||
1116 | |||
1117 | send_code(code, dtree); // send the distance code |
||
1118 | extra = extra_dbits[code]; |
||
1119 | |||
1120 | if (extra != 0) |
||
1121 | { |
||
1122 | dist -= fbase_dist[code]; |
||
1123 | send_bits(dist, extra); // send the extra distance bits |
||
1124 | } |
||
1125 | } // literal or match pair ? |
||
1126 | |||
1127 | flag >>= 1; |
||
1128 | } |
||
1129 | while (lx < flast_lit); |
||
1130 | } |
||
1131 | |||
1132 | send_code(END_BLOCK, ltree); |
||
1133 | } |
||
1134 | |||
1135 | // Set the file type to ASCII or BINARY, using a crude approximation: |
||
1136 | // binary if more than 20% of the bytes are <= 6 or >= 128, ascii |
||
1137 | // otherwise. IN assertion: the fields freq of dyn_ltree are set and the |
||
1138 | // total of all frequencies does not exceed 64K (to fit in an int on 16 |
||
1139 | // bit machines). |
||
1140 | void ZipDflt::set_file_type(void) |
||
1141 | { |
||
1142 | unsigned ascii_freq = 0; |
||
1143 | unsigned bin_freq = 0; |
||
1144 | int n = 0; |
||
1145 | |||
1146 | while (n < 7) |
||
1147 | bin_freq += fdyn_ltree[n++].Freq; |
||
1148 | |||
1149 | while (n < 128) |
||
1150 | ascii_freq += fdyn_ltree[n++].Freq; |
||
1151 | |||
1152 | while (n < LITERALS) |
||
1153 | bin_freq += fdyn_ltree[n++].Freq; |
||
1154 | |||
1155 | *ffile_type = (ush)((bin_freq > (ascii_freq >> 2)) ? BINARY : ASCII); // RCV Added |
||
1156 | |||
1157 | ///* (ush) |
||
1158 | // if (*ffile_type == BINARY && ftranslate_eol) |
||
1159 | // { |
||
1160 | // Notify(PF, IWARNING, "-l used on binary file"); |
||
1161 | // } |
||
1162 | } |
||
1163 | |||
1164 | /* 29/1/07 */ |
||
1165 | |||
1166 |