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