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