Rev 6851 | Rev 6855 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6617 | IgorA | 1 | ; trees.asm -- output deflated data using Huffman coding |
2 | ; Copyright (C) 1995-2012 Jean-loup Gailly |
||
3 | ; detect_data_type() function provided freely by Cosmin Truta, 2006 |
||
4 | ; For conditions of distribution and use, see copyright notice in zlib.h |
||
5 | |||
6 | ; ALGORITHM |
||
7 | |||
8 | ; The "deflation" process uses several Huffman trees. The more |
||
9 | ; common source values are represented by shorter bit sequences. |
||
10 | |||
11 | ; Each code tree is stored in a compressed form which is itself |
||
12 | ; a Huffman encoding of the lengths of all the code strings (in |
||
13 | ; ascending order by source values). The actual code strings are |
||
14 | ; reconstructed from the lengths in the inflate process, as described |
||
15 | ; in the deflate specification. |
||
16 | |||
17 | ; REFERENCES |
||
18 | |||
19 | ; Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". |
||
20 | ; Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc |
||
21 | |||
22 | ; Storer, James A. |
||
23 | ; Data Compression: Methods and Theory, pp. 49-50. |
||
24 | ; Computer Science Press, 1988. ISBN 0-7167-8156-5. |
||
25 | |||
26 | ; Sedgewick, R. |
||
27 | ; Algorithms, p290. |
||
28 | ; Addison-Wesley, 1983. ISBN 0-201-06672-6. |
||
29 | |||
30 | ; =========================================================================== |
||
31 | ; Constants |
||
32 | |||
33 | |||
34 | MAX_BL_BITS equ 7 |
||
35 | ; Bit length codes must not exceed MAX_BL_BITS bits |
||
36 | |||
37 | END_BLOCK equ 256 |
||
38 | ; end of block literal code |
||
39 | |||
40 | REP_3_6 equ 16 |
||
41 | ; repeat previous bit length 3-6 times (2 bits of repeat count) |
||
42 | |||
43 | REPZ_3_10 equ 17 |
||
44 | ; repeat a zero length 3-10 times (3 bits of repeat count) |
||
45 | |||
46 | REPZ_11_138 equ 18 |
||
47 | ; repeat a zero length 11-138 times (7 bits of repeat count) |
||
48 | |||
49 | align 4 |
||
50 | extra_lbits dd \ ;int [LENGTH_CODES] ;extra bits for each length code |
||
51 | 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 |
||
52 | |||
53 | align 4 |
||
54 | extra_dbits dd \ ;int [D_CODES] ;extra bits for each distance code |
||
55 | 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 |
||
56 | |||
57 | align 4 |
||
58 | extra_blbits dd \ ;int [BL_CODES] ;extra bits for each bit length code |
||
59 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 |
||
60 | |||
61 | align 4 |
||
62 | bl_order db 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 |
||
63 | ; The lengths of the bit length codes are sent in order of decreasing |
||
64 | ; probability, to avoid transmitting the lengths for unused bit length codes. |
||
65 | |||
66 | |||
67 | ; =========================================================================== |
||
68 | ; Local data. These are initialized only once. |
||
69 | |||
70 | |||
71 | DIST_CODE_LEN equ 512 ;see definition of array dist_code below |
||
72 | |||
73 | if GEN_TREES_H eq 1 ;| !(STDC) |
||
74 | ; non ANSI compilers may not accept trees.inc |
||
75 | |||
76 | align 4 |
||
77 | static_ltree rb sizeof.ct_data * (L_CODES+2) |
||
78 | ; The static literal tree. Since the bit lengths are imposed, there is no |
||
79 | ; need for the L_CODES extra codes used during heap construction. However |
||
80 | ; The codes 286 and 287 are needed to build a canonical tree (see _tr_init |
||
81 | ; below). |
||
82 | |||
83 | align 4 |
||
84 | static_dtree rb sizeof.ct_data * D_CODES |
||
85 | ; The static distance tree. (Actually a trivial tree since all codes use |
||
86 | ; 5 bits.) |
||
87 | |||
88 | align 4 |
||
89 | _dist_code rb DIST_CODE_LEN ;uch[] |
||
90 | ; Distance codes. The first 256 values correspond to the distances |
||
91 | ; 3 .. 258, the last 256 values correspond to the top 8 bits of |
||
92 | ; the 15 bit distances. |
||
93 | |||
94 | align 4 |
||
95 | _length_code rb MAX_MATCH-MIN_MATCH+1 ;uch[] |
||
96 | ; length code for each normalized match length (0 == MIN_MATCH) |
||
97 | |||
98 | align 4 |
||
99 | base_length rd LENGTH_CODES ;int[] |
||
100 | ; First normalized length for each code (0 = MIN_MATCH) |
||
101 | |||
102 | align 4 |
||
103 | base_dist rd D_CODES ;int[] |
||
104 | ; First normalized distance for each code (0 = distance of 1) |
||
105 | |||
106 | else |
||
107 | include 'trees.inc' |
||
108 | end if ;GEN_TREES_H |
||
109 | |||
110 | struct static_tree_desc ;_s |
||
111 | static_tree dd ? ;const ct_data * ;static tree or NULL |
||
112 | extra_bits dd ? ;const intf * ;extra bits for each code or NULL |
||
113 | extra_base dd ? ;int ;base index for extra_bits |
||
114 | elems dd ? ;int ;max number of elements in the tree |
||
115 | max_length dd ? ;int ;max bit length for the codes |
||
116 | ends |
||
117 | |||
118 | align 4 |
||
119 | static_l_desc static_tree_desc static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS |
||
120 | |||
121 | align 4 |
||
122 | static_d_desc static_tree_desc static_dtree, extra_dbits, 0, D_CODES, MAX_BITS |
||
123 | |||
124 | align 4 |
||
125 | static_bl_desc static_tree_desc 0, extra_blbits, 0, BL_CODES, MAX_BL_BITS |
||
126 | |||
127 | ; =========================================================================== |
||
128 | ; Local (static) routines in this file. |
||
129 | |||
130 | |||
131 | macro send_code s, c, tree |
||
132 | { |
||
133 | if DEBUG eq 1 |
||
134 | ; if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)) |
||
135 | end if |
||
136 | push eax ebx |
||
137 | if c eq eax |
||
138 | else |
||
139 | mov eax,c |
||
140 | end if |
||
141 | imul eax,sizeof.ct_data |
||
142 | add eax,tree |
||
143 | movzx ebx,word[eax+Len] |
||
144 | push ebx |
||
145 | movzx ebx,word[eax+Code] |
||
146 | push ebx |
||
147 | stdcall send_bits, s ;tree[c].Code, tree[c].Len |
||
148 | pop ebx eax |
||
149 | } |
||
150 | ; Send a code of the given tree[c] and tree must not have side effects |
||
151 | |||
152 | ; =========================================================================== |
||
153 | ; Output a short LSB first on the stream. |
||
154 | ; IN assertion: there is enough room in pendingBuf. |
||
155 | |||
156 | macro put_short s, w |
||
157 | { |
||
6741 | IgorA | 158 | mov eax,[s+deflate_state.pending] |
6617 | IgorA | 159 | add eax,[s+deflate_state.pending_buf] |
160 | mov word[eax],w |
||
6741 | IgorA | 161 | add dword[s+deflate_state.pending],2 |
6617 | IgorA | 162 | } |
163 | |||
164 | ; =========================================================================== |
||
165 | ; Send a value on a given number of bits. |
||
166 | ; IN assertion: length <= 16 and value fits in length bits. |
||
167 | |||
168 | ;void (s, value, length) |
||
169 | ; deflate_state* s |
||
170 | ; int value ;value to send |
||
171 | ; int length ;number of bits |
||
172 | align 4 |
||
173 | proc send_bits uses eax ecx edi, s:dword, value:dword, length:dword |
||
174 | ; Tracevv((stderr," l %2d v %4x ", length, value)); |
||
175 | ;if DEBUG eq 1 |
||
176 | mov eax,[length] |
||
177 | cmp eax,0 |
||
178 | jle @f |
||
179 | cmp eax,15 |
||
180 | jle .end1 |
||
181 | @@: |
||
6639 | IgorA | 182 | zlib_assert 'invalid length' ;Assert(..>0 && ..<=15) |
6617 | IgorA | 183 | .end1: |
184 | mov edi,[s] |
||
6847 | IgorA | 185 | ;;add [edi+deflate_state.bits_sent],eax |
6617 | IgorA | 186 | |
187 | ; If not enough room in bi_buf, use (valid) bits from bi_buf and |
||
188 | ; (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) |
||
189 | ; unused bits in value. |
||
190 | |||
191 | mov ecx,Buf_size |
||
192 | sub ecx,eax |
||
193 | cmp [edi+deflate_state.bi_valid],ecx |
||
194 | jle @f ;if (..>..) |
||
195 | mov eax,[value] |
||
196 | mov ecx,[edi+deflate_state.bi_valid] |
||
197 | shl eax,cl |
||
198 | or [edi+deflate_state.bi_buf],ax |
||
199 | mov cx,[edi+deflate_state.bi_buf] |
||
200 | put_short edi, cx |
||
201 | mov eax,[value] |
||
202 | mov ecx,Buf_size |
||
203 | sub ecx,[edi+deflate_state.bi_valid] |
||
6851 | IgorA | 204 | sar eax,cl |
6617 | IgorA | 205 | mov [edi+deflate_state.bi_buf],ax |
206 | mov eax,[length] |
||
207 | sub eax,Buf_size |
||
208 | jmp .end0 |
||
209 | @@: ;else |
||
210 | mov eax,[value] |
||
211 | mov ecx,[edi+deflate_state.bi_valid] |
||
212 | shl eax,cl |
||
213 | or [edi+deflate_state.bi_buf],ax |
||
214 | mov eax,[length] |
||
215 | .end0: |
||
216 | add [edi+deflate_state.bi_valid],eax |
||
217 | ;else ;!DEBUG |
||
218 | |||
219 | ;{ int len = length; |
||
220 | ; if (s->bi_valid > (int)Buf_size - len) { |
||
221 | ; int val = value; |
||
222 | ; s->bi_buf |= (uint_16)val << s->bi_valid; |
||
223 | ; put_short(s, s->bi_buf); |
||
224 | ; s->bi_buf = (uint_16)val >> (Buf_size - s->bi_valid); |
||
225 | ; s->bi_valid += len - Buf_size; |
||
226 | ; } else { |
||
227 | ; s->bi_buf |= (uint_16)(value) << s->bi_valid; |
||
228 | ; s->bi_valid += len; |
||
229 | ; } |
||
230 | ;} |
||
231 | ;end if ;DEBUG |
||
232 | ret |
||
233 | endp |
||
234 | |||
235 | ; the arguments must not have side effects |
||
236 | |||
237 | ; =========================================================================== |
||
238 | ; Initialize the various 'constant' tables. |
||
239 | |||
240 | ;int static_init_done = 0 |
||
241 | |||
242 | ;void () |
||
243 | align 4 |
||
244 | proc tr_static_init |
||
245 | if GEN_TREES_H eq 1 |
||
246 | |||
247 | ; int n ;iterates over tree elements |
||
248 | ; int bits ;bit counter |
||
249 | ; int length ;length value |
||
250 | ; int code ;code value |
||
251 | ; int dist ;distance index |
||
252 | ; uint_16 bl_count[MAX_BITS+1]; |
||
253 | ; number of codes at each bit length for an optimal tree |
||
254 | |||
255 | ; if (static_init_done) return; |
||
256 | |||
257 | ; For some embedded targets, global variables are not initialized: |
||
258 | ;if NO_INIT_GLOBAL_POINTERS |
||
259 | ; static_l_desc.static_tree = static_ltree; |
||
260 | ; static_l_desc.extra_bits = extra_lbits; |
||
261 | ; static_d_desc.static_tree = static_dtree; |
||
262 | ; static_d_desc.extra_bits = extra_dbits; |
||
263 | ; static_bl_desc.extra_bits = extra_blbits; |
||
264 | ;end if |
||
265 | |||
266 | ; Initialize the mapping length (0..255) -> length code (0..28) |
||
267 | ; length = 0; |
||
268 | ; for (code = 0; code < LENGTH_CODES-1; code++) { |
||
269 | ; base_length[code] = length; |
||
270 | ; for (n = 0; n < (1< |
||
271 | ; _length_code[length++] = (uch)code; |
||
272 | ; } |
||
273 | ; } |
||
274 | ; Assert (length == 256, "tr_static_init: length != 256"); |
||
275 | ; Note that the length 255 (match length 258) can be represented |
||
276 | ; in two different ways: code 284 + 5 bits or code 285, so we |
||
277 | ; overwrite length_code[255] to use the best encoding: |
||
278 | |||
279 | ; _length_code[length-1] = (uch)code; |
||
280 | |||
281 | ; Initialize the mapping dist (0..32K) -> dist code (0..29) |
||
282 | ; dist = 0; |
||
283 | ; for (code = 0 ; code < 16; code++) { |
||
284 | ; base_dist[code] = dist; |
||
285 | ; for (n = 0; n < (1< |
||
286 | ; _dist_code[dist++] = (uch)code; |
||
287 | ; } |
||
288 | ; } |
||
289 | ; Assert (dist == 256, "tr_static_init: dist != 256"); |
||
290 | ; dist >>= 7; /* from now on, all distances are divided by 128 */ |
||
291 | ; for ( ; code < D_CODES; code++) { |
||
292 | ; base_dist[code] = dist << 7; |
||
293 | ; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { |
||
294 | ; _dist_code[256 + dist++] = (uch)code; |
||
295 | ; } |
||
296 | ; } |
||
297 | ; Assert (dist == 256, "tr_static_init: 256+dist != 512"); |
||
298 | |||
299 | ; Construct the codes of the static literal tree |
||
300 | ; for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; |
||
301 | ; n = 0; |
||
302 | ; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; |
||
303 | ; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; |
||
304 | ; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; |
||
305 | ; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; |
||
306 | ; Codes 286 and 287 do not exist, but we must include them in the |
||
307 | ; tree construction to get a canonical Huffman tree (longest code |
||
308 | ; all ones) |
||
309 | |||
310 | ; gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); |
||
311 | |||
312 | ; The static distance tree is trivial: |
||
313 | ; for (n = 0; n < D_CODES; n++) { |
||
314 | ; static_dtree[n].Len = 5; |
||
315 | ; static_dtree[n].Code = bi_reverse((unsigned)n, 5); |
||
316 | ; } |
||
317 | ; static_init_done = 1; |
||
318 | |||
319 | if GEN_TREES_H eq 1 |
||
320 | call gen_trees_header |
||
321 | end if |
||
322 | end if ;(GEN_TREES_H) | !(STDC) |
||
323 | ret |
||
324 | endp |
||
325 | |||
326 | ; =========================================================================== |
||
327 | ; Genererate the file trees.h describing the static trees. |
||
328 | |||
329 | ;# define SEPARATOR(i, last, width) \ |
||
330 | ; ((i) == (last)? "\n};\n\n" : \ |
||
331 | ; ((i) % (width) == (width)-1 ? ",\n" : ", ")) |
||
332 | |||
333 | ;void () |
||
334 | align 4 |
||
335 | proc gen_trees_header |
||
336 | ; FILE *header = fopen("trees.inc", "w"); |
||
337 | ; int i; |
||
338 | |||
339 | ; Assert (header != NULL, "Can't open trees.inc"); |
||
340 | ; fprintf(header, |
||
341 | ; "/* header created automatically with -DGEN_TREES_H */\n\n"); |
||
342 | |||
343 | ; fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); |
||
344 | ; for (i = 0; i < L_CODES+2; i++) { |
||
345 | ; fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, |
||
346 | ; static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); |
||
347 | ; } |
||
348 | |||
349 | ; fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); |
||
350 | ; for (i = 0; i < D_CODES; i++) { |
||
351 | ; fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, |
||
352 | ; static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); |
||
353 | ; } |
||
354 | |||
355 | ; fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); |
||
356 | ; for (i = 0; i < DIST_CODE_LEN; i++) { |
||
357 | ; fprintf(header, "%2u%s", _dist_code[i], |
||
358 | ; SEPARATOR(i, DIST_CODE_LEN-1, 20)); |
||
359 | ; } |
||
360 | |||
361 | ; fprintf(header, |
||
362 | ; "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); |
||
363 | ; for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { |
||
364 | ; fprintf(header, "%2u%s", _length_code[i], |
||
365 | ; SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); |
||
366 | ; } |
||
367 | |||
368 | ; fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); |
||
369 | ; for (i = 0; i < LENGTH_CODES; i++) { |
||
370 | ; fprintf(header, "%1u%s", base_length[i], |
||
371 | ; SEPARATOR(i, LENGTH_CODES-1, 20)); |
||
372 | ; } |
||
373 | |||
374 | ; fprintf(header, "local const int base_dist[D_CODES] = {\n"); |
||
375 | ; for (i = 0; i < D_CODES; i++) { |
||
376 | ; fprintf(header, "%5u%s", base_dist[i], |
||
377 | ; SEPARATOR(i, D_CODES-1, 10)); |
||
378 | ; } |
||
379 | |||
380 | ; fclose(header); |
||
381 | ret |
||
382 | endp |
||
383 | |||
384 | ; =========================================================================== |
||
385 | ; Initialize the tree data structures for a new zlib stream. |
||
386 | |||
6847 | IgorA | 387 | ;void (deflate_state* s) |
6617 | IgorA | 388 | align 4 |
389 | proc _tr_init uses eax edi, s:dword |
||
390 | mov edi,[s] |
||
391 | call tr_static_init |
||
392 | |||
393 | mov eax,edi |
||
394 | add eax,deflate_state.dyn_ltree |
||
395 | mov [edi+deflate_state.l_desc.dyn_tree],eax |
||
396 | mov [edi+deflate_state.l_desc.stat_desc],static_l_desc |
||
397 | |||
398 | add eax,deflate_state.dyn_dtree-deflate_state.dyn_ltree |
||
399 | mov [edi+deflate_state.d_desc.dyn_tree],eax |
||
400 | mov [edi+deflate_state.d_desc.stat_desc],static_d_desc |
||
401 | |||
402 | add eax,deflate_state.bl_tree-deflate_state.dyn_dtree |
||
403 | mov [edi+deflate_state.bl_desc.dyn_tree],eax |
||
404 | mov [edi+deflate_state.bl_desc.stat_desc],static_bl_desc; |
||
405 | |||
406 | mov word[edi+deflate_state.bi_buf],0 |
||
407 | mov dword[edi+deflate_state.bi_valid],0 |
||
408 | if DEBUG eq 1 |
||
409 | mov dword[edi+deflate_state.compressed_len],0 |
||
410 | mov dword[edi+deflate_state.bits_sent],0 |
||
411 | end if |
||
412 | |||
413 | ; Initialize the first block of the first file: |
||
414 | stdcall init_block,edi |
||
415 | ret |
||
416 | endp |
||
417 | |||
418 | ; =========================================================================== |
||
419 | ; Initialize a new block. |
||
420 | |||
6847 | IgorA | 421 | ;void (deflate_state* s) |
6617 | IgorA | 422 | align 4 |
423 | proc init_block uses eax ecx edi, s:dword |
||
424 | mov edi,[s] |
||
425 | |||
426 | ; Initialize the trees. |
||
427 | mov eax,edi |
||
428 | add eax,deflate_state.dyn_ltree+Freq |
||
429 | mov ecx,L_CODES |
||
430 | @@: |
||
431 | mov word[eax],0 |
||
432 | add eax,sizeof.ct_data |
||
433 | loop @b |
||
434 | mov eax,edi |
||
435 | add eax,deflate_state.dyn_dtree+Freq |
||
436 | mov ecx,D_CODES |
||
437 | @@: |
||
438 | mov word[eax],0 |
||
439 | add eax,sizeof.ct_data |
||
440 | loop @b |
||
441 | mov eax,edi |
||
442 | add eax,deflate_state.bl_tree+Freq |
||
443 | mov ecx,BL_CODES |
||
444 | @@: |
||
445 | mov word[eax],0 |
||
446 | add eax,sizeof.ct_data |
||
447 | loop @b |
||
448 | |||
6799 | IgorA | 449 | mov word[edi+sizeof.ct_data*END_BLOCK+deflate_state.dyn_ltree+Freq],1 |
6617 | IgorA | 450 | mov dword[edi+deflate_state.static_len],0 |
451 | mov dword[edi+deflate_state.opt_len],0 |
||
452 | mov dword[edi+deflate_state.matches],0 |
||
453 | mov dword[edi+deflate_state.last_lit],0 |
||
454 | ret |
||
455 | endp |
||
456 | |||
457 | SMALLEST equ 1 |
||
458 | ; Index within the heap array of least frequent node in the Huffman tree |
||
459 | |||
460 | |||
461 | ; =========================================================================== |
||
462 | ; Remove the smallest element from the heap and recreate the heap with |
||
463 | ; one less element. Updates heap and heap_len. |
||
464 | |||
465 | macro pqremove s, tree, top |
||
466 | { |
||
467 | mov eax,s |
||
6847 | IgorA | 468 | add eax,deflate_state.heap+4*SMALLEST |
6617 | IgorA | 469 | movzx top,word[eax] |
470 | push ebx |
||
471 | mov ebx,[s+deflate_state.heap_len] |
||
6847 | IgorA | 472 | mov ebx,[s+deflate_state.heap+4*ebx] |
473 | mov [eax],ebx |
||
6617 | IgorA | 474 | dec dword[s+deflate_state.heap_len] |
475 | pop ebx |
||
476 | stdcall pqdownheap, s, tree, SMALLEST |
||
477 | } |
||
478 | |||
479 | ; =========================================================================== |
||
480 | ; Compares to subtrees, using the tree depth as tie breaker when |
||
481 | ; the subtrees have equal frequency. This minimizes the worst case length. |
||
482 | |||
483 | macro smaller tree, n, m, depth, m_end |
||
484 | { |
||
485 | ;if (..<.. || (..==.. && depth[n] <= depth[m])) |
||
486 | local .end0 |
||
6847 | IgorA | 487 | mov eax,n |
6617 | IgorA | 488 | imul eax,sizeof.ct_data |
489 | add eax,tree |
||
490 | mov ax,word[eax+Freq] |
||
6847 | IgorA | 491 | mov ebx,m |
6617 | IgorA | 492 | imul ebx,sizeof.ct_data |
493 | add ebx,tree |
||
494 | mov bx,word[ebx+Freq] |
||
495 | cmp ax,bx |
||
496 | jl .end0 |
||
497 | jne m_end |
||
6847 | IgorA | 498 | mov eax,n |
6815 | IgorA | 499 | mov al,byte[eax+depth] |
6847 | IgorA | 500 | mov ebx,m |
6815 | IgorA | 501 | cmp al,byte[ebx+depth] |
6617 | IgorA | 502 | jg m_end |
503 | .end0: |
||
504 | } |
||
505 | |||
506 | ; =========================================================================== |
||
507 | ; Restore the heap property by moving down the tree starting at node k, |
||
508 | ; exchanging a node with the smallest of its two sons if necessary, stopping |
||
509 | ; when the heap property is re-established (each father smaller than its |
||
510 | ; two sons). |
||
511 | |||
512 | ;void (s, tree, k) |
||
513 | ; deflate_state* s |
||
514 | ; ct_data* tree ;the tree to restore |
||
515 | ; int k ;node to move down |
||
516 | align 4 |
||
517 | proc pqdownheap, s:dword, tree:dword, k:dword |
||
518 | pushad |
||
6815 | IgorA | 519 | ;ecx - v dw |
6617 | IgorA | 520 | mov edi,[s] |
6815 | IgorA | 521 | mov esi,[k] |
6847 | IgorA | 522 | mov ecx,[edi+deflate_state.heap+4*esi] |
6617 | IgorA | 523 | shl esi,1 |
524 | ;esi = j ;left son of k |
||
525 | .cycle0: ;while (..<=..) |
||
526 | cmp esi,[edi+deflate_state.heap_len] |
||
527 | jg .cycle0end |
||
528 | ; Set j to the smallest of the two sons: |
||
529 | ;;cmp esi,[edi+deflate_state.heap_len] |
||
530 | jge .end1 ;if (..<.. && |
||
531 | mov edx,esi |
||
6847 | IgorA | 532 | shl edx,2 |
6617 | IgorA | 533 | add edx,edi |
534 | add edx,deflate_state.heap |
||
6847 | IgorA | 535 | smaller [tree], dword[edx+4], dword[edx], edi+deflate_state.depth, .end1 |
6617 | IgorA | 536 | inc esi |
537 | .end1: |
||
538 | ; Exit if v is smaller than both sons |
||
6847 | IgorA | 539 | mov edx,[edi+deflate_state.heap+4*esi] |
540 | smaller [tree], ecx, edx, edi+deflate_state.depth, .end2 |
||
6617 | IgorA | 541 | jmp .cycle0end ;break |
542 | .end2: |
||
543 | ; Exchange v with the smallest son |
||
6815 | IgorA | 544 | ;;mov dx,[edi+deflate_state.heap+2*esi] |
6617 | IgorA | 545 | mov eax,[k] |
6847 | IgorA | 546 | mov [edi+deflate_state.heap+4*eax],edx |
6617 | IgorA | 547 | mov [k],esi |
548 | ; And continue down the tree, setting j to the left son of k |
||
549 | shl esi,1 |
||
550 | jmp .cycle0 |
||
6815 | IgorA | 551 | align 4 |
6617 | IgorA | 552 | .cycle0end: |
553 | mov eax,[k] |
||
6847 | IgorA | 554 | mov [edi+deflate_state.heap+4*eax],ecx |
6617 | IgorA | 555 | popad |
556 | ret |
||
557 | endp |
||
558 | |||
559 | ; =========================================================================== |
||
560 | ; Compute the optimal bit lengths for a tree and update the total bit length |
||
561 | ; for the current block. |
||
562 | ; IN assertion: the fields freq and dad are set, heap[heap_max] and |
||
563 | ; above are the tree nodes sorted by increasing frequency. |
||
564 | ; OUT assertions: the field len is set to the optimal bit length, the |
||
565 | ; array bl_count contains the frequencies for each bit length. |
||
566 | ; The length opt_len is updated; static_len is also updated if stree is |
||
567 | ; not null. |
||
568 | |||
6854 | IgorA | 569 | ;void (deflate_state* s, tree_desc* desc) |
570 | align 16 |
||
6617 | IgorA | 571 | proc gen_bitlen, s:dword, desc:dword |
572 | locals |
||
573 | tree dd ? ;ct_data* ;= desc.dyn_tree |
||
574 | max_code dd ? ;int ;= desc.max_code |
||
575 | stree dd ? ;ct_data* ;= desc.stat_desc.static_tree |
||
576 | extra dd ? ;intf* ;= desc.stat_desc.extra_bits |
||
577 | base dd ? ;int ;= desc.stat_desc.extra_base |
||
578 | max_length dd ? ;int ;= desc.stat_desc.max_length |
||
579 | h dd ? ;int ;heap index |
||
580 | m dd ? ;int ;iterate over the tree elements |
||
581 | bits dd ? ;int ;bit length |
||
582 | xbits dd ? ;int ;extra bits |
||
583 | f dw ? ;uint_16 ;frequency |
||
584 | overflow dd 0 ;int ;number of elements with bit length too large |
||
585 | endl |
||
586 | pushad |
||
587 | mov edi,[s] |
||
588 | mov edx,[desc] |
||
589 | mov eax,[edx+tree_desc.dyn_tree] |
||
590 | mov [tree],eax |
||
591 | mov eax,[edx+tree_desc.max_code] |
||
592 | mov [max_code],eax |
||
593 | mov ebx,[edx+tree_desc.stat_desc] |
||
594 | mov eax,[ebx+static_tree_desc.static_tree] |
||
595 | mov [stree],eax |
||
596 | mov eax,[ebx+static_tree_desc.extra_bits] |
||
597 | mov [extra],eax |
||
598 | mov eax,[ebx+static_tree_desc.extra_base] |
||
599 | mov [base],eax |
||
600 | mov eax,[ebx+static_tree_desc.max_length] |
||
601 | mov [max_length],eax |
||
602 | |||
603 | xor ecx,ecx |
||
604 | .cycle0: |
||
605 | cmp ecx,MAX_BITS |
||
606 | jg .cycle0end ;for (..;..<=..;..) |
||
607 | mov word[edi+deflate_state.bl_count+2*ecx],0 |
||
608 | inc ecx |
||
609 | jmp .cycle0 |
||
610 | align 4 |
||
611 | .cycle0end: |
||
612 | |||
613 | ; In a first pass, compute the optimal bit lengths (which may |
||
614 | ; overflow in the case of the bit length tree). |
||
615 | |||
616 | mov eax,[edi+deflate_state.heap_max] |
||
6847 | IgorA | 617 | mov eax,[edi+deflate_state.heap+4*eax] |
6617 | IgorA | 618 | imul eax,sizeof.ct_data |
619 | add eax,[tree] |
||
620 | mov word[eax+Len],0 ;root of the heap |
||
621 | |||
622 | mov eax,[edi+deflate_state.heap_max] |
||
623 | inc eax |
||
624 | mov [h],eax |
||
6854 | IgorA | 625 | jmp @f |
626 | align 4 |
||
6617 | IgorA | 627 | .cycle1: |
6854 | IgorA | 628 | inc dword[h] |
629 | @@: |
||
6617 | IgorA | 630 | cmp dword[h],HEAP_SIZE |
631 | jge .cycle1end ;for (..;..<..;..) |
||
6854 | IgorA | 632 | mov eax,[h] |
633 | mov ecx,[edi+4*eax+deflate_state.heap] |
||
6617 | IgorA | 634 | ;ecx = n |
6854 | IgorA | 635 | mov edx,[tree] |
636 | movzx eax,word[edx+sizeof.ct_data*ecx+Dad] |
||
637 | movzx eax,word[edx+sizeof.ct_data*eax+Len] |
||
6617 | IgorA | 638 | inc eax |
639 | mov [bits],eax ;bits = tree[tree[n].Dad].Len + 1 |
||
640 | mov eax,[max_length] |
||
641 | cmp [bits],eax |
||
642 | jle @f ;if (..>..) |
||
643 | mov [bits],eax |
||
644 | inc dword[overflow] |
||
645 | @@: |
||
6854 | IgorA | 646 | mov eax,[bits] |
647 | mov [edx+sizeof.ct_data*ecx+Len],ax |
||
6617 | IgorA | 648 | ; We overwrite tree[n].Dad which is no longer needed |
649 | |||
650 | cmp ecx,[max_code] |
||
6854 | IgorA | 651 | jg .cycle1 ;if (..>..) continue ;not a leaf node |
6617 | IgorA | 652 | |
6854 | IgorA | 653 | inc word[edi+2*eax+deflate_state.bl_count] |
6617 | IgorA | 654 | mov dword[xbits],0 |
655 | cmp ecx,[base] |
||
656 | jl @f ;if (..>=..) |
||
657 | mov eax,ecx |
||
658 | sub eax,[base] |
||
659 | shl eax,2 ;*= sizeof.dd |
||
660 | add eax,[extra] |
||
661 | mov eax,[eax] |
||
662 | mov [xbits],eax |
||
663 | @@: |
||
6854 | IgorA | 664 | movzx eax,word[edx+sizeof.ct_data*ecx+Freq] |
6617 | IgorA | 665 | mov [f],ax |
666 | mov esi,[bits] |
||
667 | add esi,[xbits] |
||
668 | imul eax,esi |
||
669 | add [edi+deflate_state.opt_len],eax |
||
670 | cmp dword[stree],0 |
||
671 | je @f ;if (..) |
||
672 | movzx eax,word[f] |
||
673 | mov esi,sizeof.ct_data |
||
674 | imul esi,ecx |
||
6854 | IgorA | 675 | add esi,[tree] ;;;must be [stree] but don't work |
6617 | IgorA | 676 | movzx esi,word[esi+Len] |
677 | add esi,[xbits] |
||
678 | imul eax,esi |
||
679 | add [edi+deflate_state.static_len],eax |
||
680 | @@: |
||
681 | jmp .cycle1 |
||
682 | align 4 |
||
683 | .cycle1end: |
||
684 | cmp dword[overflow],0 |
||
685 | je .end_f ;if (..==0) return |
||
686 | |||
687 | ; Trace((stderr,"\nbit length overflow\n")); |
||
688 | ; This happens for example on obj2 and pic of the Calgary corpus |
||
689 | |||
690 | ; Find the first bit length which could increase: |
||
691 | .cycle2: ;do |
||
692 | mov eax,[max_length] |
||
693 | dec eax |
||
694 | mov [bits],eax |
||
695 | shl eax,1 ;*= sizeof.dw |
||
696 | add eax,edi |
||
697 | add eax,deflate_state.bl_count |
||
698 | @@: |
||
699 | cmp word[eax],0 |
||
700 | jne @f ;while (..==0) bits-- |
||
701 | dec dword[bits] |
||
702 | sub eax,2 |
||
703 | jmp @b |
||
6813 | IgorA | 704 | align 4 |
6617 | IgorA | 705 | @@: |
706 | dec word[eax] ;move one leaf down the tree |
||
707 | add word[eax+2],2 ;move one overflow item as its brother |
||
708 | mov eax,[max_length] |
||
709 | dec word[edi+deflate_state.bl_count+2*eax] |
||
710 | ; The brother of the overflow item also moves one step up, |
||
711 | ; but this does not affect bl_count[max_length] |
||
712 | |||
713 | sub dword[overflow],2 |
||
714 | cmp dword[overflow],0 |
||
715 | jg .cycle2 ;while (..>0) |
||
716 | |||
717 | ; Now recompute all bit lengths, scanning in increasing frequency. |
||
718 | ; h is still equal to HEAP_SIZE. (It is simpler to reconstruct all |
||
719 | ; lengths instead of fixing only the wrong ones. This idea is taken |
||
720 | ; from 'ar' written by Haruhiko Okumura.) |
||
721 | |||
722 | mov eax,[max_length] |
||
723 | mov [bits],eax |
||
724 | .cycle3: |
||
725 | cmp dword[bits],0 |
||
726 | je .end_f ;for (..;..!=0;..) |
||
727 | mov eax,[bits] |
||
6854 | IgorA | 728 | movzx ecx,word[edi+2*eax+deflate_state.bl_count] |
6617 | IgorA | 729 | .cycle4: ;while (..!=0) |
6854 | IgorA | 730 | test ecx,ecx |
731 | jz .cycle4end |
||
6617 | IgorA | 732 | dec dword[h] |
733 | mov eax,[h] |
||
6854 | IgorA | 734 | mov eax,[edi+4*eax+deflate_state.heap] |
6617 | IgorA | 735 | mov [m],eax ;m = s.heap[--h] |
736 | cmp eax,[max_code] |
||
6813 | IgorA | 737 | jg .cycle4 ;if (..>..) continue |
6617 | IgorA | 738 | mov esi,[m] |
739 | mov eax,[bits] |
||
6854 | IgorA | 740 | cmp word[edx+sizeof.ct_data*esi+Len],ax |
6617 | IgorA | 741 | je @f ;if (..!=..) |
742 | ; Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); |
||
743 | movzx ebx,word[esi+Len] |
||
744 | sub eax,ebx |
||
745 | movzx ebx,word[esi+Freq] |
||
746 | imul eax,ebx ;eax = (bits - tree[m].Len) * tree[m].Freq |
||
747 | add [edi+deflate_state.opt_len],eax |
||
748 | mov eax,[bits] |
||
749 | mov word[esi+Len],ax |
||
750 | @@: |
||
751 | dec ecx |
||
752 | jmp .cycle4 |
||
6813 | IgorA | 753 | align 4 |
6617 | IgorA | 754 | .cycle4end: |
755 | dec dword[bits] |
||
756 | jmp .cycle3 |
||
6813 | IgorA | 757 | align 4 |
6617 | IgorA | 758 | .end_f: |
759 | popad |
||
760 | ret |
||
761 | endp |
||
762 | |||
763 | ; =========================================================================== |
||
764 | ; Generate the codes for a given tree and bit counts (which need not be |
||
765 | ; optimal). |
||
766 | ; IN assertion: the array bl_count contains the bit length statistics for |
||
767 | ; the given tree and the field len is set for all tree elements. |
||
768 | ; OUT assertion: the field code is set for all tree elements of non |
||
769 | ; zero code length. |
||
770 | |||
771 | ;void (tree, max_code, bl_count) |
||
772 | ; ct_data *tree ;the tree to decorate |
||
773 | ; int max_code ;largest code with non zero frequency |
||
774 | ; uint_16p bl_count ;number of codes at each bit length |
||
775 | align 4 |
||
776 | proc gen_codes uses eax ebx ecx edx edi, tree:dword, max_code:dword, bl_count:dword |
||
777 | locals |
||
778 | u_code dw 0 ;uint_16 ;running code value |
||
779 | bits dd 1 ;int ;bit index |
||
780 | next_code rw MAX_BITS+1 ;uint_16[] ;next code value for each bit length |
||
781 | endl |
||
782 | ; The distribution counts are first used to generate the code values |
||
783 | ; without bit reversal. |
||
784 | mov ebx,ebp |
||
785 | sub ebx,2*(MAX_BITS+1) |
||
786 | |||
787 | .cycle0: ;for (..;..<=..;..) |
||
788 | cmp dword[bits],MAX_BITS |
||
789 | jg .cycle0end |
||
790 | mov eax,[bits] |
||
791 | dec eax |
||
792 | shl eax,1 |
||
793 | add eax,[bl_count] |
||
794 | mov ax,word[eax] |
||
795 | add ax,[u_code] |
||
796 | shl ax,1 ;ax = (u_code + bl_count[bits-1]) << 1 |
||
797 | mov [u_code],ax |
||
798 | mov ecx,[bits] |
||
799 | mov word[ebx+2*ecx],ax ;next_code[bits] = u_code |
||
800 | inc dword[bits] |
||
801 | jmp .cycle0 |
||
802 | .cycle0end: |
||
803 | ; Check that the bit counts in bl_count are consistent. The last code |
||
804 | ; must be all ones. |
||
805 | |||
806 | mov eax,[bl_count] |
||
807 | mov ax,word[eax+2*MAX_BITS] |
||
808 | add ax,[u_code] |
||
809 | dec ax |
||
810 | cmp ax,(1 shl MAX_BITS)-1 |
||
811 | je @f |
||
6639 | IgorA | 812 | zlib_assert 'inconsistent bit counts' ;Assert(..==..) |
6617 | IgorA | 813 | @@: |
814 | ; Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); |
||
815 | |||
816 | xor ecx,ecx ;n = 0 |
||
817 | .cycle1: ;for (..;..<=..;..) |
||
818 | cmp ecx,[max_code] |
||
819 | jg .cycle1end |
||
820 | mov edx,sizeof.ct_data |
||
821 | imul edx,ecx |
||
822 | add edx,[tree] ;edx = &tree[n] |
||
823 | movzx edi,word[edx+Len] |
||
824 | cmp edi,0 |
||
825 | jne @f ;if (..==0) continue |
||
826 | inc ecx |
||
827 | jmp .cycle1 |
||
828 | @@: |
||
829 | ; Now reverse the bits |
||
830 | movzx eax,word[ebx+2*edi] |
||
831 | stdcall bi_reverse, eax, edi |
||
832 | mov word[edx+Code],ax |
||
833 | inc word[ebx+2*edi] |
||
834 | |||
835 | ; Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", |
||
836 | ; n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); |
||
837 | inc ecx |
||
838 | jmp .cycle1 |
||
839 | .cycle1end: |
||
840 | ret |
||
841 | endp |
||
842 | |||
843 | ; =========================================================================== |
||
844 | ; Construct one Huffman tree and assigns the code bit strings and lengths. |
||
845 | ; Update the total bit length for the current block. |
||
846 | ; IN assertion: the field freq is set for all tree elements. |
||
847 | ; OUT assertions: the fields len and code are set to the optimal bit length |
||
848 | ; and corresponding code. The length opt_len is updated; static_len is |
||
849 | ; also updated if stree is not null. The field max_code is set. |
||
850 | |||
851 | ;void (s, desc) |
||
852 | ; deflate_state* s |
||
853 | ; tree_desc *desc ;the tree descriptor |
||
854 | align 4 |
||
855 | proc build_tree uses eax ebx ecx edx edi, s:dword, desc:dword |
||
856 | locals |
||
857 | tree dd ? ;ct_data* ;= desc.dyn_tree |
||
858 | stree dd ? ;ct_data* ;= desc.stat_desc.static_tree |
||
859 | elems dd ? ;int ;= desc.stat_desc.elems |
||
860 | m dd ? ;int ;iterate over heap elements |
||
861 | max_code dd -1 ;int ;largest code with non zero frequency |
||
862 | node dd ? ;int ;new node being created |
||
863 | endl |
||
864 | ; Construct the initial heap, with least frequent element in |
||
865 | ; heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. |
||
866 | ; heap[0] is not used. |
||
867 | mov ebx,[desc] |
||
868 | mov eax,[ebx+tree_desc.dyn_tree] |
||
869 | mov [tree],eax |
||
870 | mov ecx,[ebx+tree_desc.stat_desc] |
||
871 | mov eax,[ecx+static_tree_desc.static_tree] |
||
872 | mov [stree],eax |
||
873 | mov ecx,[ecx+static_tree_desc.elems] |
||
874 | mov [elems],ecx |
||
875 | mov edi,[s] |
||
6639 | IgorA | 876 | zlib_debug 'build_tree cycle0 ecx = %d',ecx |
6617 | IgorA | 877 | |
878 | mov dword[edi+deflate_state.heap_len],0 |
||
879 | mov dword[edi+deflate_state.heap_max],HEAP_SIZE |
||
880 | |||
6813 | IgorA | 881 | mov edx,[tree] |
882 | xor ecx,ecx |
||
6617 | IgorA | 883 | .cycle0: ;for (..;..<..;..) |
6813 | IgorA | 884 | cmp ecx,[elems] |
6854 | IgorA | 885 | jge .cycle1 |
6813 | IgorA | 886 | cmp word[edx+Freq],0 |
6617 | IgorA | 887 | je @f ;if (..!=0) |
888 | inc dword[edi+deflate_state.heap_len] |
||
889 | mov eax,[edi+deflate_state.heap_len] |
||
6813 | IgorA | 890 | mov [max_code],ecx |
6847 | IgorA | 891 | mov dword[edi+deflate_state.heap+4*eax],ecx |
6813 | IgorA | 892 | mov byte[edi+deflate_state.depth+ecx],0 |
6617 | IgorA | 893 | jmp .end0 |
894 | align 4 |
||
895 | @@: ;else |
||
6813 | IgorA | 896 | mov word[edx+Len],0 |
6617 | IgorA | 897 | .end0: |
6813 | IgorA | 898 | add edx,sizeof.ct_data |
899 | inc ecx |
||
900 | jmp .cycle0 |
||
6617 | IgorA | 901 | |
902 | ; The pkzip format requires that at least one distance code exists, |
||
903 | ; and that at least one bit should be sent even if there is only one |
||
904 | ; possible code. So to avoid special checks later on we force at least |
||
905 | ; two codes of non zero frequency. |
||
906 | |||
6854 | IgorA | 907 | align 4 |
6617 | IgorA | 908 | .cycle1: ;while (..<..) |
909 | cmp dword[edi+deflate_state.heap_len],2 |
||
910 | jge .cycle1end |
||
911 | inc dword[edi+deflate_state.heap_len] |
||
912 | xor eax,eax |
||
913 | cmp dword[max_code],2 |
||
914 | jge @f |
||
915 | inc dword[max_code] |
||
916 | mov eax,[max_code] |
||
917 | @@: |
||
918 | mov ecx,[edi+deflate_state.heap_len] |
||
6847 | IgorA | 919 | mov [edi+deflate_state.heap+4*ecx],eax |
6617 | IgorA | 920 | mov [node],eax |
921 | imul eax,sizeof.ct_data |
||
922 | add eax,[tree] |
||
923 | mov word[eax+Freq],1 |
||
924 | mov eax,[node] |
||
925 | mov byte[edi+deflate_state.depth+eax],0 |
||
926 | dec dword[edi+deflate_state.opt_len] |
||
927 | cmp dword[stree],0 |
||
928 | je .cycle1 ;if (..) |
||
929 | mov eax,[node] |
||
930 | imul eax,sizeof.ct_data |
||
931 | add eax,[stree] |
||
932 | movzx eax,word[eax+Len] |
||
933 | sub [edi+deflate_state.static_len],eax |
||
934 | ; node is 0 or 1 so it does not have extra bits |
||
935 | jmp .cycle1 |
||
936 | align 4 |
||
937 | .cycle1end: |
||
938 | mov eax,[max_code] |
||
939 | mov [ebx+tree_desc.max_code],eax |
||
940 | |||
941 | ; The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, |
||
942 | ; establish sub-heaps of increasing lengths: |
||
943 | |||
944 | mov ecx,[edi+deflate_state.heap_len] |
||
6854 | IgorA | 945 | sar ecx,1 |
6617 | IgorA | 946 | .cycle2: ;for (..;..>=..;..) |
947 | cmp ecx,1 |
||
948 | jl .cycle2end |
||
949 | stdcall pqdownheap, edi, [tree], ecx |
||
950 | dec ecx |
||
951 | jmp .cycle2 |
||
952 | align 4 |
||
953 | .cycle2end: |
||
954 | |||
955 | ; Construct the Huffman tree by repeatedly combining the least two |
||
956 | ; frequent nodes. |
||
957 | |||
958 | mov eax,[elems] |
||
959 | mov [node],eax ;next internal node of the tree |
||
960 | .cycle3: ;do |
||
961 | pqremove edi, [tree], ecx ;n = node of least frequency |
||
962 | movzx edx,word[eax] |
||
963 | mov [m],edx ;m = node of next least frequency |
||
964 | |||
965 | mov eax,[edi+deflate_state.heap_max] |
||
966 | dec eax |
||
6847 | IgorA | 967 | mov [edi+deflate_state.heap+4*eax],ecx ;keep the nodes sorted by frequency |
6617 | IgorA | 968 | dec eax |
969 | mov [edi+deflate_state.heap_max],eax |
||
6847 | IgorA | 970 | mov [edi+deflate_state.heap+4*eax],edx |
6617 | IgorA | 971 | |
972 | ; Create a new node father of n and m |
||
973 | ;;mov edx,[m] |
||
974 | imul edx,sizeof.ct_data |
||
975 | add edx,[tree] |
||
976 | mov ax,word[edx+Freq] |
||
977 | mov edx,ecx |
||
978 | imul edx,sizeof.ct_data |
||
979 | add edx,[tree] |
||
980 | add ax,word[edx+Freq] |
||
981 | mov edx,[node] |
||
982 | imul edx,sizeof.ct_data |
||
983 | add edx,[tree] |
||
984 | mov word[edx+Freq],ax |
||
985 | |||
986 | mov eax,ecx |
||
987 | add eax,edi |
||
6813 | IgorA | 988 | mov al,byte[eax+deflate_state.depth] |
6617 | IgorA | 989 | mov edx,[m] |
990 | add edx,edi |
||
6813 | IgorA | 991 | mov ah,byte[edx+deflate_state.depth] |
6617 | IgorA | 992 | cmp al,ah |
6815 | IgorA | 993 | jge @f ;if (al>=ah) al=al : al=ah |
6617 | IgorA | 994 | mov al,ah |
995 | @@: |
||
996 | inc al |
||
997 | mov edx,[node] |
||
998 | add edx,edi |
||
6813 | IgorA | 999 | mov byte[edx+deflate_state.depth],al |
6617 | IgorA | 1000 | |
1001 | mov eax,[node] |
||
1002 | mov edx,[m] |
||
1003 | imul edx,sizeof.ct_data |
||
1004 | add edx,[tree] |
||
1005 | mov [edx+Dad],ax |
||
1006 | mov edx,ecx |
||
1007 | imul edx,sizeof.ct_data |
||
1008 | add edx,[tree] |
||
1009 | mov [edx+Dad],ax |
||
1010 | ;if DUMP_BL_TREE eq 1 |
||
1011 | ; if (tree == s->bl_tree) { |
||
1012 | ; fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", |
||
1013 | ; node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); |
||
1014 | ; } |
||
1015 | ;end if |
||
1016 | ; and insert the new node in the heap |
||
1017 | mov ecx,[node] |
||
6847 | IgorA | 1018 | mov [edi+deflate_state.heap+4*SMALLEST],ecx |
6617 | IgorA | 1019 | inc dword[node] |
1020 | stdcall pqdownheap, edi, [tree], SMALLEST |
||
1021 | cmp dword[edi+deflate_state.heap_len],2 |
||
1022 | jge .cycle3 ;while (..>=..) |
||
1023 | |||
6847 | IgorA | 1024 | mov ecx,[edi+deflate_state.heap+4*SMALLEST] |
6617 | IgorA | 1025 | dec dword[edi+deflate_state.heap_max] |
1026 | mov eax,[edi+deflate_state.heap_max] |
||
6847 | IgorA | 1027 | mov [edi+deflate_state.heap+4*eax],ecx |
6617 | IgorA | 1028 | |
1029 | ; At this point, the fields freq and dad are set. We can now |
||
1030 | ; generate the bit lengths. |
||
1031 | |||
1032 | stdcall gen_bitlen, edi, [desc] |
||
1033 | |||
1034 | ; The field len is now set, we can generate the bit codes |
||
1035 | mov eax,edi |
||
1036 | add eax,deflate_state.bl_count |
||
1037 | stdcall gen_codes, [tree], [max_code], eax |
||
1038 | ret |
||
1039 | endp |
||
1040 | |||
1041 | ; =========================================================================== |
||
1042 | ; Scan a literal or distance tree to determine the frequencies of the codes |
||
1043 | ; in the bit length tree. |
||
1044 | |||
1045 | ;void (s, tree, max_code) |
||
1046 | ; deflate_state* s |
||
1047 | ; ct_data *tree ;the tree to be scanned |
||
1048 | ; int max_code ;and its largest code of non zero frequency |
||
1049 | align 4 |
||
1050 | proc scan_tree uses eax ebx ecx edi, s:dword, tree:dword, max_code:dword |
||
1051 | locals |
||
1052 | n dd ? ;int ;iterates over all tree elements |
||
1053 | prevlen dd -1 ;int ;last emitted length |
||
1054 | curlen dd ? ;int ;length of current code |
||
1055 | nextlen dd ? ;int ;= tree[0].Len ;length of next code |
||
1056 | count dd 0 ;int ;repeat count of the current code |
||
1057 | max_count dd 7 ;int ;max repeat count |
||
1058 | min_count dd 4 ;int ;min repeat count |
||
1059 | endl |
||
1060 | mov edi,[s] |
||
1061 | mov eax,[tree] |
||
1062 | movzx eax,word[eax+Len] |
||
1063 | mov [nextlen],eax |
||
6815 | IgorA | 1064 | test eax,eax |
1065 | jnz @f ;if (..==0) |
||
6617 | IgorA | 1066 | mov dword[max_count],138 |
1067 | mov dword[min_count],3 |
||
1068 | @@: |
||
1069 | mov eax,[max_code] |
||
1070 | inc eax |
||
1071 | imul eax,sizeof.ct_data |
||
1072 | add eax,[tree] |
||
1073 | mov word[eax+Len],0xffff ;guard |
||
1074 | |||
1075 | xor ecx,ecx |
||
6815 | IgorA | 1076 | align 4 |
6617 | IgorA | 1077 | .cycle0: |
1078 | cmp ecx,[max_code] |
||
1079 | jg .cycle0end ;for (..;..<=..;..) |
||
1080 | mov eax,[nextlen] |
||
1081 | mov [curlen],eax |
||
6815 | IgorA | 1082 | inc ecx |
1083 | mov eax,sizeof.ct_data |
||
1084 | imul eax,ecx |
||
6617 | IgorA | 1085 | add eax,[tree] |
1086 | movzx eax,word[eax+Len] |
||
1087 | mov [nextlen],eax |
||
1088 | inc dword[count] |
||
1089 | mov ebx,[count] |
||
1090 | cmp ebx,[max_count] |
||
1091 | jge .end0 |
||
1092 | mov eax,[nextlen] |
||
1093 | cmp [curlen],eax |
||
6815 | IgorA | 1094 | je .cycle0 ;if (..<.. && ..==..) continue |
1095 | align 4 |
||
6617 | IgorA | 1096 | .end0: |
1097 | cmp ebx,[min_count] |
||
1098 | jge .end1 ;else if (..<..) |
||
1099 | mov eax,[curlen] |
||
1100 | imul eax,sizeof.ct_data |
||
1101 | add eax,edi |
||
6813 | IgorA | 1102 | add word[eax+deflate_state.bl_tree+Freq],bx |
6617 | IgorA | 1103 | jmp .end4 |
6815 | IgorA | 1104 | align 4 |
6617 | IgorA | 1105 | .end1: |
1106 | cmp dword[curlen],0 |
||
1107 | je .end2 ;else if (..!=0) |
||
1108 | mov eax,[curlen] |
||
1109 | cmp eax,[prevlen] |
||
1110 | je @f ;if (..!=..) |
||
1111 | imul eax,sizeof.ct_data |
||
1112 | add eax,edi |
||
6813 | IgorA | 1113 | inc word[eax+deflate_state.bl_tree+Freq] |
6617 | IgorA | 1114 | @@: |
1115 | mov eax,REP_3_6 |
||
1116 | imul eax,sizeof.ct_data |
||
1117 | add eax,edi |
||
6813 | IgorA | 1118 | inc word[eax+deflate_state.bl_tree+Freq] |
6617 | IgorA | 1119 | jmp .end4 |
6815 | IgorA | 1120 | align 4 |
6617 | IgorA | 1121 | .end2: |
1122 | cmp ebx,10 |
||
1123 | jg .end3 ;else if (..<=..) |
||
1124 | mov eax,REPZ_3_10 |
||
1125 | imul eax,sizeof.ct_data |
||
1126 | add eax,edi |
||
6813 | IgorA | 1127 | inc word[eax+deflate_state.bl_tree+Freq] |
6617 | IgorA | 1128 | jmp .end4 |
6815 | IgorA | 1129 | align 4 |
6617 | IgorA | 1130 | .end3: ;else |
1131 | mov eax,REPZ_11_138 |
||
1132 | imul eax,sizeof.ct_data |
||
1133 | add eax,edi |
||
6813 | IgorA | 1134 | inc word[eax+deflate_state.bl_tree+Freq] |
6617 | IgorA | 1135 | .end4: |
6815 | IgorA | 1136 | mov dword[count],0 |
6617 | IgorA | 1137 | mov eax,[curlen] |
1138 | mov [prevlen],eax |
||
6815 | IgorA | 1139 | cmp dword[nextlen],0 |
6617 | IgorA | 1140 | jne .end5 ;if (..==0) |
1141 | mov dword[max_count],138 |
||
1142 | mov dword[min_count],3 |
||
6815 | IgorA | 1143 | jmp .cycle0 |
1144 | align 4 |
||
6617 | IgorA | 1145 | .end5: |
1146 | cmp eax,[nextlen] |
||
1147 | jne .end6 ;else if (..==..) |
||
1148 | mov dword[max_count],6 |
||
1149 | mov dword[min_count],3 |
||
6815 | IgorA | 1150 | jmp .cycle0 |
1151 | align 4 |
||
6617 | IgorA | 1152 | .end6: ;else |
1153 | mov dword[max_count],7 |
||
1154 | mov dword[min_count],4 |
||
1155 | jmp .cycle0 |
||
6815 | IgorA | 1156 | align 4 |
6617 | IgorA | 1157 | .cycle0end: |
1158 | ret |
||
1159 | endp |
||
1160 | |||
1161 | ; =========================================================================== |
||
1162 | ; Send a literal or distance tree in compressed form, using the codes in |
||
1163 | ; bl_tree. |
||
1164 | |||
1165 | ;void (s, tree, max_code) |
||
1166 | ; deflate_state* s |
||
1167 | ; ct_data *tree ;the tree to be scanned |
||
1168 | ; int max_code ;and its largest code of non zero frequency |
||
1169 | align 4 |
||
1170 | proc send_tree uses eax ebx ecx edi, s:dword, tree:dword, max_code:dword |
||
1171 | locals |
||
1172 | n dd ? ;int ;iterates over all tree elements |
||
1173 | prevlen dd -1 ;int ;last emitted length |
||
1174 | curlen dd ? ;int ;length of current code |
||
1175 | nextlen dd ? ;int ;= tree[0].Len ;length of next code |
||
1176 | count dd 0 ;int ;repeat count of the current code |
||
1177 | max_count dd 7 ;int ;max repeat count |
||
1178 | min_count dd 4 ;int ;min repeat count |
||
1179 | endl |
||
1180 | mov edi,[s] |
||
1181 | ; *** tree[max_code+1].Len = -1 ;guard already set |
||
1182 | mov eax,[tree] |
||
1183 | movzx eax,word[eax+Len] |
||
1184 | mov [nextlen],eax |
||
6813 | IgorA | 1185 | xor ecx,ecx |
1186 | test eax,eax |
||
1187 | jnz .cycle0 ;if (..==0) |
||
6617 | IgorA | 1188 | mov dword[max_count],138 |
1189 | mov dword[min_count],3 |
||
6813 | IgorA | 1190 | align 4 |
6617 | IgorA | 1191 | .cycle0: ;for (..;..<=..;..) |
1192 | cmp ecx,[max_code] |
||
1193 | jg .cycle0end |
||
1194 | mov eax,[nextlen] |
||
1195 | mov [curlen],eax |
||
1196 | mov eax,ecx |
||
1197 | inc eax |
||
1198 | imul eax,sizeof.ct_data |
||
1199 | add eax,[tree] |
||
1200 | movzx eax,word[eax+Len] |
||
1201 | mov [nextlen],eax |
||
1202 | inc dword[count] |
||
1203 | mov ebx,[count] |
||
1204 | cmp ebx,[max_count] |
||
1205 | jge .end0 |
||
1206 | mov eax,[nextlen] |
||
1207 | cmp [curlen],eax |
||
1208 | jne .end0 ;if (..<.. && ..==..) |
||
1209 | inc ecx |
||
1210 | jmp .cycle0 ;continue |
||
6813 | IgorA | 1211 | align 4 |
6617 | IgorA | 1212 | .end0: |
1213 | cmp ebx,[min_count] |
||
1214 | jge .end1 ;else if (..<..) |
||
1215 | @@: ;do |
||
1216 | mov ebx,edi |
||
1217 | add ebx,deflate_state.bl_tree |
||
1218 | send_code edi, [curlen], ebx |
||
1219 | dec dword[count] |
||
6813 | IgorA | 1220 | jnz @b ;while (..!=0) |
6617 | IgorA | 1221 | jmp .end4 |
1222 | align 4 |
||
1223 | .end1: |
||
1224 | cmp dword[curlen],0 |
||
1225 | je .end2 ;else if (..!=0) |
||
1226 | mov eax,[curlen] |
||
1227 | cmp eax,[prevlen] |
||
1228 | je @f ;if (..!=..) |
||
1229 | mov ebx,edi |
||
1230 | add ebx,deflate_state.bl_tree |
||
1231 | send_code edi, eax, ebx |
||
1232 | dec dword[count] |
||
1233 | @@: |
||
1234 | cmp dword[count],3 |
||
1235 | jl @f |
||
1236 | cmp dword[count],6 |
||
1237 | jle .end8 |
||
1238 | @@: |
||
6639 | IgorA | 1239 | zlib_assert ' 3_6?' ;Assert(..>=.. && ..<=..) |
6617 | IgorA | 1240 | .end8: |
1241 | mov ebx,edi |
||
1242 | add ebx,deflate_state.bl_tree |
||
1243 | send_code edi, REP_3_6, ebx |
||
1244 | mov ebx,[count] |
||
1245 | sub ebx,3 |
||
1246 | stdcall send_bits, edi, ebx, 2 |
||
1247 | jmp .end4 |
||
1248 | .end2: |
||
1249 | cmp ebx,10 |
||
1250 | jg .end3 ;else if (..<=..) |
||
1251 | mov ebx,edi |
||
1252 | add ebx,deflate_state.bl_tree |
||
1253 | send_code edi, REPZ_3_10, ebx |
||
1254 | mov ebx,[count] |
||
1255 | sub ebx,3 |
||
1256 | stdcall send_bits, edi, ebx, 3 |
||
1257 | jmp .end4 |
||
1258 | .end3: ;else |
||
1259 | mov ebx,edi |
||
1260 | add ebx,deflate_state.bl_tree |
||
1261 | send_code edi, REPZ_11_138, ebx |
||
1262 | mov ebx,[count] |
||
1263 | sub ebx,11 |
||
1264 | stdcall send_bits, edi, ebx, 7 |
||
1265 | .end4: |
||
1266 | mov dword[curlen],0 |
||
1267 | mov eax,[curlen] |
||
1268 | mov [prevlen],eax |
||
1269 | mov [nextlen],eax |
||
1270 | cmp eax,0 |
||
1271 | jne .end5 ;if (..==0) |
||
1272 | mov dword[max_count],138 |
||
1273 | mov dword[min_count],3 |
||
1274 | jmp .end7 |
||
1275 | .end5: |
||
1276 | mov eax,[curlen] |
||
1277 | cmp eax,[nextlen] |
||
1278 | jne .end6 ;else if (..==..) |
||
1279 | mov dword[max_count],6 |
||
1280 | mov dword[min_count],3 |
||
1281 | jmp .end7 |
||
1282 | .end6: ;else |
||
1283 | mov dword[max_count],7 |
||
1284 | mov dword[min_count],4 |
||
1285 | .end7: |
||
1286 | inc ecx |
||
1287 | jmp .cycle0 |
||
1288 | align 4 |
||
1289 | .cycle0end: |
||
1290 | ret |
||
1291 | endp |
||
1292 | |||
1293 | ; =========================================================================== |
||
1294 | ; Construct the Huffman tree for the bit lengths and return the index in |
||
1295 | ; bl_order of the last bit length code to send. |
||
1296 | |||
6847 | IgorA | 1297 | ;int (deflate_state* s) |
6617 | IgorA | 1298 | align 4 |
1299 | proc build_bl_tree uses edi, s:dword |
||
1300 | locals |
||
1301 | max_blindex dd ? ;int ;index of last bit length code of non zero freq |
||
1302 | endl |
||
1303 | mov edi,[s] |
||
1304 | ; Determine the bit length frequencies for literal and distance trees |
||
1305 | mov eax,edi |
||
1306 | add eax,deflate_state.dyn_ltree |
||
1307 | stdcall scan_tree, edi, eax, [edi+deflate_state.l_desc.max_code] |
||
6799 | IgorA | 1308 | add eax,deflate_state.dyn_dtree-deflate_state.dyn_ltree |
6617 | IgorA | 1309 | stdcall scan_tree, edi, eax, [edi+deflate_state.d_desc.max_code] |
1310 | |||
1311 | ; Build the bit length tree: |
||
6799 | IgorA | 1312 | add eax,deflate_state.bl_desc-deflate_state.dyn_dtree |
6617 | IgorA | 1313 | stdcall build_tree, edi, eax |
1314 | ; opt_len now includes the length of the tree representations, except |
||
1315 | ; the lengths of the bit lengths codes and the 5+5+4 bits for the counts. |
||
1316 | |||
1317 | ; Determine the number of bit length codes to send. The pkzip format |
||
1318 | ; requires that at least 4 bit length codes be sent. (appnote.txt says |
||
1319 | ; 3 but the actual value used is 4.) |
||
1320 | |||
1321 | mov dword[max_blindex],BL_CODES-1 |
||
1322 | .cycle0: ;for (..;..>=..;..) |
||
1323 | cmp dword[max_blindex],3 |
||
1324 | jl .cycle0end |
||
1325 | dec dword[max_blindex] |
||
1326 | mov eax,[max_blindex] |
||
1327 | add eax,bl_order |
||
1328 | movzx eax,byte[eax] |
||
1329 | imul eax,sizeof.ct_data |
||
1330 | add eax,edi |
||
6813 | IgorA | 1331 | cmp word[eax+deflate_state.bl_tree+Len],0 |
6617 | IgorA | 1332 | jne .cycle0end ;if (..!=0) break |
1333 | jmp .cycle0 |
||
6813 | IgorA | 1334 | align 4 |
6617 | IgorA | 1335 | .cycle0end: |
1336 | ; Update opt_len to include the bit length tree and counts |
||
1337 | mov eax,[max_blindex] |
||
1338 | inc eax |
||
1339 | imul eax,3 |
||
1340 | add eax,5+5+4 |
||
1341 | add [edi+deflate_state.opt_len],eax |
||
1342 | ; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); |
||
1343 | |||
1344 | mov eax,[max_blindex] |
||
1345 | ret |
||
1346 | endp |
||
1347 | |||
1348 | ; =========================================================================== |
||
1349 | ; Send the header for a block using dynamic Huffman trees: the counts, the |
||
1350 | ; lengths of the bit length codes, the literal tree and the distance tree. |
||
1351 | ; IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. |
||
1352 | |||
1353 | ;void (s, lcodes, dcodes, blcodes) |
||
1354 | ; deflate_state* s |
||
1355 | ; int lcodes, dcodes, blcodes ;number of codes for each tree |
||
1356 | align 4 |
||
1357 | proc send_all_trees uses eax ebx ecx edi, s:dword, lcodes:dword, dcodes:dword, blcodes:dword |
||
1358 | ;ecx = index in bl_order |
||
1359 | cmp dword[lcodes],257 |
||
1360 | jl @f |
||
1361 | cmp dword[dcodes],1 |
||
1362 | jl @f |
||
1363 | cmp dword[blcodes],4 |
||
1364 | jge .end0 |
||
1365 | @@: |
||
6639 | IgorA | 1366 | zlib_assert 'not enough codes' ;Assert(..>=.. && ..>=.. && ..>=..) |
6617 | IgorA | 1367 | .end0: |
1368 | cmp dword[lcodes],L_CODES |
||
1369 | jg @f |
||
1370 | cmp dword[dcodes],D_CODES |
||
1371 | jg @f |
||
1372 | cmp dword[blcodes],BL_CODES |
||
1373 | jle .end1 |
||
1374 | @@: |
||
6639 | IgorA | 1375 | zlib_assert 'too many codes' ;Assert(..<=.. && ..<=.. && ..<=..) |
6617 | IgorA | 1376 | .end1: |
1377 | ; Tracev((stderr, "\nbl counts: ")); |
||
1378 | mov edi,[s] |
||
1379 | mov eax,[lcodes] |
||
1380 | sub eax,257 |
||
1381 | stdcall send_bits, edi, eax, 5 ;not +255 as stated in appnote.txt |
||
1382 | mov eax,[dcodes] |
||
1383 | dec eax |
||
1384 | stdcall send_bits, edi, eax, 5 |
||
1385 | mov eax,[blcodes] |
||
1386 | sub eax,4 |
||
1387 | stdcall send_bits, edi, eax, 4 ;not -3 as stated in appnote.txt |
||
1388 | xor ecx,ecx |
||
1389 | .cycle0: |
||
1390 | cmp ecx,[blcodes] |
||
1391 | jge .cycle0end ;for (..;..<..;..) |
||
1392 | ; Tracev((stderr, "\nbl code %2d ", bl_order[ecx])); |
||
6851 | IgorA | 1393 | movzx eax,byte[ecx+bl_order] |
1394 | movzx eax,word[edi+sizeof.ct_data*eax+deflate_state.bl_tree+Len] |
||
6813 | IgorA | 1395 | stdcall send_bits, edi, eax, 3 |
6617 | IgorA | 1396 | inc ecx |
1397 | jmp .cycle0 |
||
1398 | align 4 |
||
1399 | .cycle0end: |
||
1400 | ; Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); |
||
1401 | |||
1402 | mov ebx,[lcodes] |
||
1403 | dec ebx |
||
1404 | mov eax,edi |
||
1405 | add eax,deflate_state.dyn_ltree |
||
1406 | stdcall send_tree, edi, eax, ebx ;literal tree |
||
1407 | ; Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); |
||
1408 | |||
1409 | mov ebx,[dcodes] |
||
1410 | dec ebx |
||
1411 | add eax,deflate_state.dyn_dtree-deflate_state.dyn_ltree |
||
1412 | stdcall send_tree, edi, eax, ebx ;distance tree |
||
1413 | ; Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); |
||
1414 | ret |
||
1415 | endp |
||
1416 | |||
1417 | ; =========================================================================== |
||
1418 | ; Send a stored block |
||
1419 | |||
1420 | ;void (s, buf, stored_len, last) |
||
1421 | ; deflate_state* s |
||
1422 | ; charf *buf ;input block |
||
1423 | ; ulg stored_len ;length of input block |
||
1424 | ; int last ;one if this is the last block for a file |
||
1425 | align 4 |
||
1426 | proc _tr_stored_block uses eax edi, s:dword, buf:dword, stored_len:dword, last:dword |
||
1427 | mov edi,[s] |
||
1428 | mov eax,[last] |
||
1429 | add eax,STORED_BLOCK shl 1 |
||
1430 | stdcall send_bits, edi, eax, 3 ;send block type |
||
1431 | if DEBUG eq 1 |
||
1432 | mov eax,[edi+deflate_state.compressed_len] |
||
1433 | add eax,3+7 |
||
1434 | and eax,not 7 |
||
1435 | mov [edi+deflate_state.compressed_len],eax |
||
1436 | mov eax,[stored_len] |
||
1437 | add eax,4 |
||
1438 | shl eax,3 |
||
1439 | add [edi+deflate_state.compressed_len],eax |
||
1440 | end if |
||
1441 | stdcall copy_block, edi, [buf], [stored_len], 1 ;with header |
||
1442 | ret |
||
1443 | endp |
||
1444 | |||
1445 | ; =========================================================================== |
||
1446 | ; Flush the bits in the bit buffer to pending output (leaves at most 7 bits) |
||
1447 | |||
6847 | IgorA | 1448 | ;void (deflate_state* s) |
1449 | ;align 4 |
||
1450 | ;proc _tr_flush_bits, s:dword |
||
1451 | ; stdcall bi_flush, [s] |
||
1452 | ; ret |
||
1453 | ;endp |
||
6617 | IgorA | 1454 | |
6847 | IgorA | 1455 | _tr_flush_bits equ bi_flush |
1456 | |||
6617 | IgorA | 1457 | ; =========================================================================== |
1458 | ; Send one empty static block to give enough lookahead for inflate. |
||
1459 | ; This takes 10 bits, of which 7 may remain in the bit buffer. |
||
1460 | |||
6847 | IgorA | 1461 | ;void (deflate_state* s) |
6617 | IgorA | 1462 | align 4 |
1463 | proc _tr_align uses edi, s:dword |
||
1464 | mov edi,[s] |
||
1465 | stdcall send_bits, edi, STATIC_TREES shl 1, 3 |
||
1466 | send_code edi, END_BLOCK, static_ltree |
||
1467 | if DEBUG eq 1 |
||
1468 | add [edi+deflate_state.compressed_len],10 ;3 for block type, 7 for EOB |
||
1469 | end if |
||
1470 | stdcall bi_flush, edi |
||
1471 | ret |
||
1472 | endp |
||
1473 | |||
1474 | ; =========================================================================== |
||
1475 | ; Determine the best encoding for the current block: dynamic trees, static |
||
1476 | ; trees or store, and output the encoded block to the zip file. |
||
1477 | |||
1478 | ;void (s, buf, stored_len, last) |
||
1479 | ; deflate_state* s |
||
1480 | ; charf *buf ;input block, or NULL if too old |
||
1481 | ; ulg stored_len ;length of input block |
||
1482 | ; int last ;one if this is the last block for a file |
||
1483 | align 4 |
||
1484 | proc _tr_flush_block uses eax ebx edi, s:dword, buf:dword, stored_len:dword, last:dword |
||
1485 | locals |
||
1486 | opt_lenb dd ? ;ulg |
||
1487 | static_lenb dd ? ;opt_len and static_len in bytes |
||
1488 | max_blindex dd 0 ;int ;index of last bit length code of non zero freq |
||
1489 | endl |
||
1490 | ; Build the Huffman trees unless a stored block is forced |
||
1491 | mov edi,[s] |
||
1492 | cmp word[edi+deflate_state.level],0 |
||
1493 | jle .end0 ;if (..>0) |
||
1494 | |||
1495 | ; Check if the file is binary or text |
||
1496 | mov ebx,[edi+deflate_state.strm] |
||
6797 | IgorA | 1497 | cmp dword[ebx+z_stream.data_type],Z_UNKNOWN |
6617 | IgorA | 1498 | jne @f ;if (..==..) |
1499 | stdcall detect_data_type, edi |
||
6797 | IgorA | 1500 | mov [ebx+z_stream.data_type],eax |
6617 | IgorA | 1501 | @@: |
1502 | |||
1503 | ; Construct the literal and distance trees |
||
1504 | mov eax,edi |
||
1505 | add eax,deflate_state.l_desc |
||
1506 | stdcall build_tree, edi, eax |
||
1507 | ; Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); |
||
1508 | |||
1509 | mov eax,edi |
||
1510 | add eax,deflate_state.d_desc |
||
1511 | stdcall build_tree, edi, eax |
||
1512 | ; Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); |
||
1513 | ; At this point, opt_len and static_len are the total bit lengths of |
||
1514 | ; the compressed block data, excluding the tree representations. |
||
1515 | |||
1516 | ; Build the bit length tree for the above two trees, and get the index |
||
1517 | ; in bl_order of the last bit length code to send. |
||
1518 | |||
1519 | stdcall build_bl_tree, edi |
||
1520 | mov [max_blindex],eax |
||
1521 | |||
1522 | ; Determine the best encoding. Compute the block lengths in bytes. |
||
1523 | mov eax,[edi+deflate_state.opt_len] |
||
1524 | add eax,3+7 |
||
1525 | shr eax,3 |
||
1526 | mov [opt_lenb],eax |
||
1527 | mov eax,[edi+deflate_state.static_len] |
||
1528 | add eax,3+7 |
||
1529 | shr eax,3 |
||
1530 | mov [static_lenb],eax |
||
1531 | |||
1532 | ; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", |
||
1533 | ; opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, |
||
1534 | ; s->last_lit)); |
||
1535 | |||
1536 | cmp eax,[opt_lenb] |
||
6851 | IgorA | 1537 | ja .end1 ;if (..<=..) |
6617 | IgorA | 1538 | mov [opt_lenb],eax |
1539 | jmp .end1 |
||
1540 | .end0: ;else |
||
1541 | cmp dword[buf],0 |
||
1542 | jne @f |
||
6639 | IgorA | 1543 | zlib_assert 'lost buf' ;Assert(..!=0) |
6617 | IgorA | 1544 | @@: |
1545 | mov eax,[stored_len] |
||
1546 | add eax,5 |
||
1547 | mov [static_lenb],eax |
||
1548 | mov [opt_lenb],eax ;force a stored block |
||
1549 | .end1: |
||
1550 | |||
1551 | if FORCE_STORED eq 1 |
||
1552 | cmp dword[buf],0 |
||
1553 | je .end2 ;if (..!=0) ;force stored block |
||
1554 | else |
||
1555 | mov eax,[stored_len] |
||
1556 | add eax,4 |
||
1557 | cmp eax,[opt_lenb] |
||
6851 | IgorA | 1558 | ja .end2 |
6617 | IgorA | 1559 | cmp dword[buf],0 |
1560 | je .end2 ;if (..<=.. && ..!=0) |
||
1561 | ;4: two words for the lengths |
||
1562 | end if |
||
1563 | ; The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. |
||
1564 | ; Otherwise we can't have processed more than WSIZE input bytes since |
||
1565 | ; the last block flush, because compression would have been |
||
1566 | ; successful. If LIT_BUFSIZE <= WSIZE, it is never too late to |
||
1567 | ; transform a block into a stored block. |
||
1568 | |||
1569 | stdcall _tr_stored_block, edi, [buf], [stored_len], [last] |
||
1570 | jmp .end4 |
||
1571 | .end2: |
||
1572 | if FORCE_STATIC eq 1 |
||
1573 | cmp dword[static_lenb],0 |
||
1574 | jl .end3 ;else if (..>=0) ;force static trees |
||
1575 | else |
||
1576 | cmp word[edi+deflate_state.strategy],Z_FIXED |
||
1577 | je @f |
||
1578 | mov eax,[opt_lenb] |
||
1579 | cmp [static_lenb],eax |
||
1580 | je @f ;else if (..==.. || ..==..) |
||
1581 | jmp .end3 |
||
1582 | @@: |
||
1583 | end if |
||
1584 | mov eax,STATIC_TREES shl 1 |
||
1585 | add eax,[last] |
||
1586 | stdcall send_bits, edi, eax, 3 |
||
1587 | stdcall compress_block, edi, static_ltree, static_dtree |
||
1588 | if DEBUG eq 1 |
||
1589 | mov eax,[edi+deflate_state.static_len] |
||
1590 | add eax,3 |
||
1591 | add [edi+deflate_state.compressed_len],eax |
||
1592 | end if |
||
1593 | jmp .end4 |
||
1594 | .end3: ;else |
||
1595 | mov eax,DYN_TREES shl 1 |
||
1596 | add eax,[last] |
||
1597 | stdcall send_bits, edi, eax, 3 |
||
1598 | mov eax,[max_blindex] |
||
1599 | inc eax |
||
1600 | push eax |
||
1601 | mov eax,[edi+deflate_state.d_desc.max_code] |
||
1602 | inc eax |
||
1603 | push eax |
||
1604 | mov eax,[edi+deflate_state.l_desc.max_code] |
||
1605 | inc eax |
||
1606 | stdcall send_all_trees, edi, eax ;, ..., ... |
||
1607 | mov eax,edi |
||
1608 | add eax,deflate_state.dyn_dtree |
||
1609 | push eax |
||
1610 | add eax,deflate_state.dyn_ltree-deflate_state.dyn_dtree |
||
1611 | stdcall compress_block, edi, eax ;, ... |
||
1612 | if DEBUG eq 1 |
||
1613 | mov eax,[edi+deflate_state.opt_len] |
||
1614 | add eax,3 |
||
1615 | add [edi+deflate_state.compressed_len],eax |
||
1616 | end if |
||
1617 | .end4: |
||
1618 | ; Assert (s->compressed_len == s->bits_sent, "bad compressed size"); |
||
1619 | ; The above check is made mod 2^32, for files larger than 512 MB |
||
1620 | ; and uLong implemented on 32 bits. |
||
1621 | |||
1622 | stdcall init_block,edi |
||
1623 | |||
1624 | cmp dword[last],0 |
||
1625 | je @f ;if (..) |
||
1626 | stdcall bi_windup,edi |
||
1627 | if DEBUG eq 1 |
||
1628 | add [edi+deflate_state.compressed_len],7 ;align on byte boundary |
||
1629 | end if |
||
1630 | @@: |
||
1631 | ; Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, |
||
1632 | ; s->compressed_len-7*last)); |
||
1633 | ret |
||
1634 | endp |
||
1635 | |||
1636 | ; =========================================================================== |
||
1637 | ; Save the match info and tally the frequency counts. Return true if |
||
1638 | ; the current block must be flushed. |
||
1639 | |||
1640 | ;int (s, dist, lc) |
||
1641 | ; deflate_state* s |
||
1642 | ; unsigned dist ;distance of matched string |
||
1643 | ; unsigned lc ;match length-MIN_MATCH or unmatched char (if dist==0) |
||
1644 | align 4 |
||
1645 | proc _tr_tally uses ebx edi, s:dword, dist:dword, lc:dword |
||
1646 | mov edi,[s] |
||
1647 | mov eax,[edi+deflate_state.last_lit] |
||
1648 | shl eax,1 |
||
1649 | add eax,[edi+deflate_state.d_buf] |
||
1650 | mov ebx,[dist] |
||
1651 | mov word[eax],bx |
||
1652 | mov eax,[edi+deflate_state.last_lit] |
||
1653 | add eax,[edi+deflate_state.l_buf] |
||
1654 | mov ebx,[lc] |
||
1655 | mov byte[eax],bl |
||
1656 | inc dword[edi+deflate_state.last_lit] |
||
1657 | cmp dword[dist],0 |
||
1658 | jne @f ;if (..==0) |
||
1659 | ; lc is the unmatched char |
||
1660 | mov eax,[lc] |
||
6851 | IgorA | 1661 | inc word[edi+sizeof.ct_data*eax+deflate_state.dyn_ltree+Freq] |
6617 | IgorA | 1662 | jmp .end0 |
6815 | IgorA | 1663 | align 4 |
6617 | IgorA | 1664 | @@: ;else |
1665 | inc dword[edi+deflate_state.matches] |
||
1666 | ; Here, lc is the match length - MIN_MATCH |
||
1667 | dec dword[dist] ;dist = match distance - 1 |
||
1668 | MAX_DIST edi |
||
1669 | cmp word[dist],ax |
||
1670 | jge @f |
||
1671 | cmp word[lc],MAX_MATCH-MIN_MATCH |
||
1672 | jg @f |
||
1673 | d_code [dist] |
||
1674 | cmp ax,D_CODES |
||
1675 | jl .end2 |
||
1676 | @@: |
||
6639 | IgorA | 1677 | zlib_assert '_tr_tally: bad match' ;Assert(..<.. && ..<=.. && ..<..) |
6617 | IgorA | 1678 | .end2: |
1679 | mov eax,[lc] |
||
6815 | IgorA | 1680 | movzx eax,byte[eax+_length_code] |
6851 | IgorA | 1681 | inc word[edi+sizeof.ct_data*eax+deflate_state.dyn_ltree+sizeof.ct_data*(LITERALS+1)+Freq] |
6617 | IgorA | 1682 | d_code [dist] |
6851 | IgorA | 1683 | inc word[edi+sizeof.ct_data*eax+deflate_state.dyn_dtree+Freq] |
6617 | IgorA | 1684 | .end0: |
1685 | |||
1686 | if TRUNCATE_BLOCK eq 1 |
||
1687 | ; Try to guess if it is profitable to stop the current block here |
||
1688 | mov eax,[edi+deflate_state.last_lit] |
||
1689 | and eax,0x1fff |
||
6847 | IgorA | 1690 | jnz .end1 |
6617 | IgorA | 1691 | cmp word[edi+deflate_state.level],2 |
6847 | IgorA | 1692 | jle .end1 ;if (..==0 && ..>..) |
6617 | IgorA | 1693 | ; Compute an upper bound for the compressed length |
1694 | ; ulg out_length = (ulg)s->last_lit*8L; |
||
1695 | ; ulg in_length = (ulg)((long)s->strstart - s->block_start); |
||
1696 | ; int dcode; |
||
1697 | ; for (dcode = 0; dcode < D_CODES; dcode++) { |
||
1698 | ; out_length += (ulg)s->dyn_dtree[dcode].Freq * |
||
1699 | ; (5L+extra_dbits[dcode]); |
||
1700 | ; } |
||
1701 | ; out_length >>= 3; |
||
1702 | ; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", |
||
1703 | ; s->last_lit, in_length, out_length, |
||
1704 | ; 100L - out_length*100L/in_length)); |
||
1705 | ; if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; |
||
1706 | .end1: |
||
1707 | end if |
||
6851 | IgorA | 1708 | mov ebx,[edi+deflate_state.lit_bufsize] |
1709 | dec ebx |
||
6617 | IgorA | 1710 | xor eax,eax |
6851 | IgorA | 1711 | cmp [edi+deflate_state.last_lit],ebx |
1712 | sete al ;return (..==..) |
||
1713 | |||
6617 | IgorA | 1714 | ; We avoid equality with lit_bufsize because of wraparound at 64K |
1715 | ; on 16 bit machines and because stored blocks are restricted to |
||
1716 | ; 64K-1 bytes. |
||
1717 | ret |
||
1718 | endp |
||
1719 | |||
1720 | ; =========================================================================== |
||
1721 | ; Send the block data compressed using the given Huffman trees |
||
1722 | |||
1723 | ;void (s, ltree, dtree) |
||
6799 | IgorA | 1724 | ; deflate_state* s |
6617 | IgorA | 1725 | ; ct_data *ltree ;literal tree |
1726 | ; ct_data *dtree ;distance tree |
||
1727 | align 4 |
||
1728 | proc compress_block uses eax edi, s:dword, ltree:dword, dtree:dword |
||
1729 | locals |
||
1730 | dist dd ? ;unsigned ;distance of matched string |
||
1731 | lc dd ? ;int ;match length or unmatched char (if dist == 0) |
||
1732 | lx dd 0 ;unsigned ;running index in l_buf |
||
1733 | u_code dd ? ;unsigned ;the code to send |
||
1734 | endl |
||
1735 | mov edi,[s] |
||
1736 | cmp dword[edi+deflate_state.last_lit],0 |
||
1737 | je .end0 ;if (..!=0) |
||
1738 | .cycle0: ; do |
||
1739 | mov eax,[lx] |
||
1740 | shl eax,1 |
||
1741 | add eax,[edi+deflate_state.d_buf] |
||
1742 | movzx eax,word[eax] |
||
1743 | mov [dist],eax |
||
1744 | mov eax,[lx] |
||
1745 | add eax,[edi+deflate_state.l_buf] |
||
1746 | movzx eax,byte[eax] |
||
1747 | mov [lc],eax |
||
1748 | inc dword[lx] |
||
1749 | cmp dword[dist],0 |
||
1750 | jne @f ;if (..==0) |
||
1751 | send_code edi, [lc], [ltree] ;send a literal byte |
||
1752 | ; Tracecv(isgraph(lc), (stderr," '%c' ", lc)); |
||
1753 | jmp .end1 |
||
1754 | @@: ;else |
||
1755 | ; Here, lc is the match length - MIN_MATCH |
||
1756 | mov eax,[lc] |
||
1757 | add eax,_length_code |
||
1758 | movzx eax,byte[eax] |
||
1759 | mov [u_code],eax |
||
1760 | add eax,LITERALS+1 |
||
1761 | send_code edi, eax, [ltree] ;send the length code |
||
1762 | mov eax,[u_code] |
||
6847 | IgorA | 1763 | mov eax,[4*eax+extra_lbits] |
1764 | test eax,eax |
||
1765 | jz @f ;if (..!=0) |
||
1766 | push eax ;extra |
||
6617 | IgorA | 1767 | mov eax,[u_code] |
6847 | IgorA | 1768 | mov eax,[4*eax+base_length] |
6617 | IgorA | 1769 | sub [lc],eax |
6847 | IgorA | 1770 | stdcall send_bits, edi, [lc] ;, ... ;send the extra length bits |
6617 | IgorA | 1771 | @@: |
1772 | dec dword[dist] ;dist is now the match distance - 1 |
||
1773 | d_code [dist] |
||
1774 | mov [u_code],eax |
||
1775 | cmp eax,D_CODES |
||
1776 | jl @f |
||
6639 | IgorA | 1777 | zlib_assert 'bad d_code' ;Assert(..<..) |
6617 | IgorA | 1778 | @@: |
1779 | send_code edi, [u_code], [dtree] ;send the distance code |
||
1780 | mov eax,[u_code] |
||
6847 | IgorA | 1781 | mov eax,[4*eax+extra_dbits] |
1782 | test eax,eax |
||
1783 | jz .end1 ;if (..!=0) |
||
1784 | push eax ;extra |
||
6617 | IgorA | 1785 | mov eax,[u_code] |
6847 | IgorA | 1786 | mov eax,[4*eax+base_dist] |
6617 | IgorA | 1787 | sub [dist],eax |
6847 | IgorA | 1788 | stdcall send_bits, edi, [dist] ;, ... ;send the extra distance bits |
6617 | IgorA | 1789 | .end1: ;literal or match pair ? |
1790 | |||
1791 | ; Check that the overlay between pending_buf and d_buf+l_buf is ok: |
||
1792 | mov eax,[lx] |
||
1793 | shl eax,1 |
||
1794 | add eax,[edi+deflate_state.lit_bufsize] |
||
6741 | IgorA | 1795 | cmp [edi+deflate_state.pending],eax |
6617 | IgorA | 1796 | jl @f |
6639 | IgorA | 1797 | zlib_assert 'pendingBuf overflow' ;Assert(..<..) |
6617 | IgorA | 1798 | @@: |
1799 | mov eax,[edi+deflate_state.last_lit] |
||
1800 | cmp [lx],eax |
||
6851 | IgorA | 1801 | jb .cycle0 ;while (..<..) |
6617 | IgorA | 1802 | align 4 |
1803 | .end0: |
||
1804 | |||
1805 | send_code edi, END_BLOCK, [ltree] |
||
1806 | ret |
||
1807 | endp |
||
1808 | |||
1809 | ; =========================================================================== |
||
1810 | ; Check if the data type is TEXT or BINARY, using the following algorithm: |
||
1811 | ; - TEXT if the two conditions below are satisfied: |
||
1812 | ; a) There are no non-portable control characters belonging to the |
||
1813 | ; "black list" (0..6, 14..25, 28..31). |
||
1814 | ; b) There is at least one printable character belonging to the |
||
1815 | ; "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). |
||
1816 | ; - BINARY otherwise. |
||
1817 | ; - The following partially-portable control characters form a |
||
1818 | ; "gray list" that is ignored in this detection algorithm: |
||
1819 | ; (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). |
||
1820 | ; IN assertion: the fields Freq of dyn_ltree are set. |
||
1821 | |||
6851 | IgorA | 1822 | ;int (deflate_state* s) |
6617 | IgorA | 1823 | align 4 |
1824 | proc detect_data_type uses ebx ecx edi, s:dword |
||
1825 | ; black_mask is the bit mask of black-listed bytes |
||
1826 | ; set bits 0..6, 14..25, and 28..31 |
||
1827 | ; 0xf3ffc07f = binary 11110011111111111100000001111111 |
||
1828 | locals |
||
1829 | black_mask dd 0xf3ffc07f |
||
1830 | endl |
||
1831 | mov edi,[s] |
||
1832 | |||
1833 | ; Check for non-textual ("black-listed") bytes. |
||
1834 | xor ecx,ecx |
||
1835 | mov ebx,edi |
||
1836 | add ebx,deflate_state.dyn_ltree+Freq |
||
1837 | .cycle0: |
||
1838 | cmp ecx,31 |
||
1839 | jg .cycle0end ;for (..;..<=..;..,..) |
||
1840 | bt dword[black_mask],0 |
||
1841 | jnc @f |
||
1842 | cmp word[ebx],0 |
||
1843 | je @f ;if (..&.. && ..!=0) |
||
1844 | mov eax,Z_BINARY |
||
1845 | jmp .end_f |
||
1846 | @@: |
||
1847 | shr dword[black_mask],1 |
||
1848 | add ebx,sizeof.ct_data |
||
1849 | inc ecx |
||
1850 | jmp .cycle0 |
||
1851 | .cycle0end: |
||
1852 | |||
1853 | ; Check for textual ("white-listed") bytes. |
||
1854 | mov ebx,edi |
||
1855 | add ebx,deflate_state.dyn_ltree+Freq+9*sizeof.ct_data |
||
1856 | cmp word[ebx],0 |
||
1857 | jne @f |
||
1858 | add ebx,sizeof.ct_data |
||
1859 | cmp word[ebx],0 |
||
1860 | jne @f |
||
1861 | add ebx,3*sizeof.ct_data |
||
1862 | cmp word[ebx],0 |
||
1863 | je .end0 |
||
1864 | @@: ;if (..!=0 || ..!=0 || ..!= 0) |
||
1865 | mov eax,Z_TEXT |
||
1866 | jmp .end_f |
||
1867 | .end0: |
||
1868 | mov ecx,32 |
||
1869 | mov ebx,edi |
||
6799 | IgorA | 1870 | add ebx,deflate_state.dyn_ltree+Freq+32*sizeof.ct_data |
6617 | IgorA | 1871 | .cycle1: |
1872 | cmp ecx,LITERALS |
||
1873 | jge .cycle1end ;for (..;..<..;..,..) |
||
1874 | cmp word[ebx],0 |
||
1875 | je @f ;if (..!=0) |
||
1876 | mov eax,Z_TEXT |
||
1877 | jmp .end_f |
||
1878 | @@: |
||
1879 | add ebx,sizeof.ct_data |
||
1880 | inc ecx |
||
1881 | jmp .cycle1 |
||
1882 | .cycle1end: |
||
1883 | |||
1884 | ; There are no "black-listed" or "white-listed" bytes: |
||
1885 | ; this stream either is empty or has tolerated ("gray-listed") bytes only. |
||
1886 | |||
1887 | mov eax,Z_BINARY |
||
1888 | .end_f: |
||
1889 | ret |
||
1890 | endp |
||
1891 | |||
1892 | ; =========================================================================== |
||
1893 | ; Reverse the first len bits of a code, using straightforward code (a faster |
||
1894 | ; method would use a table) |
||
1895 | ; IN assertion: 1 <= len <= 15 |
||
1896 | |||
1897 | ;unsigned (code, len) |
||
1898 | ; unsigned code ;the value to invert |
||
1899 | ; int len ;its bit length |
||
1900 | align 4 |
||
1901 | proc bi_reverse uses ebx, p1code:dword, len:dword |
||
1902 | xor eax,eax |
||
1903 | @@: ;do |
||
1904 | mov ebx,[p1code] |
||
1905 | and ebx,1 |
||
1906 | or eax,ebx |
||
1907 | shr dword[p1code],1 |
||
1908 | shl eax,1 |
||
1909 | dec dword[len] |
||
1910 | cmp dword[len],0 |
||
1911 | jg @b ;while (..>..) |
||
6813 | IgorA | 1912 | shr eax,1 |
6617 | IgorA | 1913 | ret |
1914 | endp |
||
1915 | |||
1916 | ; =========================================================================== |
||
1917 | ; Flush the bit buffer, keeping at most 7 bits in it. |
||
1918 | |||
6851 | IgorA | 1919 | ;void (deflate_state* s) |
6617 | IgorA | 1920 | align 4 |
1921 | proc bi_flush uses eax ecx edi, s:dword |
||
1922 | mov edi,[s] |
||
1923 | cmp dword[edi+deflate_state.bi_valid],16 |
||
1924 | jne @f ;if (..==..) |
||
1925 | mov cx,[edi+deflate_state.bi_buf] |
||
1926 | put_short edi,cx |
||
1927 | mov word[edi+deflate_state.bi_buf],0 |
||
1928 | mov dword[edi+deflate_state.bi_valid],0 |
||
1929 | jmp .end0 |
||
1930 | @@: ;else if (..>=..) |
||
1931 | cmp dword[edi+deflate_state.bi_valid],8 |
||
1932 | jl .end0 |
||
1933 | mov cl,byte[edi+deflate_state.bi_buf] |
||
1934 | put_byte edi,cl |
||
1935 | shr word[edi+deflate_state.bi_buf],8 |
||
1936 | sub dword[edi+deflate_state.bi_valid],8 |
||
1937 | .end0: |
||
1938 | ret |
||
1939 | endp |
||
1940 | |||
1941 | ; =========================================================================== |
||
1942 | ; Flush the bit buffer and align the output on a byte boundary |
||
1943 | |||
6847 | IgorA | 1944 | ;void (deflate_state* s) |
6617 | IgorA | 1945 | align 4 |
1946 | proc bi_windup uses eax ecx edi, s:dword |
||
1947 | mov edi,[s] |
||
1948 | cmp dword[edi+deflate_state.bi_valid],8 |
||
1949 | jle @f ;if (..>..) |
||
1950 | mov cx,[edi+deflate_state.bi_buf] |
||
1951 | put_short edi, cx |
||
1952 | jmp .end0 |
||
1953 | @@: ;else if (..>0) |
||
1954 | cmp dword[edi+deflate_state.bi_valid],0 |
||
1955 | jle .end0 |
||
1956 | mov cl,byte[edi+deflate_state.bi_buf] |
||
1957 | put_byte edi, cl |
||
1958 | .end0: |
||
1959 | mov word[edi+deflate_state.bi_buf],0 |
||
1960 | mov dword[edi+deflate_state.bi_valid],0 |
||
1961 | if DEBUG eq 1 |
||
1962 | mov eax,[edi+deflate_state.bits_sent] |
||
1963 | add eax,7 |
||
1964 | and eax,not 7 |
||
1965 | mov [edi+deflate_state.bits_sent],eax |
||
1966 | end if |
||
1967 | ret |
||
1968 | endp |
||
1969 | |||
1970 | ; =========================================================================== |
||
1971 | ; Copy a stored block, storing first the length and its |
||
1972 | ; one's complement if requested. |
||
1973 | |||
1974 | ;void (s, buf, len, header) |
||
1975 | ; deflate_state* s |
||
1976 | ; charf *buf ;the input data |
||
1977 | ; unsigned len ;its length |
||
1978 | ; int header ;true if block header must be written |
||
1979 | align 4 |
||
1980 | proc copy_block uses eax ebx ecx edi esi, s:dword, buf:dword, len:dword, p4header:dword |
||
1981 | mov edi,[s] |
||
1982 | stdcall bi_windup,edi ;align on byte boundary |
||
1983 | |||
1984 | cmp dword[p4header],0 |
||
1985 | je @f ;if (..) |
||
1986 | mov ecx,[len] |
||
1987 | put_short edi, cx |
||
1988 | not cx |
||
1989 | put_short edi, cx |
||
1990 | if DEBUG eq 1 |
||
1991 | add dword[edi+deflate_state.bits_sent],2*16 |
||
1992 | end if |
||
1993 | @@: |
||
1994 | if DEBUG eq 1 |
||
1995 | mov ecx,[len] |
||
1996 | shl ecx,3 |
||
1997 | add [edi+deflate_state.bits_sent],ecx |
||
1998 | end if |
||
1999 | mov ecx,[len] |
||
6851 | IgorA | 2000 | ; test ecx,ecx |
2001 | ; jz .end_f |
||
6617 | IgorA | 2002 | mov esi,[buf] |
6815 | IgorA | 2003 | jmp .end0 |
2004 | align 4 |
||
6617 | IgorA | 2005 | @@: ;while (len--) |
2006 | lodsb |
||
2007 | mov bl,al |
||
2008 | put_byte edi, bl |
||
6815 | IgorA | 2009 | .end0: |
6617 | IgorA | 2010 | loop @b |
6851 | IgorA | 2011 | ; .end_f: |
6617 | IgorA | 2012 | ret |
2013 | endp=>=> |