Subversion Repositories Kolibri OS

Rev

Rev 6799 | Rev 6819 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6799 Rev 6801
1
; deflate.asm -- compress data using the deflation algorithm
1
; deflate.asm -- compress data using the deflation algorithm
2
; Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
2
; Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
3
; For conditions of distribution and use, see copyright notice in zlib.inc
3
; For conditions of distribution and use, see copyright notice in zlib.inc
4
 
4
 
5
;  ALGORITHM
5
;  ALGORITHM
6
 
6
 
7
;      The "deflation" process depends on being able to identify portions
7
;      The "deflation" process depends on being able to identify portions
8
;      of the input text which are identical to earlier input (within a
8
;      of the input text which are identical to earlier input (within a
9
;      sliding window trailing behind the input currently being processed).
9
;      sliding window trailing behind the input currently being processed).
10
 
10
 
11
;      The most straightforward technique turns out to be the fastest for
11
;      The most straightforward technique turns out to be the fastest for
12
;      most input files: try all possible matches and select the longest.
12
;      most input files: try all possible matches and select the longest.
13
;      The key feature of this algorithm is that insertions into the string
13
;      The key feature of this algorithm is that insertions into the string
14
;      dictionary are very simple and thus fast, and deletions are avoided
14
;      dictionary are very simple and thus fast, and deletions are avoided
15
;      completely. Insertions are performed at each input character, whereas
15
;      completely. Insertions are performed at each input character, whereas
16
;      string matches are performed only when the previous match ends. So it
16
;      string matches are performed only when the previous match ends. So it
17
;      is preferable to spend more time in matches to allow very fast string
17
;      is preferable to spend more time in matches to allow very fast string
18
;      insertions and avoid deletions. The matching algorithm for small
18
;      insertions and avoid deletions. The matching algorithm for small
19
;      strings is inspired from that of Rabin & Karp. A brute force approach
19
;      strings is inspired from that of Rabin & Karp. A brute force approach
20
;      is used to find longer strings when a small match has been found.
20
;      is used to find longer strings when a small match has been found.
21
;      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
21
;      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
22
;      (by Leonid Broukhis).
22
;      (by Leonid Broukhis).
23
;         A previous version of this file used a more sophisticated algorithm
23
;         A previous version of this file used a more sophisticated algorithm
24
;      (by Fiala and Greene) which is guaranteed to run in linear amortized
24
;      (by Fiala and Greene) which is guaranteed to run in linear amortized
25
;      time, but has a larger average cost, uses more memory and is patented.
25
;      time, but has a larger average cost, uses more memory and is patented.
26
;      However the F&G algorithm may be faster for some highly redundant
26
;      However the F&G algorithm may be faster for some highly redundant
27
;      files if the parameter max_chain_length (described below) is too large.
27
;      files if the parameter max_chain_length (described below) is too large.
28
 
28
 
29
;  ACKNOWLEDGEMENTS
29
;  ACKNOWLEDGEMENTS
30
 
30
 
31
;      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
31
;      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
32
;      I found it in 'freeze' written by Leonid Broukhis.
32
;      I found it in 'freeze' written by Leonid Broukhis.
33
;      Thanks to many people for bug reports and testing.
33
;      Thanks to many people for bug reports and testing.
34
 
34
 
35
;  REFERENCES
35
;  REFERENCES
36
 
36
 
37
;      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
37
;      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
38
;      Available in http://tools.ietf.org/html/rfc1951
38
;      Available in http://tools.ietf.org/html/rfc1951
39
 
39
 
40
;      A description of the Rabin and Karp algorithm is given in the book
40
;      A description of the Rabin and Karp algorithm is given in the book
41
;         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
41
;         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
42
 
42
 
43
;      Fiala,E.R., and Greene,D.H.
43
;      Fiala,E.R., and Greene,D.H.
44
;         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
44
;         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
45
 
45
 
46
 
46
 
47
deflate_copyright db ' deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ',0
47
deflate_copyright db ' deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ',0
48
 
48
 
49
;  If you use the zlib library in a product, an acknowledgment is welcome
49
;  If you use the zlib library in a product, an acknowledgment is welcome
50
;  in the documentation of your product. If for some reason you cannot
50
;  in the documentation of your product. If for some reason you cannot
51
;  include such an acknowledgment, I would appreciate that you keep this
51
;  include such an acknowledgment, I would appreciate that you keep this
52
;  copyright string in the executable of your product.
52
;  copyright string in the executable of your product.
53
 
53
 
54
; ===========================================================================
54
; ===========================================================================
55
;  Function prototypes.
55
;  Function prototypes.
56
 
56
 
57
;enum block_state
57
;enum block_state
58
need_more   equ 1 ;block not completed, need more input or more output
58
need_more   equ 1 ;block not completed, need more input or more output
59
block_done  equ 2 ;block flush performed
59
block_done  equ 2 ;block flush performed
60
finish_started equ 3 ;finish started, need only more output at next deflate
60
finish_started equ 3 ;finish started, need only more output at next deflate
61
finish_done equ 4 ;finish done, accept no more input or output
61
finish_done equ 4 ;finish done, accept no more input or output
62
 
62
 
63
; ===========================================================================
63
; ===========================================================================
64
; Local data
64
; Local data
65
 
65
 
66
NIL equ 0
66
NIL equ 0
67
; Tail of hash chains
67
; Tail of hash chains
68
 
68
 
69
TOO_FAR equ 4096
69
TOO_FAR equ 4096
70
; Matches of length 3 are discarded if their distance exceeds TOO_FAR
70
; Matches of length 3 are discarded if their distance exceeds TOO_FAR
71
 
71
 
72
; Values for max_lazy_match, good_match and max_chain_length, depending on
72
; Values for max_lazy_match, good_match and max_chain_length, depending on
73
; the desired pack level (0..9). The values given below have been tuned to
73
; the desired pack level (0..9). The values given below have been tuned to
74
; exclude worst case performance for pathological files. Better values may be
74
; exclude worst case performance for pathological files. Better values may be
75
; found for specific files.
75
; found for specific files.
76
 
76
 
77
struct config_s ;config
77
struct config_s ;config
78
	good_length dw ? ;uint_16 ;reduce lazy search above this match length
78
	good_length dw ? ;uint_16 ;reduce lazy search above this match length
79
	max_lazy    dw ? ;uint_16 ;do not perform lazy search above this match length
79
	max_lazy    dw ? ;uint_16 ;do not perform lazy search above this match length
80
	nice_length dw ? ;uint_16 ;quit search above this match length
80
	nice_length dw ? ;uint_16 ;quit search above this match length
81
	max_chain   dw ? ;uint_16
81
	max_chain   dw ? ;uint_16
82
	co_func     dd ? ;compress_func
82
	co_func     dd ? ;compress_func
83
ends
83
ends
84
 
84
 
85
align 16
85
align 16
86
configuration_table:
86
configuration_table:
87
	config_s  0,   0,   0,    0, deflate_stored  ;store only
87
	config_s  0,   0,   0,    0, deflate_stored  ;store only
88
	config_s  4,   4,   8,    4, deflate_fast ;max speed, no lazy matches
88
	config_s  4,   4,   8,    4, deflate_fast ;max speed, no lazy matches
89
if FASTEST eq 0
89
if FASTEST eq 0
90
	config_s  4,   5,  16,    8, deflate_fast
90
	config_s  4,   5,  16,    8, deflate_fast
91
	config_s  4,   6,  32,   32, deflate_fast
91
	config_s  4,   6,  32,   32, deflate_fast
92
	config_s  4,   4,  16,   16, deflate_slow ;lazy matches
92
	config_s  4,   4,  16,   16, deflate_slow ;lazy matches
93
	config_s  8,  16,  32,   32, deflate_slow
93
	config_s  8,  16,  32,   32, deflate_slow
94
	config_s  8,  16, 128,  128, deflate_slow
94
	config_s  8,  16, 128,  128, deflate_slow
95
	config_s  8,  32, 128,  256, deflate_slow
95
	config_s  8,  32, 128,  256, deflate_slow
96
	config_s 32, 128, 258, 1024, deflate_slow
96
	config_s 32, 128, 258, 1024, deflate_slow
97
	config_s 32, 258, 258, 4096, deflate_slow ;max compression
97
	config_s 32, 258, 258, 4096, deflate_slow ;max compression
98
end if
98
end if
99
 
99
 
100
; Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
100
; Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
101
; For deflate_fast() (levels <= 3) good is ignored and lazy has a different
101
; For deflate_fast() (levels <= 3) good is ignored and lazy has a different
102
; meaning.
102
; meaning.
103
 
103
 
104
 
104
 
105
EQUAL equ 0
105
EQUAL equ 0
106
; result of memcmp for equal strings
106
; result of memcmp for equal strings
107
 
107
 
108
; rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH
108
; rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH
109
macro RANK f, reg
109
macro RANK f, reg
110
{
110
{
111
local .end0
111
local .end0
112
	xor reg,reg
112
	xor reg,reg
113
	cmp f,4
113
	cmp f,4
114
	jle .end0
114
	jle .end0
115
		sub reg,9
115
		sub reg,9
116
	.end0:
116
	.end0:
117
	add reg,f
117
	add reg,f
118
	add reg,f
118
	add reg,f
119
}
119
}
120
 
120
 
121
; ===========================================================================
121
; ===========================================================================
122
; Update a hash value with the given input byte
122
; Update a hash value with the given input byte
123
; IN  assertion: all calls to to UPDATE_HASH are made with consecutive
123
; IN  assertion: all calls to to UPDATE_HASH are made with consecutive
124
;    input characters, so that a running hash key can be computed from the
124
;    input characters, so that a running hash key can be computed from the
125
;    previous key instead of complete recalculation each time.
125
;    previous key instead of complete recalculation each time.
126
 
126
 
127
macro UPDATE_HASH s,h,c
127
macro UPDATE_HASH s,h,c
128
{
128
{
129
push ebx ecx
129
push ebx ecx
130
	mov ebx,h
130
	mov ebx,h
131
	mov ecx,[s+deflate_state.hash_shift]
131
	mov ecx,[s+deflate_state.hash_shift]
132
	shl ebx,cl
132
	shl ebx,cl
133
	xor ebx,c
133
	xor ebx,c
134
	and ebx,[s+deflate_state.hash_mask]
134
	and ebx,[s+deflate_state.hash_mask]
135
	mov h,ebx
135
	mov h,ebx
136
pop ecx ebx
136
pop ecx ebx
137
}
137
}
138
 
138
 
139
; ===========================================================================
139
; ===========================================================================
140
; Insert string str in the dictionary and set match_head to the previous head
140
; Insert string str in the dictionary and set match_head to the previous head
141
; of the hash chain (the most recent string with same hash key). Return
141
; of the hash chain (the most recent string with same hash key). Return
142
; the previous length of the hash chain.
142
; the previous length of the hash chain.
143
; If this file is compiled with -DFASTEST, the compression level is forced
143
; If this file is compiled with -DFASTEST, the compression level is forced
144
; to 1, and no hash chains are maintained.
144
; to 1, and no hash chains are maintained.
145
; IN  assertion: all calls to to INSERT_STRING are made with consecutive
145
; IN  assertion: all calls to to INSERT_STRING are made with consecutive
146
;    input characters and the first MIN_MATCH bytes of str are valid
146
;    input characters and the first MIN_MATCH bytes of str are valid
147
;    (except for the last MIN_MATCH-1 bytes of the input file).
147
;    (except for the last MIN_MATCH-1 bytes of the input file).
148
 
148
 
149
macro INSERT_STRING s, str, match_head
149
macro INSERT_STRING s, str, match_head
150
{
150
{
151
	mov eax,[s+deflate_state.window]
151
	mov eax,[s+deflate_state.window]
152
	add eax,str
152
	add eax,str
153
	add eax,MIN_MATCH-1
153
	add eax,MIN_MATCH-1
154
	movzx eax,byte[eax]
154
	movzx eax,byte[eax]
155
	UPDATE_HASH s, [s+deflate_state.ins_h], eax
155
	UPDATE_HASH s, [s+deflate_state.ins_h], eax
156
	mov eax,[s+deflate_state.ins_h]
156
	mov eax,[s+deflate_state.ins_h]
157
	shl eax,2
157
	shl eax,2
158
	add eax,[s+deflate_state.head]
158
	add eax,[s+deflate_state.head]
159
	mov eax,[eax]
159
	mov eax,[eax]
160
	mov match_head,eax
160
	mov match_head,eax
161
if FASTEST eq 0
161
if FASTEST eq 0
162
push ebx
162
push ebx
163
	mov ebx,[s+deflate_state.w_mask]
163
	mov ebx,[s+deflate_state.w_mask]
164
	and ebx,str
164
	and ebx,str
165
	shl ebx,2
165
	shl ebx,2
166
	add ebx,[s+deflate_state.prev]
166
	add ebx,[s+deflate_state.prev]
167
	mov [ebx],eax
167
	mov [ebx],eax
168
pop ebx
168
pop ebx
169
end if
169
end if
170
	mov eax,[s+deflate_state.ins_h]
170
	mov eax,[s+deflate_state.ins_h]
171
	shl eax,2
171
	shl eax,2
172
	add eax,[s+deflate_state.head]
172
	add eax,[s+deflate_state.head]
173
	push str
173
	push str
174
	pop dword[eax]
174
	pop dword[eax]
175
}
175
}
176
 
176
 
177
; ===========================================================================
177
; ===========================================================================
178
; Initialize the hash table (avoiding 64K overflow for 16 bit systems).
178
; Initialize the hash table (avoiding 64K overflow for 16 bit systems).
179
; prev[] will be initialized on the fly.
179
; prev[] will be initialized on the fly.
180
 
180
 
181
macro CLEAR_HASH s
181
macro CLEAR_HASH s
182
{
182
{
183
	;mov eax,[s+deflate_state.hash_size]
183
	;mov eax,[s+deflate_state.hash_size]
184
	;dec eax
184
	;dec eax
185
	;shl eax,2
185
	;shl eax,2
186
	;add eax,[s+deflate_state.head]
186
	;add eax,[s+deflate_state.head]
187
	;mov dword[eax],NIL
187
	;mov dword[eax],NIL
188
	mov eax,[s+deflate_state.hash_size]
188
	mov eax,[s+deflate_state.hash_size]
189
	;dec eax
189
	;dec eax
190
	shl eax,2 ;sizeof(*s.head)
190
	shl eax,2 ;sizeof(*s.head)
191
	stdcall zmemzero, [s+deflate_state.head], eax
191
	stdcall zmemzero, [s+deflate_state.head], eax
192
}
192
}
193
 
193
 
194
align 4
194
align 4
195
proc deflateInit, strm:dword, level:dword
195
proc deflateInit, strm:dword, level:dword
196
	stdcall deflateInit_, [strm], [level], ZLIB_VERSION, sizeof.z_stream
196
	stdcall deflateInit_, [strm], [level], ZLIB_VERSION, sizeof.z_stream
197
	ret
197
	ret
198
endp
198
endp
199
 
199
 
200
; =========================================================================
200
; =========================================================================
201
;int (strm, level, version, stream_size)
201
;int (strm, level, version, stream_size)
202
;    z_streamp strm
202
;    z_streamp strm
203
;    int level
203
;    int level
204
;    const char *version
204
;    const char *version
205
;    int stream_size
205
;    int stream_size
206
align 4
206
align 4
207
proc deflateInit_, strm:dword, level:dword, version:dword, stream_size:dword
207
proc deflateInit_, strm:dword, level:dword, version:dword, stream_size:dword
208
	stdcall deflateInit2_, [strm], [level], Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,\
208
	stdcall deflateInit2_, [strm], [level], Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,\
209
			Z_DEFAULT_STRATEGY, [version], [stream_size]
209
			Z_DEFAULT_STRATEGY, [version], [stream_size]
210
	; To do: ignore strm->next_in if we use it as window
210
	; To do: ignore strm->next_in if we use it as window
211
	ret
211
	ret
212
endp
212
endp
213
 
213
 
214
align 4
214
align 4
215
proc deflateInit2, strm:dword, level:dword, method:dword, windowBits:dword, memLevel:dword, strategy:dword
215
proc deflateInit2, strm:dword, level:dword, method:dword, windowBits:dword, memLevel:dword, strategy:dword
216
	stdcall deflateInit2_, [strm],[level],[method],[windowBits],[memLevel],\
216
	stdcall deflateInit2_, [strm],[level],[method],[windowBits],[memLevel],\
217
		[strategy], ZLIB_VERSION, sizeof.z_stream
217
		[strategy], ZLIB_VERSION, sizeof.z_stream
218
	ret
218
	ret
219
endp
219
endp
220
 
220
 
221
; =========================================================================
221
; =========================================================================
222
;int (strm, level, method, windowBits, memLevel, strategy,
222
;int (strm, level, method, windowBits, memLevel, strategy,
223
;                  version, stream_size)
223
;                  version, stream_size)
224
;    z_streamp strm
224
;    z_streamp strm
225
;    int  level
225
;    int  level
226
;    int  method
226
;    int  method
227
;    int  windowBits
227
;    int  windowBits
228
;    int  memLevel
228
;    int  memLevel
229
;    int  strategy
229
;    int  strategy
230
;    const char *version
230
;    const char *version
231
;    int stream_size
231
;    int stream_size
232
align 4
232
align 4
233
proc deflateInit2_ uses ebx ecx edx edi, strm:dword, level:dword, method:dword,\
233
proc deflateInit2_ uses ebx ecx edx edi, strm:dword, level:dword, method:dword,\
234
	windowBits:dword, memLevel:dword, strategy:dword, version:dword, stream_size:dword
234
	windowBits:dword, memLevel:dword, strategy:dword, version:dword, stream_size:dword
235
locals
235
locals
236
	wrap dd 1 ;int
236
	wrap dd 1 ;int
237
	overlay dd ? ;uint_16p
237
	overlay dd ? ;uint_16p
238
endl
238
endl
239
	; We overlay pending_buf and d_buf+l_buf. This works since the average
239
	; We overlay pending_buf and d_buf+l_buf. This works since the average
240
	; output size for (length,distance) codes is <= 24 bits.
240
	; output size for (length,distance) codes is <= 24 bits.
241
 
241
 
242
	mov eax,[version]
242
	mov eax,[version]
243
	cmp eax,Z_NULL
243
	cmp eax,Z_NULL
244
	je @f
244
	je @f
245
	mov ebx,dword[ZLIB_VERSION]
245
	mov ebx,dword[ZLIB_VERSION]
246
	cmp dword[eax],ebx
246
	cmp dword[eax],ebx
247
	jne @f
247
	jne @f
248
	cmp dword[stream_size],sizeof.z_stream
248
	cmp dword[stream_size],sizeof.z_stream
249
	je .end0
249
	je .end0
250
	@@: ;if (..==0 || ..[0]!=..[0] || ..!=..)
250
	@@: ;if (..==0 || ..[0]!=..[0] || ..!=..)
251
		mov eax,Z_VERSION_ERROR
251
		mov eax,Z_VERSION_ERROR
252
		jmp .end_f
252
		jmp .end_f
253
	.end0:
253
	.end0:
254
	mov ebx,[strm]
254
	mov ebx,[strm]
255
	cmp ebx,Z_NULL
255
	cmp ebx,Z_NULL
256
	jne @f ;if (..==0) return ..
256
	jne @f ;if (..==0) return ..
257
		mov eax,Z_STREAM_ERROR
257
		mov eax,Z_STREAM_ERROR
258
		jmp .end_f
258
		jmp .end_f
259
	@@:
259
	@@:
260
 
260
 
261
	mov dword[ebx+z_stream.msg],Z_NULL
261
	mov dword[ebx+z_stream.msg],Z_NULL
262
	cmp dword[ebx+z_stream.zalloc],0
262
	cmp dword[ebx+z_stream.zalloc],0
263
	jne @f ;if (..==0)
263
	jne @f ;if (..==0)
264
if Z_SOLO eq 1
264
if Z_SOLO eq 1
265
		mov eax,Z_STREAM_ERROR
265
		mov eax,Z_STREAM_ERROR
266
		jmp .end_f
266
		jmp .end_f
267
else
267
else
268
		mov dword[ebx+z_stream.zalloc],zcalloc
268
		mov dword[ebx+z_stream.zalloc],zcalloc
269
		mov dword[ebx+z_stream.opaque],0
269
		mov dword[ebx+z_stream.opaque],0
270
end if
270
end if
271
	@@:
271
	@@:
272
	cmp dword[ebx+z_stream.zfree],0
272
	cmp dword[ebx+z_stream.zfree],0
273
	jne @f ;if (..==0)
273
	jne @f ;if (..==0)
274
if Z_SOLO eq 1
274
if Z_SOLO eq 1
275
		mov eax,Z_STREAM_ERROR
275
		mov eax,Z_STREAM_ERROR
276
		jmp .end_f
276
		jmp .end_f
277
else
277
else
278
		mov dword[ebx+z_stream.zfree],zcfree
278
		mov dword[ebx+z_stream.zfree],zcfree
279
end if
279
end if
280
	@@:
280
	@@:
281
 
281
 
282
if FASTEST eq 1
282
if FASTEST eq 1
283
	cmp dword[level],0
283
	cmp dword[level],0
284
	je @f ;if (..!=0)
284
	je @f ;if (..!=0)
285
		mov dword[level],1
285
		mov dword[level],1
286
	@@:
286
	@@:
287
else
287
else
288
	cmp dword[level],Z_DEFAULT_COMPRESSION
288
	cmp dword[level],Z_DEFAULT_COMPRESSION
289
	jne @f ;if (..==0)
289
	jne @f ;if (..==0)
290
		mov dword[level],6
290
		mov dword[level],6
291
	@@:
291
	@@:
292
end if
292
end if
293
 
293
 
294
	cmp dword[windowBits],0
294
	cmp dword[windowBits],0
295
	jge @f ;if (..<0) ;suppress zlib wrapper
295
	jge @f ;if (..<0) ;suppress zlib wrapper
296
		mov dword[wrap],0
296
		mov dword[wrap],0
297
		neg dword[windowBits]
297
		neg dword[windowBits]
298
		inc dword[windowBits]
298
		inc dword[windowBits]
299
		jmp .end1
299
		jmp .end1
300
	@@:
300
	@@:
301
if GZIP eq 1
301
if GZIP eq 1
302
	cmp dword[windowBits],15
302
	cmp dword[windowBits],15
303
	jle .end1 ;else if (..>15)
303
	jle .end1 ;else if (..>15)
304
		mov dword[wrap],2 ;write gzip wrapper instead
304
		mov dword[wrap],2 ;write gzip wrapper instead
305
		sub dword[windowBits],16
305
		sub dword[windowBits],16
306
end if
306
end if
307
	.end1:
307
	.end1:
308
	cmp dword[memLevel],1
308
	cmp dword[memLevel],1
309
	jl .end2
309
	jl .end2
310
	cmp dword[memLevel],MAX_MEM_LEVEL
310
	cmp dword[memLevel],MAX_MEM_LEVEL
311
	jg .end2
311
	jg .end2
312
	cmp dword[method],Z_DEFLATED
312
	cmp dword[method],Z_DEFLATED
313
	jne .end2
313
	jne .end2
314
	cmp dword[windowBits],8
314
	cmp dword[windowBits],8
315
	jl .end2
315
	jl .end2
316
	cmp dword[windowBits],15
316
	cmp dword[windowBits],15
317
	jg .end2
317
	jg .end2
318
	cmp dword[level],0
318
	cmp dword[level],0
319
	jl .end2
319
	jl .end2
320
	cmp dword[level],9
320
	cmp dword[level],9
321
	jg .end2
321
	jg .end2
322
	cmp dword[strategy],0
322
	cmp dword[strategy],0
323
	jl .end2
323
	jl .end2
324
	cmp dword[strategy],Z_FIXED
324
	cmp dword[strategy],Z_FIXED
325
	jle @f
325
	jle @f
326
	.end2: ;if (..<.. || ..>.. || ..!=.. || ..<.. || ..>.. || ..<0 || ..>.. || ..<0 || ..>..)
326
	.end2: ;if (..<.. || ..>.. || ..!=.. || ..<.. || ..>.. || ..<0 || ..>.. || ..<0 || ..>..)
327
		mov eax,Z_STREAM_ERROR
327
		mov eax,Z_STREAM_ERROR
328
		jmp .end_f
328
		jmp .end_f
329
	@@:
329
	@@:
330
	cmp dword[windowBits],8
330
	cmp dword[windowBits],8
331
	jne @f ;if (..==..)
331
	jne @f ;if (..==..)
332
		inc dword[windowBits] ;until 256-byte window bug fixed
332
		inc dword[windowBits] ;until 256-byte window bug fixed
333
	@@:
333
	@@:
334
	ZALLOC ebx, 1, sizeof.deflate_state
334
	ZALLOC ebx, 1, sizeof.deflate_state
335
	;eax = s
335
	;eax = s
336
	cmp eax,Z_NULL
336
	cmp eax,Z_NULL
337
	jne @f ;if (..==0)
337
	jne @f ;if (..==0)
338
		mov eax,Z_MEM_ERROR
338
		mov eax,Z_MEM_ERROR
339
		jmp .end_f
339
		jmp .end_f
340
	@@:
340
	@@:
341
	mov edi,eax ;edi = s
341
	mov edi,eax ;edi = s
342
	mov [ebx+z_stream.state],edi
342
	mov [ebx+z_stream.state],edi
343
	mov [edi+deflate_state.strm],ebx
343
	mov [edi+deflate_state.strm],ebx
344
 
344
 
345
	mov eax,[wrap]
345
	mov eax,[wrap]
346
	mov [edi+deflate_state.wrap],eax
346
	mov [edi+deflate_state.wrap],eax
347
	mov [edi+deflate_state.gzhead],Z_NULL
347
	mov [edi+deflate_state.gzhead],Z_NULL
348
	mov ecx,[windowBits]
348
	mov ecx,[windowBits]
349
	mov [edi+deflate_state.w_bits],ecx
349
	mov [edi+deflate_state.w_bits],ecx
350
	xor eax,eax
350
	xor eax,eax
351
	inc eax
351
	inc eax
352
	shl eax,cl
352
	shl eax,cl
353
	mov [edi+deflate_state.w_size],eax
353
	mov [edi+deflate_state.w_size],eax
354
	dec eax
354
	dec eax
355
	mov [edi+deflate_state.w_mask],eax
355
	mov [edi+deflate_state.w_mask],eax
356
 
356
 
357
	mov ecx,[memLevel]
357
	mov ecx,[memLevel]
358
	add ecx,7
358
	add ecx,7
359
	mov [edi+deflate_state.hash_bits],ecx
359
	mov [edi+deflate_state.hash_bits],ecx
360
	xor eax,eax
360
	xor eax,eax
361
	inc eax
361
	inc eax
362
	shl eax,cl
362
	shl eax,cl
363
	mov [edi+deflate_state.hash_size],eax
363
	mov [edi+deflate_state.hash_size],eax
364
	dec eax
364
	dec eax
365
	mov [edi+deflate_state.hash_mask],eax
365
	mov [edi+deflate_state.hash_mask],eax
366
	add ecx,MIN_MATCH-1
366
	add ecx,MIN_MATCH-1
367
	xor edx,edx
367
	xor edx,edx
368
	mov eax,ecx
368
	mov eax,ecx
369
	mov ecx,MIN_MATCH
369
	mov ecx,MIN_MATCH
370
	div ecx
370
	div ecx
371
	mov [edi+deflate_state.hash_shift],eax
371
	mov [edi+deflate_state.hash_shift],eax
372
 
372
 
373
	ZALLOC ebx, [edi+deflate_state.w_size], 2 ;2*sizeof(Byte)
373
	ZALLOC ebx, [edi+deflate_state.w_size], 2 ;2*sizeof(Byte)
374
	mov [edi+deflate_state.window],eax
374
	mov [edi+deflate_state.window],eax
375
	ZALLOC ebx, [edi+deflate_state.w_size], 4 ;sizeof(Pos)
375
	ZALLOC ebx, [edi+deflate_state.w_size], 4 ;sizeof(Pos)
376
	mov [edi+deflate_state.prev],eax
376
	mov [edi+deflate_state.prev],eax
377
	ZALLOC ebx, [edi+deflate_state.hash_size], 4 ;sizeof(Pos)
377
	ZALLOC ebx, [edi+deflate_state.hash_size], 4 ;sizeof(Pos)
378
	mov [edi+deflate_state.head],eax
378
	mov [edi+deflate_state.head],eax
379
 
379
 
380
	mov dword[edi+deflate_state.high_water],0 ;nothing written to s->window yet
380
	mov dword[edi+deflate_state.high_water],0 ;nothing written to s->window yet
381
 
381
 
382
	mov ecx,[memLevel]
382
	mov ecx,[memLevel]
383
	add ecx,6
383
	add ecx,6
384
	xor eax,eax
384
	xor eax,eax
385
	inc eax
385
	inc eax
386
	shl eax,cl
386
	shl eax,cl
387
	mov [edi+deflate_state.lit_bufsize],eax ;16K elements by default
387
	mov [edi+deflate_state.lit_bufsize],eax ;16K elements by default
388
 
388
 
389
	ZALLOC ebx, eax, 4 ;sizeof(uint_16)+2
389
	ZALLOC ebx, eax, 4 ;sizeof(uint_16)+2
390
	mov [overlay],eax
390
	mov [overlay],eax
391
	mov [edi+deflate_state.pending_buf],eax
391
	mov [edi+deflate_state.pending_buf],eax
392
	mov eax,[edi+deflate_state.lit_bufsize]
392
	mov eax,[edi+deflate_state.lit_bufsize]
393
	imul eax,4 ;sizeof(uint_16)+2
393
	imul eax,4 ;sizeof(uint_16)+2
394
	mov [edi+deflate_state.pending_buf_size],eax
394
	mov [edi+deflate_state.pending_buf_size],eax
395
 
395
 
396
	cmp dword[edi+deflate_state.window],Z_NULL
396
	cmp dword[edi+deflate_state.window],Z_NULL
397
	je .end3
397
	je .end3
398
	cmp dword[edi+deflate_state.prev],Z_NULL
398
	cmp dword[edi+deflate_state.prev],Z_NULL
399
	je .end3
399
	je .end3
400
	cmp dword[edi+deflate_state.head],Z_NULL
400
	cmp dword[edi+deflate_state.head],Z_NULL
401
	je .end3
401
	je .end3
402
	cmp dword[edi+deflate_state.pending_buf],Z_NULL
402
	cmp dword[edi+deflate_state.pending_buf],Z_NULL
403
	je .end3
403
	je .end3
404
		jmp @f
404
		jmp @f
405
	.end3: ;if (..==0 || ..==0 || ..==0 || ..==0)
405
	.end3: ;if (..==0 || ..==0 || ..==0 || ..==0)
406
		mov dword[edi+deflate_state.status],FINISH_STATE
406
		mov dword[edi+deflate_state.status],FINISH_STATE
407
		ERR_MSG Z_MEM_ERROR
407
		ERR_MSG Z_MEM_ERROR
408
		mov [ebx+z_stream.msg],eax
408
		mov [ebx+z_stream.msg],eax
409
		stdcall deflateEnd, ebx
409
		stdcall deflateEnd, ebx
410
		mov eax,Z_MEM_ERROR
410
		mov eax,Z_MEM_ERROR
411
		jmp .end_f
411
		jmp .end_f
412
	@@:
412
	@@:
413
	mov eax,[edi+deflate_state.lit_bufsize]
413
	mov eax,[edi+deflate_state.lit_bufsize]
414
	shr eax,1 ;/=sizeof(uint_16)
414
	shr eax,1 ;/=sizeof(uint_16)
415
	add eax,[overlay]
415
	add eax,[overlay]
416
	mov [edi+deflate_state.d_buf],eax
416
	mov [edi+deflate_state.d_buf],eax
417
	mov eax,[edi+deflate_state.lit_bufsize]
417
	mov eax,[edi+deflate_state.lit_bufsize]
418
	imul eax,3 ;1+sizeof(uint_16)
418
	imul eax,3 ;1+sizeof(uint_16)
419
	add eax,[edi+deflate_state.pending_buf]
419
	add eax,[edi+deflate_state.pending_buf]
420
	mov [edi+deflate_state.l_buf],eax
420
	mov [edi+deflate_state.l_buf],eax
421
 
421
 
422
	mov eax,[level]
422
	mov eax,[level]
423
	mov [edi+deflate_state.level],ax
423
	mov [edi+deflate_state.level],ax
424
	mov eax,[strategy]
424
	mov eax,[strategy]
425
	mov [edi+deflate_state.strategy],ax
425
	mov [edi+deflate_state.strategy],ax
426
	mov eax,[method]
426
	mov eax,[method]
427
	mov [edi+deflate_state.method],al
427
	mov [edi+deflate_state.method],al
428
 
428
 
429
	stdcall deflateReset, ebx
429
	stdcall deflateReset, ebx
430
.end_f:
430
.end_f:
431
zlib_debug 'deflateInit2_ strategy = %d',[strategy]
431
zlib_debug 'deflateInit2_ strategy = %d',[strategy]
432
	ret
432
	ret
433
endp
433
endp
434
 
434
 
435
; =========================================================================
435
; =========================================================================
436
;int (strm, dictionary, dictLength)
436
;int (strm, dictionary, dictLength)
437
;    z_streamp strm
437
;    z_streamp strm
438
;    const Bytef *dictionary
438
;    const Bytef *dictionary
439
;    uInt  dictLength
439
;    uInt  dictLength
440
align 4
440
align 4
441
proc deflateSetDictionary uses ebx edi, strm:dword, dictionary:dword, dictLength:dword
441
proc deflateSetDictionary uses ebx edi, strm:dword, dictionary:dword, dictLength:dword
442
locals
442
locals
443
;    uInt str, n;
443
;    uInt str, n;
444
	wrap  dd ? ;int
444
	wrap  dd ? ;int
445
	avail dd ? ;unsigned
445
	avail dd ? ;unsigned
446
	next  dd ? ;unsigned char*
446
	next  dd ? ;unsigned char*
447
endl
447
endl
448
	mov ebx,[strm]
448
	mov ebx,[strm]
449
	cmp ebx,Z_NULL
449
	cmp ebx,Z_NULL
450
	je @f
450
	je @f
451
	mov edi,[ebx+z_stream.state]
451
	mov edi,[ebx+z_stream.state]
452
	cmp edi,Z_NULL
452
	cmp edi,Z_NULL
453
	je @f
453
	je @f
454
	cmp dword[dictionary],Z_NULL
454
	cmp dword[dictionary],Z_NULL
455
	je @f ;if (..==0 || ..==0 || ..==0)
455
	je @f ;if (..==0 || ..==0 || ..==0)
456
		jmp .end0
456
		jmp .end0
457
	@@:
457
	@@:
458
		mov eax,Z_STREAM_ERROR
458
		mov eax,Z_STREAM_ERROR
459
		jmp .end_f
459
		jmp .end_f
460
	.end0:
460
	.end0:
461
	
461
	
462
	mov eax,[edi+deflate_state.wrap]
462
	mov eax,[edi+deflate_state.wrap]
463
	mov [wrap],eax
463
	mov [wrap],eax
464
	cmp dword[wrap],2
464
	cmp dword[wrap],2
465
	je .end1
465
	je .end1
466
	cmp dword[edi+deflate_state.lookahead],0
466
	cmp dword[edi+deflate_state.lookahead],0
467
	jne .end1
467
	jne .end1
468
	cmp dword[wrap],1
468
	cmp dword[wrap],1
469
	jne @f
469
	jne @f
470
	cmp dword[edi+deflate_state.status],INIT_STATE
470
	cmp dword[edi+deflate_state.status],INIT_STATE
471
	je @f
471
	je @f
472
	.end1: ;if (..==.. || .. || (..==.. && ..!=..)) return ..
472
	.end1: ;if (..==.. || .. || (..==.. && ..!=..)) return ..
473
		mov eax,Z_STREAM_ERROR
473
		mov eax,Z_STREAM_ERROR
474
		jmp .end_f
474
		jmp .end_f
475
	@@:
475
	@@:
476
 
476
 
477
	; when using zlib wrappers, compute Adler-32 for provided dictionary
477
	; when using zlib wrappers, compute Adler-32 for provided dictionary
478
	cmp dword[wrap],1
478
	cmp dword[wrap],1
479
	jne @f ;if (..==..)
479
	jne @f ;if (..==..)
480
		stdcall adler32, [ebx+z_stream.adler], [dictionary], [dictLength]
480
		stdcall adler32, [ebx+z_stream.adler], [dictionary], [dictLength]
481
		mov [ebx+z_stream.adler],eax
481
		mov [ebx+z_stream.adler],eax
482
	@@:
482
	@@:
483
	mov dword[edi+deflate_state.wrap],0 ;avoid computing Adler-32 in read_buf
483
	mov dword[edi+deflate_state.wrap],0 ;avoid computing Adler-32 in read_buf
484
 
484
 
485
	; if dictionary would fill window, just replace the history
485
	; if dictionary would fill window, just replace the history
486
	mov eax,[edi+deflate_state.w_size]
486
	mov eax,[edi+deflate_state.w_size]
487
	cmp [dictLength],eax
487
	cmp [dictLength],eax
488
	jl .end2 ;if (..>=..)
488
	jl .end2 ;if (..>=..)
489
;        if (wrap == 0) {            /* already empty otherwise */
489
;        if (wrap == 0) {            /* already empty otherwise */
490
;            CLEAR_HASH(s);
490
;            CLEAR_HASH(s);
491
;            s->strstart = 0;
491
;            s->strstart = 0;
492
;            s->block_start = 0L;
492
;            s->block_start = 0L;
493
;            s->insert = 0;
493
;            s->insert = 0;
494
;        }
494
;        }
495
;        dictionary += dictLength - s->w_size;  /* use the tail */
495
;        dictionary += dictLength - s->w_size;  /* use the tail */
496
		mov eax,[edi+deflate_state.w_size]
496
		mov eax,[edi+deflate_state.w_size]
497
		mov [dictLength],eax
497
		mov [dictLength],eax
498
	.end2:
498
	.end2:
499
 
499
 
500
	; insert dictionary into window and hash
500
	; insert dictionary into window and hash
501
;    avail = strm->avail_in;
501
;    avail = strm->avail_in;
502
;    next = strm->next_in;
502
;    next = strm->next_in;
503
;    strm->avail_in = dictLength;
503
;    strm->avail_in = dictLength;
504
;    strm->next_in = (z_const Bytef *)dictionary;
504
;    strm->next_in = (z_const Bytef *)dictionary;
505
;    fill_window(s);
505
;    fill_window(s);
506
;    while (s->lookahead >= MIN_MATCH) {
506
;    while (s->lookahead >= MIN_MATCH) {
507
;        str = s->strstart;
507
;        str = s->strstart;
508
;        n = s->lookahead - (MIN_MATCH-1);
508
;        n = s->lookahead - (MIN_MATCH-1);
509
;        do {
509
;        do {
510
;            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
510
;            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
511
if FASTEST eq 0
511
if FASTEST eq 0
512
;            s->prev[str & s->w_mask] = s->head[s->ins_h];
512
;            s->prev[str & s->w_mask] = s->head[s->ins_h];
513
end if
513
end if
514
;            s->head[s->ins_h] = (Pos)str;
514
;            s->head[s->ins_h] = (Pos)str;
515
;            str++;
515
;            str++;
516
;        } while (--n);
516
;        } while (--n);
517
;        s->strstart = str;
517
;        s->strstart = str;
518
;        s->lookahead = MIN_MATCH-1;
518
;        s->lookahead = MIN_MATCH-1;
519
;        fill_window(s);
519
;        fill_window(s);
520
;    }
520
;    }
521
;    s->strstart += s->lookahead;
521
;    s->strstart += s->lookahead;
522
;    s->block_start = (long)s->strstart;
522
;    s->block_start = (long)s->strstart;
523
	mov eax,[edi+deflate_state.lookahead]
523
	mov eax,[edi+deflate_state.lookahead]
524
	mov [edi+deflate_state.insert],eax
524
	mov [edi+deflate_state.insert],eax
525
	mov dword[edi+deflate_state.lookahead],0
525
	mov dword[edi+deflate_state.lookahead],0
526
	mov eax,MIN_MATCH-1
526
	mov eax,MIN_MATCH-1
527
	mov [edi+deflate_state.prev_length],eax
527
	mov [edi+deflate_state.prev_length],eax
528
	mov [edi+deflate_state.match_length],eax
528
	mov [edi+deflate_state.match_length],eax
529
	mov dword[edi+deflate_state.match_available],0
529
	mov dword[edi+deflate_state.match_available],0
530
	mov eax,[next]
530
	mov eax,[next]
531
	mov [ebx+z_stream.next_in],eax
531
	mov [ebx+z_stream.next_in],eax
532
	mov eax,[avail]
532
	mov eax,[avail]
533
	mov [ebx+z_stream.avail_in],eax
533
	mov [ebx+z_stream.avail_in],eax
534
	mov eax,[wrap]
534
	mov eax,[wrap]
535
	mov [edi+deflate_state.wrap],eax
535
	mov [edi+deflate_state.wrap],eax
536
	mov eax,Z_OK
536
	mov eax,Z_OK
537
.end_f:
537
.end_f:
538
	ret
538
	ret
539
endp
539
endp
540
 
540
 
541
; =========================================================================
541
; =========================================================================
542
;int (strm)
542
;int (strm)
543
;    z_streamp strm
543
;    z_streamp strm
544
align 4
544
align 4
545
proc deflateResetKeep uses ebx edi, strm:dword
545
proc deflateResetKeep uses ebx edi, strm:dword
546
	mov ebx,[strm]
546
	mov ebx,[strm]
547
	cmp ebx,Z_NULL
547
	cmp ebx,Z_NULL
548
	je @f
548
	je @f
549
	mov edi,[ebx+z_stream.state]
549
	mov edi,[ebx+z_stream.state]
550
	cmp edi,Z_NULL
550
	cmp edi,Z_NULL
551
	je @f
551
	je @f
552
	cmp dword[ebx+z_stream.zalloc],0
552
	cmp dword[ebx+z_stream.zalloc],0
553
	je @f
553
	je @f
554
	cmp dword[ebx+z_stream.zfree],0
554
	cmp dword[ebx+z_stream.zfree],0
555
	je @f ;if (..==0 || ..==0 || ..==0 || ..==0)
555
	je @f ;if (..==0 || ..==0 || ..==0 || ..==0)
556
		jmp .end0
556
		jmp .end0
557
	@@:
557
	@@:
558
		mov eax,Z_STREAM_ERROR
558
		mov eax,Z_STREAM_ERROR
559
		jmp .end_f
559
		jmp .end_f
560
	.end0:
560
	.end0:
561
 
561
 
562
	mov dword[ebx+z_stream.total_out],0
562
	mov dword[ebx+z_stream.total_out],0
563
	mov dword[ebx+z_stream.total_in],0
563
	mov dword[ebx+z_stream.total_in],0
564
	mov dword[ebx+z_stream.msg],Z_NULL ;use zfree if we ever allocate msg dynamically
564
	mov dword[ebx+z_stream.msg],Z_NULL ;use zfree if we ever allocate msg dynamically
565
	mov dword[ebx+z_stream.data_type],Z_UNKNOWN
565
	mov dword[ebx+z_stream.data_type],Z_UNKNOWN
566
 
566
 
567
	mov dword[edi+deflate_state.pending],0
567
	mov dword[edi+deflate_state.pending],0
568
	mov eax,[edi+deflate_state.pending_buf]
568
	mov eax,[edi+deflate_state.pending_buf]
569
	mov [edi+deflate_state.pending_out],eax
569
	mov [edi+deflate_state.pending_out],eax
570
 
570
 
571
	cmp dword[edi+deflate_state.wrap],0
571
	cmp dword[edi+deflate_state.wrap],0
572
	jge @f ;if (..<0)
572
	jge @f ;if (..<0)
573
		neg dword[edi+deflate_state.wrap]
573
		neg dword[edi+deflate_state.wrap]
574
		inc dword[edi+deflate_state.wrap] ;was made negative by deflate(..., Z_FINISH)
574
		inc dword[edi+deflate_state.wrap] ;was made negative by deflate(..., Z_FINISH)
575
	@@:
575
	@@:
576
	mov eax,BUSY_STATE
576
	mov eax,BUSY_STATE
577
	cmp dword[edi+deflate_state.wrap],0
577
	cmp dword[edi+deflate_state.wrap],0
578
	je @f
578
	je @f
579
		mov eax,INIT_STATE
579
		mov eax,INIT_STATE
580
	@@:
580
	@@:
581
	mov dword[edi+deflate_state.status],eax
581
	mov dword[edi+deflate_state.status],eax
582
	stdcall adler32, 0, Z_NULL, 0
582
	stdcall adler32, 0, Z_NULL, 0
583
if GZIP eq 1
583
if GZIP eq 1
584
	cmp dword[edi+deflate_state.wrap],2
584
	cmp dword[edi+deflate_state.wrap],2
585
	jne @f
585
	jne @f
586
		xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
586
		xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
587
	@@:
587
	@@:
588
end if
588
end if
589
	mov dword[ebx+z_stream.adler],eax
589
	mov dword[ebx+z_stream.adler],eax
590
	mov dword[edi+deflate_state.last_flush],Z_NO_FLUSH
590
	mov dword[edi+deflate_state.last_flush],Z_NO_FLUSH
591
	stdcall _tr_init, edi
591
	stdcall _tr_init, edi
592
 
592
 
593
	mov eax,Z_OK
593
	mov eax,Z_OK
594
.end_f:
594
.end_f:
595
	ret
595
	ret
596
endp
596
endp
597
 
597
 
598
; =========================================================================
598
; =========================================================================
599
;int (strm)
599
;int (strm)
600
;    z_streamp strm
600
;    z_streamp strm
601
align 4
601
align 4
602
proc deflateReset uses ebx, strm:dword
602
proc deflateReset uses ebx, strm:dword
603
	mov ebx,[strm]
603
	mov ebx,[strm]
604
	zlib_debug 'deflateReset'
604
	zlib_debug 'deflateReset'
605
	stdcall deflateResetKeep, ebx
605
	stdcall deflateResetKeep, ebx
606
	cmp eax,Z_OK
606
	cmp eax,Z_OK
607
	jne @f ;if (..==Z_OK)
607
	jne @f ;if (..==Z_OK)
608
		stdcall lm_init, [ebx+z_stream.state]
608
		stdcall lm_init, [ebx+z_stream.state]
609
	@@:
609
	@@:
610
	ret
610
	ret
611
endp
611
endp
612
 
612
 
613
; =========================================================================
613
; =========================================================================
614
;int (strm, head)
614
;int (strm, head)
615
;    z_streamp strm
615
;    z_streamp strm
616
;    gz_headerp head
616
;    gz_headerp head
617
align 4
617
align 4
618
proc deflateSetHeader uses ebx, strm:dword, head:dword
618
proc deflateSetHeader uses ebx, strm:dword, head:dword
619
	mov ebx,[strm]
619
	mov ebx,[strm]
620
	cmp ebx,Z_NULL
620
	cmp ebx,Z_NULL
621
	je @f
621
	je @f
622
	mov ebx,[ebx+z_stream.state]
622
	mov ebx,[ebx+z_stream.state]
623
	cmp ebx,Z_NULL
623
	cmp ebx,Z_NULL
624
	jne .end0
624
	jne .end0
625
	@@: ;if (..==0 || ..==0) return ..
625
	@@: ;if (..==0 || ..==0) return ..
626
		mov eax,Z_STREAM_ERROR
626
		mov eax,Z_STREAM_ERROR
627
		jmp .end_f
627
		jmp .end_f
628
	.end0:
628
	.end0:
629
	cmp dword[ebx+deflate_state.wrap],2
629
	cmp dword[ebx+deflate_state.wrap],2
630
	je @f ;if (..!=..) return ..
630
	je @f ;if (..!=..) return ..
631
		mov eax,Z_STREAM_ERROR
631
		mov eax,Z_STREAM_ERROR
632
		jmp .end_f
632
		jmp .end_f
633
	@@:
633
	@@:
634
	mov eax,[head]
634
	mov eax,[head]
635
	mov [ebx+deflate_state.gzhead],eax
635
	mov [ebx+deflate_state.gzhead],eax
636
	mov eax,Z_OK
636
	mov eax,Z_OK
637
.end_f:
637
.end_f:
638
	ret
638
	ret
639
endp
639
endp
640
 
640
 
641
; =========================================================================
641
; =========================================================================
642
;int (strm, pending, bits)
642
;int (strm, pending, bits)
643
;    unsigned *pending
643
;    unsigned *pending
644
;    int *bits
644
;    int *bits
645
;    z_streamp strm
645
;    z_streamp strm
646
align 4
646
align 4
647
proc deflatePending uses ebx edi, strm:dword, pending:dword, bits:dword
647
proc deflatePending uses ebx edi, strm:dword, pending:dword, bits:dword
648
	mov ebx,[strm]
648
	mov ebx,[strm]
649
	cmp ebx,Z_NULL
649
	cmp ebx,Z_NULL
650
	je @f
650
	je @f
651
	mov edi,[ebx+z_stream.state]
651
	mov edi,[ebx+z_stream.state]
652
	cmp edi,Z_NULL
652
	cmp edi,Z_NULL
653
	jne .end0
653
	jne .end0
654
	@@: ;if (..==0 || ..==0) return ..
654
	@@: ;if (..==0 || ..==0) return ..
655
		mov eax,Z_STREAM_ERROR
655
		mov eax,Z_STREAM_ERROR
656
		jmp .end_f
656
		jmp .end_f
657
	.end0:
657
	.end0:
658
	cmp dword[pending],Z_NULL
658
	cmp dword[pending],Z_NULL
659
	je @f ;if (..!=..)
659
	je @f ;if (..!=..)
660
		mov eax,[pending]
660
		mov eax,[pending]
661
		mov ebx,[edi+deflate_state.pending]
661
		mov ebx,[edi+deflate_state.pending]
662
		mov [eax],ebx
662
		mov [eax],ebx
663
	@@:
663
	@@:
664
	cmp dword[bits],Z_NULL
664
	cmp dword[bits],Z_NULL
665
	je @f ;if (..!=..)
665
	je @f ;if (..!=..)
666
		mov eax,[bits]
666
		mov eax,[bits]
667
		mov ebx,[edi+deflate_state.bi_valid]
667
		mov ebx,[edi+deflate_state.bi_valid]
668
		mov [eax],ebx
668
		mov [eax],ebx
669
	@@:
669
	@@:
670
	mov eax,Z_OK
670
	mov eax,Z_OK
671
.end_f:
671
.end_f:
672
	ret
672
	ret
673
endp
673
endp
674
 
674
 
675
; =========================================================================
675
; =========================================================================
676
;int (strm, bits, value)
676
;int (strm, bits, value)
677
;    z_streamp strm
677
;    z_streamp strm
678
;    int bits
678
;    int bits
679
;    int value
679
;    int value
680
align 4
680
align 4
681
proc deflatePrime uses ebx edi, strm:dword, bits:dword, value:dword
681
proc deflatePrime uses ebx edi, strm:dword, bits:dword, value:dword
682
;    int put;
682
;    int put;
683
 
683
 
684
	mov ebx,[strm]
684
	mov ebx,[strm]
685
	cmp ebx,Z_NULL
685
	cmp ebx,Z_NULL
686
	je @f
686
	je @f
687
	mov edi,[ebx+z_stream.state] ;s = strm.state
687
	mov edi,[ebx+z_stream.state] ;s = strm.state
688
	cmp edi,Z_NULL
688
	cmp edi,Z_NULL
689
	jne .end0
689
	jne .end0
690
	@@: ;if (..==0 || ..==0) return ..
690
	@@: ;if (..==0 || ..==0) return ..
691
		mov eax,Z_STREAM_ERROR
691
		mov eax,Z_STREAM_ERROR
692
		jmp .end_f
692
		jmp .end_f
693
	.end0:
693
	.end0:
694
;    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
694
;    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
695
;        return Z_BUF_ERROR;
695
;        return Z_BUF_ERROR;
696
;    do {
696
;    do {
697
;        put = Buf_size - s->bi_valid;
697
;        put = Buf_size - s->bi_valid;
698
;        if (put > bits)
698
;        if (put > bits)
699
;            put = bits;
699
;            put = bits;
700
;        s->bi_buf |= (uint_16)((value & ((1 << put) - 1)) << s->bi_valid);
700
;        s->bi_buf |= (uint_16)((value & ((1 << put) - 1)) << s->bi_valid);
701
;        s->bi_valid += put;
701
;        s->bi_valid += put;
702
;        _tr_flush_bits(s);
702
;        _tr_flush_bits(s);
703
;        value >>= put;
703
;        value >>= put;
704
;        bits -= put;
704
;        bits -= put;
705
;    } while (bits);
705
;    } while (bits);
706
	mov eax,Z_OK
706
	mov eax,Z_OK
707
.end_f:
707
.end_f:
708
	ret
708
	ret
709
endp
709
endp
710
 
710
 
711
; =========================================================================
711
; =========================================================================
712
;int (strm, level, strategy)
712
;int (strm, level, strategy)
713
;    z_streamp strm
713
;    z_streamp strm
714
;    int level
714
;    int level
715
;    int strategy
715
;    int strategy
716
align 4
716
align 4
717
proc deflateParams uses ebx edi, strm:dword, level:dword, strategy:dword
717
proc deflateParams uses ebx edi, strm:dword, level:dword, strategy:dword
718
locals
718
locals
719
	co_func dd ?
719
	co_func dd ?
720
	err dd Z_OK
720
	err dd Z_OK
721
endl
721
endl
722
 
722
 
723
	mov ebx,[strm]
723
	mov ebx,[strm]
724
	cmp ebx,Z_NULL
724
	cmp ebx,Z_NULL
725
	je @f
725
	je @f
726
	mov edi,[ebx+z_stream.state] ;s = strm.state
726
	mov edi,[ebx+z_stream.state] ;s = strm.state
727
	cmp edi,Z_NULL
727
	cmp edi,Z_NULL
728
	jne .end0
728
	jne .end0
729
	@@: ;if (..==0 || ..==0) return ..
729
	@@: ;if (..==0 || ..==0) return ..
730
		mov eax,Z_STREAM_ERROR
730
		mov eax,Z_STREAM_ERROR
731
		jmp .end_f
731
		jmp .end_f
732
	.end0:
732
	.end0:
733
 
733
 
734
if FASTEST eq 1
734
if FASTEST eq 1
735
	cmp dword[level],0
735
	cmp dword[level],0
736
	je @f ;if (..!=0)
736
	je @f ;if (..!=0)
737
		mov dword[level],1
737
		mov dword[level],1
738
	@@:
738
	@@:
739
else
739
else
740
	cmp dword[level],Z_DEFAULT_COMPRESSION
740
	cmp dword[level],Z_DEFAULT_COMPRESSION
741
	jne @f ;if (..==0)
741
	jne @f ;if (..==0)
742
		mov dword[level],6
742
		mov dword[level],6
743
	@@:
743
	@@:
744
end if
744
end if
745
	cmp dword[level],0
745
	cmp dword[level],0
746
	jl @f
746
	jl @f
747
	cmp dword[level],9
747
	cmp dword[level],9
748
	jg @f
748
	jg @f
749
	cmp dword[strategy],0
749
	cmp dword[strategy],0
750
	jl @f
750
	jl @f
751
	cmp dword[strategy],Z_FIXED
751
	cmp dword[strategy],Z_FIXED
752
	jle .end1
752
	jle .end1
753
	@@: ;if (..<0 || ..>9 || ..<0 || ..>..)
753
	@@: ;if (..<0 || ..>9 || ..<0 || ..>..)
754
		mov eax,Z_STREAM_ERROR
754
		mov eax,Z_STREAM_ERROR
755
		jmp .end_f
755
		jmp .end_f
756
	.end1:
756
	.end1:
757
	movzx eax,word[edi+deflate_state.level]
757
	movzx eax,word[edi+deflate_state.level]
758
	imul eax,sizeof.config_s
758
	imul eax,sizeof.config_s
759
	add eax,configuration_table+config_s.co_func
759
	add eax,configuration_table+config_s.co_func
760
	mov [co_func],eax
760
	mov [co_func],eax
761
 
761
 
762
;    if ((strategy != s->strategy || co_func != configuration_table[level].func) &&
762
;    if ((strategy != s->strategy || co_func != configuration_table[level].func) &&
763
;        strm->total_in != 0) {
763
;        strm->total_in != 0) {
764
		; Flush the last buffer:
764
		; Flush the last buffer:
765
;        err = deflate(strm, Z_BLOCK);
765
;        err = deflate(strm, Z_BLOCK);
766
;        if (err == Z_BUF_ERROR && s->pending == 0)
766
;        if (err == Z_BUF_ERROR && s->pending == 0)
767
;            err = Z_OK;
767
;            err = Z_OK;
768
;    }
768
;    }
769
;    if (s->level != level) {
769
;    if (s->level != level) {
770
;        s->level = level;
770
;        s->level = level;
771
;        s->max_lazy_match   = configuration_table[level].max_lazy;
771
;        s->max_lazy_match   = configuration_table[level].max_lazy;
772
;        s->good_match       = configuration_table[level].good_length;
772
;        s->good_match       = configuration_table[level].good_length;
773
;        s->nice_match       = configuration_table[level].nice_length;
773
;        s->nice_match       = configuration_table[level].nice_length;
774
;        s->max_chain_length = configuration_table[level].max_chain;
774
;        s->max_chain_length = configuration_table[level].max_chain;
775
;    }
775
;    }
776
	mov eax,[strategy]
776
	mov eax,[strategy]
777
	mov [edi+deflate_state.strategy],ax
777
	mov [edi+deflate_state.strategy],ax
778
	mov eax,[err]
778
	mov eax,[err]
779
.end_f:
779
.end_f:
780
	ret
780
	ret
781
endp
781
endp
782
 
782
 
783
; =========================================================================
783
; =========================================================================
784
;int (strm, good_length, max_lazy, nice_length, max_chain)
784
;int (strm, good_length, max_lazy, nice_length, max_chain)
785
;    z_streamp strm
785
;    z_streamp strm
786
;    int good_length
786
;    int good_length
787
;    int max_lazy
787
;    int max_lazy
788
;    int nice_length
788
;    int nice_length
789
;    int max_chain
789
;    int max_chain
790
align 4
790
align 4
791
proc deflateTune uses ebx, strm:dword, good_length:dword, max_lazy:dword,\
791
proc deflateTune uses ebx, strm:dword, good_length:dword, max_lazy:dword,\
792
			nice_length:dword, max_chain:dword
792
			nice_length:dword, max_chain:dword
793
	mov ebx,[strm]
793
	mov ebx,[strm]
794
	cmp ebx,Z_NULL
794
	cmp ebx,Z_NULL
795
	je @f
795
	je @f
796
	cmp dword[ebx+z_stream.state],Z_NULL
796
	cmp dword[ebx+z_stream.state],Z_NULL
797
	jne .end0
797
	jne .end0
798
	@@: ;if (..==0 || ..==0) return ..
798
	@@: ;if (..==0 || ..==0) return ..
799
		mov eax,Z_STREAM_ERROR
799
		mov eax,Z_STREAM_ERROR
800
		jmp .end_f
800
		jmp .end_f
801
	.end0:
801
	.end0:
802
	mov ebx,[ebx+z_stream.state] ;s = strm.state
802
	mov ebx,[ebx+z_stream.state] ;s = strm.state
803
	mov eax,[good_length]
803
	mov eax,[good_length]
804
	mov [ebx+deflate_state.good_match],eax
804
	mov [ebx+deflate_state.good_match],eax
805
	mov eax,[max_lazy]
805
	mov eax,[max_lazy]
806
	mov [ebx+deflate_state.max_lazy_match],eax
806
	mov [ebx+deflate_state.max_lazy_match],eax
807
	mov eax,[nice_length]
807
	mov eax,[nice_length]
808
	mov [ebx+deflate_state.nice_match],eax
808
	mov [ebx+deflate_state.nice_match],eax
809
	mov eax,[max_chain]
809
	mov eax,[max_chain]
810
	mov [ebx+deflate_state.max_chain_length],eax
810
	mov [ebx+deflate_state.max_chain_length],eax
811
	mov eax,Z_OK
811
	mov eax,Z_OK
812
.end_f:
812
.end_f:
813
	ret
813
	ret
814
endp
814
endp
815
 
815
 
816
; =========================================================================
816
; =========================================================================
817
; For the default windowBits of 15 and memLevel of 8, this function returns
817
; For the default windowBits of 15 and memLevel of 8, this function returns
818
; a close to exact, as well as small, upper bound on the compressed size.
818
; a close to exact, as well as small, upper bound on the compressed size.
819
; They are coded as constants here for a reason--if the #define's are
819
; They are coded as constants here for a reason--if the #define's are
820
; changed, then this function needs to be changed as well.  The return
820
; changed, then this function needs to be changed as well.  The return
821
; value for 15 and 8 only works for those exact settings.
821
; value for 15 and 8 only works for those exact settings.
822
 
822
 
823
; For any setting other than those defaults for windowBits and memLevel,
823
; For any setting other than those defaults for windowBits and memLevel,
824
; the value returned is a conservative worst case for the maximum expansion
824
; the value returned is a conservative worst case for the maximum expansion
825
; resulting from using fixed blocks instead of stored blocks, which deflate
825
; resulting from using fixed blocks instead of stored blocks, which deflate
826
; can emit on compressed data for some combinations of the parameters.
826
; can emit on compressed data for some combinations of the parameters.
827
 
827
 
828
; This function could be more sophisticated to provide closer upper bounds for
828
; This function could be more sophisticated to provide closer upper bounds for
829
; every combination of windowBits and memLevel.  But even the conservative
829
; every combination of windowBits and memLevel.  But even the conservative
830
; upper bound of about 14% expansion does not seem onerous for output buffer
830
; upper bound of about 14% expansion does not seem onerous for output buffer
831
; allocation.
831
; allocation.
832
 
832
 
833
;uLong (strm, sourceLen)
833
;uLong (strm, sourceLen)
834
;    z_streamp strm
834
;    z_streamp strm
835
;    uLong sourceLen
835
;    uLong sourceLen
836
align 4
836
align 4
837
proc deflateBound, strm:dword, sourceLen:dword
837
proc deflateBound, strm:dword, sourceLen:dword
838
;    deflate_state *s;
838
;    deflate_state *s;
839
;    uLong complen, wraplen;
839
;    uLong complen, wraplen;
840
;    Bytef *str;
840
;    Bytef *str;
841
	zlib_debug 'deflateBound'
841
	zlib_debug 'deflateBound'
842
 
842
 
843
	; conservative upper bound for compressed data
843
	; conservative upper bound for compressed data
844
;    complen = sourceLen +
844
;    complen = sourceLen +
845
;              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
845
;              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
846
 
846
 
847
	; if can't get parameters, return conservative bound plus zlib wrapper
847
	; if can't get parameters, return conservative bound plus zlib wrapper
848
;    if (strm == Z_NULL || strm->state == Z_NULL)
848
;    if (strm == Z_NULL || strm->state == Z_NULL)
849
;        return complen + 6;
849
;        return complen + 6;
850
 
850
 
851
	; compute wrapper length
851
	; compute wrapper length
852
;    s = strm->state;
852
;    s = strm->state;
853
;    switch (s->wrap) {
853
;    switch (s->wrap) {
854
;    case 0:                                 /* raw deflate */
854
;    case 0:                                 /* raw deflate */
855
;        wraplen = 0;
855
;        wraplen = 0;
856
;        break;
856
;        break;
857
;    case 1:                                 /* zlib wrapper */
857
;    case 1:                                 /* zlib wrapper */
858
;        wraplen = 6 + (s->strstart ? 4 : 0);
858
;        wraplen = 6 + (s->strstart ? 4 : 0);
859
;        break;
859
;        break;
860
;    case 2:                                 /* gzip wrapper */
860
;    case 2:                                 /* gzip wrapper */
861
;        wraplen = 18;
861
;        wraplen = 18;
862
;        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
862
;        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
863
;            if (s->gzhead->extra != Z_NULL)
863
;            if (s->gzhead->extra != Z_NULL)
864
;                wraplen += 2 + s->gzhead->extra_len;
864
;                wraplen += 2 + s->gzhead->extra_len;
865
;            str = s->gzhead->name;
865
;            str = s->gzhead->name;
866
;            if (str != Z_NULL)
866
;            if (str != Z_NULL)
867
;                do {
867
;                do {
868
;                    wraplen++;
868
;                    wraplen++;
869
;                } while (*str++);
869
;                } while (*str++);
870
;            str = s->gzhead->comment;
870
;            str = s->gzhead->comment;
871
;            if (str != Z_NULL)
871
;            if (str != Z_NULL)
872
;                do {
872
;                do {
873
;                    wraplen++;
873
;                    wraplen++;
874
;                } while (*str++);
874
;                } while (*str++);
875
;            if (s->gzhead->hcrc)
875
;            if (s->gzhead->hcrc)
876
;                wraplen += 2;
876
;                wraplen += 2;
877
;        }
877
;        }
878
;        break;
878
;        break;
879
;    default:                                /* for compiler happiness */
879
;    default:                                /* for compiler happiness */
880
;        wraplen = 6;
880
;        wraplen = 6;
881
;    }
881
;    }
882
 
882
 
883
	; if not default parameters, return conservative bound
883
	; if not default parameters, return conservative bound
884
;    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
884
;    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
885
;        return complen + wraplen;
885
;        return complen + wraplen;
886
 
886
 
887
	; default settings: return tight bound for that case
887
	; default settings: return tight bound for that case
888
;    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
888
;    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
889
;           (sourceLen >> 25) + 13 - 6 + wraplen;
889
;           (sourceLen >> 25) + 13 - 6 + wraplen;
890
.end_f:
890
.end_f:
891
	ret
891
	ret
892
endp
892
endp
893
 
893
 
894
; =========================================================================
894
; =========================================================================
895
; Put a short in the pending buffer. The 16-bit value is put in MSB order.
895
; Put a short in the pending buffer. The 16-bit value is put in MSB order.
896
; IN assertion: the stream state is correct and there is enough room in
896
; IN assertion: the stream state is correct and there is enough room in
897
; pending_buf.
897
; pending_buf.
898
 
898
 
899
;void (s, b)
899
;void (s, b)
900
;    deflate_state *s
900
;    deflate_state *s
901
;    uInt b
901
;    uInt b
902
align 4
902
align 4
903
proc putShortMSB uses ebx ecx, s:dword, b:dword
903
proc putShortMSB uses ebx ecx, s:dword, b:dword
904
	mov ebx,[s]
904
	mov ebx,[s]
905
	mov ecx,[b]
905
	mov ecx,[b]
906
	put_byte ebx, ch
906
	put_byte ebx, ch
907
	put_byte ebx, cl
907
	put_byte ebx, cl
908
	ret
908
	ret
909
endp
909
endp
910
 
910
 
911
; =========================================================================
911
; =========================================================================
912
; Flush as much pending output as possible. All deflate() output goes
912
; Flush as much pending output as possible. All deflate() output goes
913
; through this function so some applications may wish to modify it
913
; through this function so some applications may wish to modify it
914
; to avoid allocating a large strm->next_out buffer and copying into it.
914
; to avoid allocating a large strm->next_out buffer and copying into it.
915
; (See also read_buf()).
915
; (See also read_buf()).
916
 
916
 
917
;void (strm)
917
;void (strm)
918
;    z_streamp strm
918
;    z_streamp strm
919
align 4
919
align 4
920
proc flush_pending uses eax ebx ecx edx, strm:dword
920
proc flush_pending uses eax ebx ecx edx, strm:dword
921
;ecx - len
921
;ecx - len
922
;edx - deflate_state *s
922
;edx - deflate_state *s
923
;ebx - strm
923
;ebx - strm
924
	zlib_debug 'flush_pending'
924
	zlib_debug 'flush_pending'
925
	mov ebx,[strm]
925
	mov ebx,[strm]
926
	mov edx,[ebx+z_stream.state]
926
	mov edx,[ebx+z_stream.state]
927
 
927
 
928
	stdcall _tr_flush_bits, edx
928
	stdcall _tr_flush_bits, edx
929
	mov ecx,[edx+deflate_state.pending]
929
	mov ecx,[edx+deflate_state.pending]
930
	mov eax,[ebx+z_stream.avail_out]
930
	mov eax,[ebx+z_stream.avail_out]
931
	cmp ecx,eax
931
	cmp ecx,eax
932
	jle @f ;if (..>..)
932
	jle @f ;if (..>..)
933
		mov ecx,eax
933
		mov ecx,eax
934
	@@:
934
	@@:
935
	cmp ecx,0
935
	cmp ecx,0
936
	je @f
936
	je @f
937
 
937
 
938
	stdcall zmemcpy, [ebx+z_stream.next_out], [edx+deflate_state.pending_out], ecx
938
	stdcall zmemcpy, [ebx+z_stream.next_out], [edx+deflate_state.pending_out], ecx
939
	add [ebx+z_stream.next_out],ecx
939
	add [ebx+z_stream.next_out],ecx
940
	add [edx+deflate_state.pending_out],ecx
940
	add [edx+deflate_state.pending_out],ecx
941
	add [ebx+z_stream.total_out],ecx
941
	add [ebx+z_stream.total_out],ecx
942
	sub [ebx+z_stream.avail_out],ecx
942
	sub [ebx+z_stream.avail_out],ecx
943
	sub [edx+deflate_state.pending],ecx
943
	sub [edx+deflate_state.pending],ecx
944
	cmp dword[edx+deflate_state.pending],0
944
	cmp dword[edx+deflate_state.pending],0
945
	jne @f ;if (..==0)
945
	jne @f ;if (..==0)
946
		mov eax,[edx+deflate_state.pending_buf]
946
		mov eax,[edx+deflate_state.pending_buf]
947
		mov [edx+deflate_state.pending_out],eax
947
		mov [edx+deflate_state.pending_out],eax
948
	@@:
948
	@@:
949
	ret
949
	ret
950
endp
950
endp
951
 
951
 
952
; =========================================================================
952
; =========================================================================
953
;int (strm, flush)
953
;int (strm, flush)
954
;    z_streamp strm
954
;    z_streamp strm
955
;    int flush
955
;    int flush
956
align 4
956
align 4
957
proc deflate uses ebx ecx edx edi esi, strm:dword, flush:dword
957
proc deflate uses ebx ecx edx edi esi, strm:dword, flush:dword
958
locals
958
locals
959
	old_flush dd ? ;int ;value of flush param for previous deflate call
959
	old_flush dd ? ;int ;value of flush param for previous deflate call
960
	val dd ?
960
	val dd ?
961
endl
961
endl
962
	mov ebx,[strm]
962
	mov ebx,[strm]
963
zlib_debug 'deflate strm = %d',ebx
963
zlib_debug 'deflate strm = %d',ebx
964
	cmp ebx,Z_NULL
964
	cmp ebx,Z_NULL
965
	je @f
965
	je @f
966
	mov edi,[ebx+z_stream.state] ;s = strm.state
966
	mov edi,[ebx+z_stream.state] ;s = strm.state
967
	cmp edi,Z_NULL
967
	cmp edi,Z_NULL
968
	je @f
968
	je @f
969
	cmp dword[flush],Z_BLOCK
969
	cmp dword[flush],Z_BLOCK
970
	jg @f
970
	jg @f
971
	cmp dword[flush],0
971
	cmp dword[flush],0
972
	jge .end10 ;if (..==0 || ..==0 || ..>.. || ..<0)
972
	jge .end10 ;if (..==0 || ..==0 || ..>.. || ..<0)
973
	@@:
973
	@@:
974
		mov eax,Z_STREAM_ERROR
974
		mov eax,Z_STREAM_ERROR
975
		jmp .end_f
975
		jmp .end_f
976
	.end10:
976
	.end10:
977
	cmp dword[ebx+z_stream.next_out],Z_NULL
977
	cmp dword[ebx+z_stream.next_out],Z_NULL
978
	je .beg0
978
	je .beg0
979
	cmp dword[ebx+z_stream.next_in],Z_NULL
979
	cmp dword[ebx+z_stream.next_in],Z_NULL
980
	jne @f
980
	jne @f
981
	cmp dword[ebx+z_stream.avail_in],0
981
	cmp dword[ebx+z_stream.avail_in],0
982
	jne .beg0
982
	jne .beg0
983
	@@:
983
	@@:
984
	cmp dword[edi+deflate_state.status],FINISH_STATE
984
	cmp dword[edi+deflate_state.status],FINISH_STATE
985
	jne .end0
985
	jne .end0
986
	cmp dword[flush],Z_FINISH
986
	cmp dword[flush],Z_FINISH
987
	je .end0
987
	je .end0
988
	.beg0: ;if (..==0 || (..==0 && ..!=0) || (..==.. && ..!=..))
988
	.beg0: ;if (..==0 || (..==0 && ..!=0) || (..==.. && ..!=..))
989
		ERR_RETURN ebx, Z_STREAM_ERROR
989
		ERR_RETURN ebx, Z_STREAM_ERROR
990
		jmp .end_f
990
		jmp .end_f
991
	.end0:
991
	.end0:
992
	cmp dword[ebx+z_stream.avail_out],0
992
	cmp dword[ebx+z_stream.avail_out],0
993
	jne @f ;if (..==0)
993
	jne @f ;if (..==0)
994
		ERR_RETURN ebx, Z_BUF_ERROR
994
		ERR_RETURN ebx, Z_BUF_ERROR
995
		jmp .end_f
995
		jmp .end_f
996
	@@:
996
	@@:
997
 
997
 
998
	mov dword[edi+deflate_state.strm],ebx ;just in case
998
	mov dword[edi+deflate_state.strm],ebx ;just in case
999
	mov eax,[edi+deflate_state.last_flush]
999
	mov eax,[edi+deflate_state.last_flush]
1000
	mov [old_flush],eax
1000
	mov [old_flush],eax
1001
	mov eax,[flush]
1001
	mov eax,[flush]
1002
	mov [edi+deflate_state.last_flush],eax
1002
	mov [edi+deflate_state.last_flush],eax
1003
 
1003
 
1004
	; Write the header
1004
	; Write the header
1005
	cmp dword[edi+deflate_state.status],INIT_STATE
1005
	cmp dword[edi+deflate_state.status],INIT_STATE
1006
	jne .end2 ;if (..==..)
1006
	jne .end2 ;if (..==..)
1007
if GZIP eq 1
1007
if GZIP eq 1
1008
		cmp dword[edi+deflate_state.wrap],2
1008
		cmp dword[edi+deflate_state.wrap],2
1009
		jne .end1 ;if (..==..)
1009
		jne .end1 ;if (..==..)
1010
			xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1010
			xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1011
			mov [ebx+z_stream.adler],eax
1011
			mov [ebx+z_stream.adler],eax
1012
			put_byte edi, 31
1012
			put_byte edi, 31
1013
			put_byte edi, 139
1013
			put_byte edi, 139
1014
			put_byte edi, 8
1014
			put_byte edi, 8
1015
			cmp dword[edi+deflate_state.gzhead],Z_NULL
1015
			cmp dword[edi+deflate_state.gzhead],Z_NULL
1016
			jne .end3 ;if (..==0)
1016
			jne .end3 ;if (..==0)
1017
				put_byte edi, 0
1017
				put_byte edi, 0
1018
				put_dword edi, 0
1018
				put_dword edi, 0
1019
				xor cl,cl
1019
				xor cl,cl
1020
				cmp word[edi+deflate_state.level],2
1020
				cmp word[edi+deflate_state.level],2
1021
				jge @f
1021
				jge @f
1022
					mov cl,4
1022
					mov cl,4
1023
				@@:
1023
				@@:
1024
				cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1024
				cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1025
				jl @f
1025
				jl @f
1026
					mov cl,4
1026
					mov cl,4
1027
				@@:
1027
				@@:
1028
				cmp word[edi+deflate_state.level],9
1028
				cmp word[edi+deflate_state.level],9
1029
				jne @f
1029
				jne @f
1030
					mov cl,2
1030
					mov cl,2
1031
				@@: ;..==.. ? 2 : (..>=.. || ..<.. ? 4 : 0)
1031
				@@: ;..==.. ? 2 : (..>=.. || ..<.. ? 4 : 0)
1032
				put_byte edi, cl
1032
				put_byte edi, cl
1033
				put_byte edi, OS_CODE
1033
				put_byte edi, OS_CODE
1034
				mov dword[edi+deflate_state.status],BUSY_STATE
1034
				mov dword[edi+deflate_state.status],BUSY_STATE
1035
				jmp .end2
1035
				jmp .end2
1036
			.end3: ;else
1036
			.end3: ;else
1037
				mov edx,[edi+deflate_state.gzhead]
1037
				mov edx,[edi+deflate_state.gzhead]
1038
				xor cl,cl
1038
				xor cl,cl
1039
				cmp [edx+gz_header.text],0
1039
				cmp [edx+gz_header.text],0
1040
				je @f
1040
				je @f
1041
					inc cl
1041
					inc cl
1042
				@@:
1042
				@@:
1043
				cmp [edx+gz_header.hcrc],0
1043
				cmp [edx+gz_header.hcrc],0
1044
				je @f
1044
				je @f
1045
					add cl,2
1045
					add cl,2
1046
				@@:
1046
				@@:
1047
				cmp [edx+gz_header.extra],Z_NULL
1047
				cmp [edx+gz_header.extra],Z_NULL
1048
				je @f
1048
				je @f
1049
					add cl,4
1049
					add cl,4
1050
				@@:
1050
				@@:
1051
				cmp [edx+gz_header.name],Z_NULL
1051
				cmp [edx+gz_header.name],Z_NULL
1052
				je @f
1052
				je @f
1053
					add cl,8
1053
					add cl,8
1054
				@@:
1054
				@@:
1055
				cmp [edx+gz_header.comment],Z_NULL
1055
				cmp [edx+gz_header.comment],Z_NULL
1056
				je @f
1056
				je @f
1057
					add cl,16
1057
					add cl,16
1058
				@@:
1058
				@@:
1059
				put_byte edi, cl
1059
				put_byte edi, cl
1060
				mov ecx,[edx+gz_header.time]
1060
				mov ecx,[edx+gz_header.time]
1061
				put_dword edi, ecx
1061
				put_dword edi, ecx
1062
				xor cl,cl
1062
				xor cl,cl
1063
				cmp word[edi+deflate_state.level],2
1063
				cmp word[edi+deflate_state.level],2
1064
				jge @f
1064
				jge @f
1065
					mov cl,4
1065
					mov cl,4
1066
				@@:
1066
				@@:
1067
				cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1067
				cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1068
				jl @f
1068
				jl @f
1069
					mov cl,4
1069
					mov cl,4
1070
				@@:
1070
				@@:
1071
				cmp word[edi+deflate_state.level],9
1071
				cmp word[edi+deflate_state.level],9
1072
				jne @f
1072
				jne @f
1073
					mov cl,2
1073
					mov cl,2
1074
				@@: ;..==.. ? 2 : (..>=.. || ..<.. ? 4 : 0)
1074
				@@: ;..==.. ? 2 : (..>=.. || ..<.. ? 4 : 0)
1075
				put_byte edi, cl
1075
				put_byte edi, cl
1076
				mov ecx,[edx+gz_header.os]
1076
				mov ecx,[edx+gz_header.os]
1077
				put_byte edi, cl
1077
				put_byte edi, cl
1078
				cmp dword[edx+gz_header.extra],Z_NULL
1078
				cmp dword[edx+gz_header.extra],Z_NULL
1079
				je @f ;if (..!=0)
1079
				je @f ;if (..!=0)
1080
					mov ecx,[edx+gz_header.extra_len]
1080
					mov ecx,[edx+gz_header.extra_len]
1081
					put_byte edi, cl
1081
					put_byte edi, cl
1082
					put_byte edi, ch
1082
					put_byte edi, ch
1083
				@@:
1083
				@@:
1084
				cmp dword[edx+gz_header.hcrc],0
1084
				cmp dword[edx+gz_header.hcrc],0
1085
				je @f ;if (..)
1085
				je @f ;if (..)
1086
					stdcall calc_crc32, [ebx+z_stream.adler],\
1086
					stdcall calc_crc32, [ebx+z_stream.adler],\
1087
						[edi+deflate_state.pending_buf], [edi+deflate_state.pending]
1087
						[edi+deflate_state.pending_buf], [edi+deflate_state.pending]
1088
					mov [ebx+z_stream.adler],eax
1088
					mov [ebx+z_stream.adler],eax
1089
				@@:
1089
				@@:
1090
				mov dword[edi+deflate_state.gzindex],0
1090
				mov dword[edi+deflate_state.gzindex],0
1091
				mov dword[edi+deflate_state.status],EXTRA_STATE
1091
				mov dword[edi+deflate_state.status],EXTRA_STATE
1092
			jmp .end2
1092
			jmp .end2
1093
		.end1: ;else
1093
		.end1: ;else
1094
end if
1094
end if
1095
			mov edx,[edi+deflate_state.w_bits]
1095
			mov edx,[edi+deflate_state.w_bits]
1096
			sub edx,8
1096
			sub edx,8
1097
			shl edx,4
1097
			shl edx,4
1098
			add edx,Z_DEFLATED
1098
			add edx,Z_DEFLATED
1099
			shl edx,8 ;edx = header
1099
			shl edx,8 ;edx = header
1100
			;esi = level_flags
1100
			;esi = level_flags
1101
 
1101
 
1102
			mov esi,3
1102
			mov esi,3
1103
			cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1103
			cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1104
			jge @f
1104
			jge @f
1105
			cmp word[edi+deflate_state.level],2
1105
			cmp word[edi+deflate_state.level],2
1106
			jge .end30 ;if (..>=.. || ..<..)
1106
			jge .end30 ;if (..>=.. || ..<..)
1107
			@@:
1107
			@@:
1108
				xor esi,esi
1108
				xor esi,esi
1109
				jmp .end4
1109
				jmp .end4
1110
			.end30:
1110
			.end30:
1111
			cmp word[edi+deflate_state.level],6
1111
			cmp word[edi+deflate_state.level],6
1112
			jge @f ;else if (..<..)
1112
			jge @f ;else if (..<..)
1113
				mov esi,1
1113
				mov esi,1
1114
				jmp .end4
1114
				jmp .end4
1115
			@@:
1115
			@@:
1116
			;;cmp word[edi+deflate_state.level],6
1116
			;;cmp word[edi+deflate_state.level],6
1117
			jne .end4 ;else if (..==..)
1117
			jne .end4 ;else if (..==..)
1118
				mov esi,2
1118
				mov esi,2
1119
			.end4:
1119
			.end4:
1120
			shl esi,6
1120
			shl esi,6
1121
			or edx,esi
1121
			or edx,esi
1122
			cmp dword[edi+deflate_state.strstart],0
1122
			cmp dword[edi+deflate_state.strstart],0
1123
			je @f ;if (..!=0)
1123
			je @f ;if (..!=0)
1124
				or edx,PRESET_DICT
1124
				or edx,PRESET_DICT
1125
			@@:
1125
			@@:
1126
			mov esi,edx
1126
			mov esi,edx
1127
			mov eax,edx
1127
			mov eax,edx
1128
			xor edx,edx
1128
			xor edx,edx
1129
			mov ecx,31
1129
			mov ecx,31
1130
			div ecx
1130
			div ecx
1131
			add esi,31
1131
			add esi,31
1132
			sub esi,edx ;esi = header
1132
			sub esi,edx ;esi = header
1133
 
1133
 
1134
			mov dword[edi+deflate_state.status],BUSY_STATE
1134
			mov dword[edi+deflate_state.status],BUSY_STATE
1135
			stdcall putShortMSB, edi, esi
1135
			stdcall putShortMSB, edi, esi
1136
 
1136
 
1137
			; Save the adler32 of the preset dictionary:
1137
			; Save the adler32 of the preset dictionary:
1138
			cmp dword[edi+deflate_state.strstart],0
1138
			cmp dword[edi+deflate_state.strstart],0
1139
			je @f ;if (..!=0)
1139
			je @f ;if (..!=0)
1140
				mov ecx,[ebx+z_stream.adler]
1140
				mov ecx,[ebx+z_stream.adler]
1141
				bswap ecx
1141
				bswap ecx
1142
				put_dword edi, ecx
1142
				put_dword edi, ecx
1143
			@@:
1143
			@@:
1144
			xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1144
			xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1145
			mov [ebx+z_stream.adler],eax
1145
			mov [ebx+z_stream.adler],eax
1146
	.end2:
1146
	.end2:
1147
if GZIP eq 1
1147
if GZIP eq 1
1148
	mov edx,[edi+deflate_state.gzhead]
1148
	mov edx,[edi+deflate_state.gzhead]
1149
	cmp dword[edi+deflate_state.status],EXTRA_STATE
1149
	cmp dword[edi+deflate_state.status],EXTRA_STATE
1150
	jne .end5 ;if (..==..)
1150
	jne .end5 ;if (..==..)
1151
		cmp dword[edx+gz_header.extra],Z_NULL
1151
		cmp dword[edx+gz_header.extra],Z_NULL
1152
		je .end21 ;if (..!=..)
1152
		je .end21 ;if (..!=..)
1153
			mov esi,[edi+deflate_state.pending]
1153
			mov esi,[edi+deflate_state.pending]
1154
			;esi = beg ;start of bytes to update crc
1154
			;esi = beg ;start of bytes to update crc
1155
 
1155
 
1156
			movzx ecx,word[edx+gz_header.extra_len]
1156
			movzx ecx,word[edx+gz_header.extra_len]
1157
			.cycle0: ;while (..<..)
1157
			.cycle0: ;while (..<..)
1158
			cmp dword[edi+deflate_state.gzindex],ecx
1158
			cmp dword[edi+deflate_state.gzindex],ecx
1159
			jge .cycle0end
1159
			jge .cycle0end
1160
				mov eax,[edi+deflate_state.pending]
1160
				mov eax,[edi+deflate_state.pending]
1161
				cmp eax,[edi+deflate_state.pending_buf_size]
1161
				cmp eax,[edi+deflate_state.pending_buf_size]
1162
				jne .end24 ;if (..==..)
1162
				jne .end24 ;if (..==..)
1163
					mov dword[edx+gz_header.hcrc],0
1163
					mov dword[edx+gz_header.hcrc],0
1164
					je @f
1164
					je @f
1165
					cmp [edi+deflate_state.pending],esi
1165
					cmp [edi+deflate_state.pending],esi
1166
					jle @f ;if (.. && ..>..)
1166
					jle @f ;if (.. && ..>..)
1167
						mov ecx,[edi+deflate_state.pending]
1167
						mov ecx,[edi+deflate_state.pending]
1168
						sub ecx,esi
1168
						sub ecx,esi
1169
						mov eax,[edi+deflate_state.pending_buf]
1169
						mov eax,[edi+deflate_state.pending_buf]
1170
						add eax,esi
1170
						add eax,esi
1171
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1171
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1172
						mov [ebx+z_stream.adler],eax
1172
						mov [ebx+z_stream.adler],eax
1173
					@@:
1173
					@@:
1174
					stdcall flush_pending, ebx
1174
					stdcall flush_pending, ebx
1175
					mov esi,[edi+deflate_state.pending]
1175
					mov esi,[edi+deflate_state.pending]
1176
					cmp esi,[edi+deflate_state.pending_buf_size]
1176
					cmp esi,[edi+deflate_state.pending_buf_size]
1177
					je .cycle0end ;if (..==..) break
1177
					je .cycle0end ;if (..==..) break
1178
				.end24:
1178
				.end24:
1179
				push ebx
1179
				push ebx
1180
					mov ebx,[edi+deflate_state.gzindex]
1180
					mov ebx,[edi+deflate_state.gzindex]
1181
					add ebx,[edx+gz_header.extra]
1181
					add ebx,[edx+gz_header.extra]
1182
					mov bl,[ebx]
1182
					mov bl,[ebx]
1183
					put_byte edi, bl
1183
					put_byte edi, bl
1184
				pop ebx
1184
				pop ebx
1185
				inc dword[edi+deflate_state.gzindex]
1185
				inc dword[edi+deflate_state.gzindex]
1186
				jmp .cycle0
1186
				jmp .cycle0
1187
			.cycle0end:
1187
			.cycle0end:
1188
			mov dword[edx+gz_header.hcrc],0
1188
			mov dword[edx+gz_header.hcrc],0
1189
			je @f
1189
			je @f
1190
			cmp [edi+deflate_state.pending],esi
1190
			cmp [edi+deflate_state.pending],esi
1191
			jle @f ;if (.. && ..>..)
1191
			jle @f ;if (.. && ..>..)
1192
				mov ecx,[edi+deflate_state.pending]
1192
				mov ecx,[edi+deflate_state.pending]
1193
				sub ecx,esi
1193
				sub ecx,esi
1194
				mov eax,[edi+deflate_state.pending_buf]
1194
				mov eax,[edi+deflate_state.pending_buf]
1195
				add eax,esi
1195
				add eax,esi
1196
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1196
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1197
				mov [ebx+z_stream.adler],eax
1197
				mov [ebx+z_stream.adler],eax
1198
			@@:
1198
			@@:
1199
			mov eax,[edx+gz_header.extra_len]
1199
			mov eax,[edx+gz_header.extra_len]
1200
			cmp dword[edi+deflate_state.gzindex],eax
1200
			cmp dword[edi+deflate_state.gzindex],eax
1201
			jne .end5 ;if (..==..)
1201
			jne .end5 ;if (..==..)
1202
				mov dword[edi+deflate_state.gzindex],0
1202
				mov dword[edi+deflate_state.gzindex],0
1203
				mov dword[edi+deflate_state.status],NAME_STATE
1203
				mov dword[edi+deflate_state.status],NAME_STATE
1204
			jmp .end5
1204
			jmp .end5
1205
		.end21: ;else
1205
		.end21: ;else
1206
			mov dword[edi+deflate_state.status],NAME_STATE
1206
			mov dword[edi+deflate_state.status],NAME_STATE
1207
	.end5:
1207
	.end5:
1208
	cmp dword[edi+deflate_state.status],NAME_STATE
1208
	cmp dword[edi+deflate_state.status],NAME_STATE
1209
	jne .end6 ;if (..==..)
1209
	jne .end6 ;if (..==..)
1210
		cmp dword[edx+gz_header.name],Z_NULL
1210
		cmp dword[edx+gz_header.name],Z_NULL
1211
		je .end22 ;if (..!=..)
1211
		je .end22 ;if (..!=..)
1212
			mov esi,[edi+deflate_state.pending]
1212
			mov esi,[edi+deflate_state.pending]
1213
			;esi = beg ;start of bytes to update crc
1213
			;esi = beg ;start of bytes to update crc
1214
 
1214
 
1215
			.cycle1: ;do
1215
			.cycle1: ;do
1216
				mov eax,[edi+deflate_state.pending]
1216
				mov eax,[edi+deflate_state.pending]
1217
				cmp eax,[edi+deflate_state.pending_buf_size]
1217
				cmp eax,[edi+deflate_state.pending_buf_size]
1218
				jne .end25 ;if (..==..)
1218
				jne .end25 ;if (..==..)
1219
					mov dword[edx+gz_header.hcrc],0
1219
					mov dword[edx+gz_header.hcrc],0
1220
					je @f
1220
					je @f
1221
					cmp [edi+deflate_state.pending],esi
1221
					cmp [edi+deflate_state.pending],esi
1222
					jle @f ;if (.. && ..>..)
1222
					jle @f ;if (.. && ..>..)
1223
						mov ecx,[edi+deflate_state.pending]
1223
						mov ecx,[edi+deflate_state.pending]
1224
						sub ecx,esi
1224
						sub ecx,esi
1225
						mov eax,[edi+deflate_state.pending_buf]
1225
						mov eax,[edi+deflate_state.pending_buf]
1226
						add eax,esi
1226
						add eax,esi
1227
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1227
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1228
						mov [ebx+z_stream.adler],eax
1228
						mov [ebx+z_stream.adler],eax
1229
					@@:
1229
					@@:
1230
					stdcall flush_pending, ebx
1230
					stdcall flush_pending, ebx
1231
					mov esi,[edi+deflate_state.pending]
1231
					mov esi,[edi+deflate_state.pending]
1232
					cmp esi,[edi+deflate_state.pending_buf_size]
1232
					cmp esi,[edi+deflate_state.pending_buf_size]
1233
					jne .end25 ;if (..==..)
1233
					jne .end25 ;if (..==..)
1234
						mov dword[val],1
1234
						mov dword[val],1
1235
						jmp .cycle1end
1235
						jmp .cycle1end
1236
				.end25:
1236
				.end25:
1237
				push ebx
1237
				push ebx
1238
					mov ebx,[edi+deflate_state.gzindex]
1238
					mov ebx,[edi+deflate_state.gzindex]
1239
					add ebx,[edx+gz_header.name]
1239
					add ebx,[edx+gz_header.name]
1240
					movzx ebx,byte[ebx]
1240
					movzx ebx,byte[ebx]
1241
					mov [val],ebx
1241
					mov [val],ebx
1242
					inc dword[edi+deflate_state.gzindex]
1242
					inc dword[edi+deflate_state.gzindex]
1243
					put_byte edi, bl
1243
					put_byte edi, bl
1244
				pop ebx
1244
				pop ebx
1245
				cmp dword[val],0
1245
				cmp dword[val],0
1246
				jne .cycle1 ;while (val != 0)
1246
				jne .cycle1 ;while (val != 0)
1247
			.cycle1end:
1247
			.cycle1end:
1248
			mov dword[edx+gz_header.hcrc],0
1248
			mov dword[edx+gz_header.hcrc],0
1249
			je @f
1249
			je @f
1250
			cmp [edi+deflate_state.pending],esi
1250
			cmp [edi+deflate_state.pending],esi
1251
			jle @f ;if (.. && ..>..)
1251
			jle @f ;if (.. && ..>..)
1252
				mov ecx,[edi+deflate_state.pending]
1252
				mov ecx,[edi+deflate_state.pending]
1253
				sub ecx,esi
1253
				sub ecx,esi
1254
				mov eax,[edi+deflate_state.pending_buf]
1254
				mov eax,[edi+deflate_state.pending_buf]
1255
				add eax,esi
1255
				add eax,esi
1256
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1256
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1257
				mov [ebx+z_stream.adler],eax
1257
				mov [ebx+z_stream.adler],eax
1258
			@@:
1258
			@@:
1259
			cmp dword[val],0
1259
			cmp dword[val],0
1260
			jne .end6 ;if (val == 0)
1260
			jne .end6 ;if (val == 0)
1261
				mov dword[edi+deflate_state.gzindex],0
1261
				mov dword[edi+deflate_state.gzindex],0
1262
				mov dword[edi+deflate_state.status],COMMENT_STATE
1262
				mov dword[edi+deflate_state.status],COMMENT_STATE
1263
			jmp .end6
1263
			jmp .end6
1264
		.end22: ;else
1264
		.end22: ;else
1265
			mov dword[edi+deflate_state.status],COMMENT_STATE;
1265
			mov dword[edi+deflate_state.status],COMMENT_STATE;
1266
	.end6:
1266
	.end6:
1267
	cmp dword[edi+deflate_state.status],COMMENT_STATE
1267
	cmp dword[edi+deflate_state.status],COMMENT_STATE
1268
	jne .end7 ;if (..==..)
1268
	jne .end7 ;if (..==..)
1269
		cmp dword[edx+gz_header.comment],Z_NULL
1269
		cmp dword[edx+gz_header.comment],Z_NULL
1270
		je .end23 ;if (..!=..)
1270
		je .end23 ;if (..!=..)
1271
			mov esi,[edi+deflate_state.pending]
1271
			mov esi,[edi+deflate_state.pending]
1272
			;esi = beg ;start of bytes to update crc
1272
			;esi = beg ;start of bytes to update crc
1273
 
1273
 
1274
			.cycle2: ;do
1274
			.cycle2: ;do
1275
				mov eax,[edi+deflate_state.pending]
1275
				mov eax,[edi+deflate_state.pending]
1276
				cmp eax,[edi+deflate_state.pending_buf_size]
1276
				cmp eax,[edi+deflate_state.pending_buf_size]
1277
				jne .end26 ;if (..==..)
1277
				jne .end26 ;if (..==..)
1278
					mov dword[edx+gz_header.hcrc],0
1278
					mov dword[edx+gz_header.hcrc],0
1279
					je @f
1279
					je @f
1280
					cmp [edi+deflate_state.pending],esi
1280
					cmp [edi+deflate_state.pending],esi
1281
					jle @f ;if (.. && ..>..)
1281
					jle @f ;if (.. && ..>..)
1282
						mov ecx,[edi+deflate_state.pending]
1282
						mov ecx,[edi+deflate_state.pending]
1283
						sub ecx,esi
1283
						sub ecx,esi
1284
						mov eax,[edi+deflate_state.pending_buf]
1284
						mov eax,[edi+deflate_state.pending_buf]
1285
						add eax,esi
1285
						add eax,esi
1286
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1286
						stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1287
						mov [ebx+z_stream.adler],eax
1287
						mov [ebx+z_stream.adler],eax
1288
					@@:
1288
					@@:
1289
					stdcall flush_pending, ebx
1289
					stdcall flush_pending, ebx
1290
					mov esi,[edi+deflate_state.pending]
1290
					mov esi,[edi+deflate_state.pending]
1291
					cmp esi,[edi+deflate_state.pending_buf_size]
1291
					cmp esi,[edi+deflate_state.pending_buf_size]
1292
					jne .end26 ;if (..==..)
1292
					jne .end26 ;if (..==..)
1293
						mov dword[val],1
1293
						mov dword[val],1
1294
						jmp .cycle2end
1294
						jmp .cycle2end
1295
				.end26:
1295
				.end26:
1296
				push ebx
1296
				push ebx
1297
					mov ebx,[edi+deflate_state.gzindex]
1297
					mov ebx,[edi+deflate_state.gzindex]
1298
					add ebx,[edx+gz_header.comment]
1298
					add ebx,[edx+gz_header.comment]
1299
					movzx ebx,byte[ebx]
1299
					movzx ebx,byte[ebx]
1300
					mov [val],ebx
1300
					mov [val],ebx
1301
					inc dword[edi+deflate_state.gzindex]
1301
					inc dword[edi+deflate_state.gzindex]
1302
					put_byte edi, bl
1302
					put_byte edi, bl
1303
				pop ebx
1303
				pop ebx
1304
				cmp dword[val],0
1304
				cmp dword[val],0
1305
				jne .cycle2 ;while (val != 0)
1305
				jne .cycle2 ;while (val != 0)
1306
			.cycle2end:
1306
			.cycle2end:
1307
			mov dword[edx+gz_header.hcrc],0
1307
			mov dword[edx+gz_header.hcrc],0
1308
			je @f
1308
			je @f
1309
			cmp [edi+deflate_state.pending],esi
1309
			cmp [edi+deflate_state.pending],esi
1310
			jle @f ;if (.. && ..>..)
1310
			jle @f ;if (.. && ..>..)
1311
				mov ecx,[edi+deflate_state.pending]
1311
				mov ecx,[edi+deflate_state.pending]
1312
				sub ecx,esi
1312
				sub ecx,esi
1313
				mov eax,[edi+deflate_state.pending_buf]
1313
				mov eax,[edi+deflate_state.pending_buf]
1314
				add eax,esi
1314
				add eax,esi
1315
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1315
				stdcall calc_crc32, [ebx+z_stream.adler], eax, ecx
1316
				mov [ebx+z_stream.adler],eax
1316
				mov [ebx+z_stream.adler],eax
1317
			@@:
1317
			@@:
1318
			cmp dword[val],0
1318
			cmp dword[val],0
1319
			jne .end7 ;if (val == 0)
1319
			jne .end7 ;if (val == 0)
1320
				mov dword[edi+deflate_state.status],HCRC_STATE
1320
				mov dword[edi+deflate_state.status],HCRC_STATE
1321
			jmp .end7
1321
			jmp .end7
1322
		.end23: ;else
1322
		.end23: ;else
1323
			mov dword[edi+deflate_state.status],HCRC_STATE
1323
			mov dword[edi+deflate_state.status],HCRC_STATE
1324
	.end7:
1324
	.end7:
1325
	cmp dword[edi+deflate_state.status],HCRC_STATE
1325
	cmp dword[edi+deflate_state.status],HCRC_STATE
1326
	jne .end8 ;if (..==..)
1326
	jne .end8 ;if (..==..)
1327
		cmp dword[edx+gz_header.hcrc],0
1327
		cmp dword[edx+gz_header.hcrc],0
1328
		je .end9 ;if (..)
1328
		je .end9 ;if (..)
1329
			mov ecx,[edi+deflate_state.pending]
1329
			mov ecx,[edi+deflate_state.pending]
1330
			add ecx,2
1330
			add ecx,2
1331
			cmp ecx,[edi+deflate_state.pending_buf_size]
1331
			cmp ecx,[edi+deflate_state.pending_buf_size]
1332
			jle @f ;if (..>..)
1332
			jle @f ;if (..>..)
1333
				stdcall flush_pending, ebx
1333
				stdcall flush_pending, ebx
1334
			@@:
1334
			@@:
1335
			mov ecx,[edi+deflate_state.pending]
1335
			mov ecx,[edi+deflate_state.pending]
1336
			add ecx,2
1336
			add ecx,2
1337
			cmp ecx,[edi+deflate_state.pending_buf_size]
1337
			cmp ecx,[edi+deflate_state.pending_buf_size]
1338
			jg @f ;if (..<=..)
1338
			jg @f ;if (..<=..)
1339
				mov ecx,[ebx+z_stream.adler]
1339
				mov ecx,[ebx+z_stream.adler]
1340
				put_byte edi, cl
1340
				put_byte edi, cl
1341
				put_byte edi, ch
1341
				put_byte edi, ch
1342
				xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1342
				xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
1343
				mov [ebx+z_stream.adler],eax
1343
				mov [ebx+z_stream.adler],eax
1344
				mov dword[edi+deflate_state.status],BUSY_STATE
1344
				mov dword[edi+deflate_state.status],BUSY_STATE
1345
			@@:
1345
			@@:
1346
			jmp .end8
1346
			jmp .end8
1347
		.end9: ;else
1347
		.end9: ;else
1348
			mov dword[edi+deflate_state.status],BUSY_STATE
1348
			mov dword[edi+deflate_state.status],BUSY_STATE
1349
	.end8:
1349
	.end8:
1350
end if
1350
end if
1351
 
1351
 
1352
	; Flush as much pending output as possible
1352
	; Flush as much pending output as possible
1353
	cmp dword[edi+deflate_state.pending],0
1353
	cmp dword[edi+deflate_state.pending],0
1354
	je .end13 ;if (..!=0)
1354
	je .end13 ;if (..!=0)
1355
		stdcall flush_pending, ebx
1355
		stdcall flush_pending, ebx
1356
		cmp dword[ebx+z_stream.avail_out],0
1356
		cmp dword[ebx+z_stream.avail_out],0
1357
		jne @f ;if (..==0)
1357
		jne @f ;if (..==0)
1358
			; Since avail_out is 0, deflate will be called again with
1358
			; Since avail_out is 0, deflate will be called again with
1359
			; more output space, but possibly with both pending and
1359
			; more output space, but possibly with both pending and
1360
			; avail_in equal to zero. There won't be anything to do,
1360
			; avail_in equal to zero. There won't be anything to do,
1361
			; but this is not an error situation so make sure we
1361
			; but this is not an error situation so make sure we
1362
			; return OK instead of BUF_ERROR at next call of deflate:
1362
			; return OK instead of BUF_ERROR at next call of deflate:
1363
 
1363
 
1364
			mov dword[edi+deflate_state.last_flush],-1
1364
			mov dword[edi+deflate_state.last_flush],-1
1365
			mov eax,Z_OK
1365
			mov eax,Z_OK
1366
			jmp .end_f
1366
			jmp .end_f
1367
		@@:
1367
		@@:
1368
		; Make sure there is something to do and avoid duplicate consecutive
1368
		; Make sure there is something to do and avoid duplicate consecutive
1369
		; flushes. For repeated and useless calls with Z_FINISH, we keep
1369
		; flushes. For repeated and useless calls with Z_FINISH, we keep
1370
		; returning Z_STREAM_END instead of Z_BUF_ERROR.
1370
		; returning Z_STREAM_END instead of Z_BUF_ERROR.
1371
		jmp @f
1371
		jmp @f
1372
	.end13:
1372
	.end13:
1373
	cmp dword[ebx+z_stream.avail_in],0
1373
	cmp dword[ebx+z_stream.avail_in],0
1374
	jne @f
1374
	jne @f
1375
	RANK dword[old_flush],esi
1375
	RANK dword[old_flush],esi
1376
	RANK dword[flush],eax
1376
	RANK dword[flush],eax
1377
	cmp eax,esi
1377
	cmp eax,esi
1378
	jg @f
1378
	jg @f
1379
	cmp dword[flush],Z_FINISH
1379
	cmp dword[flush],Z_FINISH
1380
	je @f ;else if (..==0 && ..<=.. && ..!=..)
1380
	je @f ;else if (..==0 && ..<=.. && ..!=..)
1381
		ERR_RETURN ebx, Z_BUF_ERROR
1381
		ERR_RETURN ebx, Z_BUF_ERROR
1382
		jmp .end_f
1382
		jmp .end_f
1383
	@@:
1383
	@@:
1384
 
1384
 
1385
	; User must not provide more input after the first FINISH:
1385
	; User must not provide more input after the first FINISH:
1386
	cmp dword[edi+deflate_state.status],FINISH_STATE
1386
	cmp dword[edi+deflate_state.status],FINISH_STATE
1387
	jne @f
1387
	jne @f
1388
	cmp dword[ebx+z_stream.avail_in],0
1388
	cmp dword[ebx+z_stream.avail_in],0
1389
	je @f ;if (..==.. && ..!=0)
1389
	je @f ;if (..==.. && ..!=0)
1390
		ERR_RETURN ebx, Z_BUF_ERROR
1390
		ERR_RETURN ebx, Z_BUF_ERROR
1391
		jmp .end_f
1391
		jmp .end_f
1392
	@@:
1392
	@@:
1393
 
1393
 
1394
	; Start a new block or continue the current one.
1394
	; Start a new block or continue the current one.
1395
 
1395
 
1396
	cmp dword[ebx+z_stream.avail_in],0
1396
	cmp dword[ebx+z_stream.avail_in],0
1397
	jne @f
1397
	jne @f
1398
	cmp dword[edi+deflate_state.lookahead],0
1398
	cmp dword[edi+deflate_state.lookahead],0
1399
	jne @f
1399
	jne @f
1400
	cmp dword[flush],Z_NO_FLUSH
1400
	cmp dword[flush],Z_NO_FLUSH
1401
	je .end11
1401
	je .end11
1402
	cmp dword[edi+deflate_state.status],FINISH_STATE
1402
	cmp dword[edi+deflate_state.status],FINISH_STATE
1403
	je .end11
1403
	je .end11
1404
	@@: ;if (..!=0 || ..!=0 || (..!=.. && ..!=..))
1404
	@@: ;if (..!=0 || ..!=0 || (..!=.. && ..!=..))
1405
		;edx = bstate
1405
		;edx = bstate
1406
		cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1406
		cmp word[edi+deflate_state.strategy],Z_HUFFMAN_ONLY
1407
		jne @f
1407
		jne @f
1408
			stdcall deflate_huff, edi, [flush]
1408
			stdcall deflate_huff, edi, [flush]
1409
			jmp .end20
1409
			jmp .end20
1410
		@@:
1410
		@@:
1411
		cmp word[edi+deflate_state.strategy],Z_RLE
1411
		cmp word[edi+deflate_state.strategy],Z_RLE
1412
		jne @f
1412
		jne @f
1413
			stdcall deflate_rle, edi, [flush]
1413
			stdcall deflate_rle, edi, [flush]
1414
			jmp .end20
1414
			jmp .end20
1415
		@@:
1415
		@@:
1416
		movzx eax,word[edi+deflate_state.level]
1416
		movzx eax,word[edi+deflate_state.level]
1417
		imul eax,sizeof.config_s
1417
		imul eax,sizeof.config_s
1418
		add eax,configuration_table+config_s.co_func
1418
		add eax,configuration_table+config_s.co_func
1419
		stdcall dword[eax], edi, [flush]
1419
		stdcall dword[eax], edi, [flush]
1420
		.end20:
1420
		.end20:
1421
		mov edx,eax
1421
		mov edx,eax
1422
 
1422
 
1423
		cmp edx,finish_started
1423
		cmp edx,finish_started
1424
		je @f
1424
		je @f
1425
		cmp edx,finish_done
1425
		cmp edx,finish_done
1426
		jne .end18
1426
		jne .end18
1427
		@@: ;if (..==.. || ..==..)
1427
		@@: ;if (..==.. || ..==..)
1428
			mov dword[edi+deflate_state.status],FINISH_STATE
1428
			mov dword[edi+deflate_state.status],FINISH_STATE
1429
		.end18:
1429
		.end18:
1430
		cmp edx,need_more
1430
		cmp edx,need_more
1431
		je @f
1431
		je @f
1432
		cmp edx,finish_started
1432
		cmp edx,finish_started
1433
		jne .end19
1433
		jne .end19
1434
		@@: ;if (..==.. || ..==..)
1434
		@@: ;if (..==.. || ..==..)
1435
			cmp dword[ebx+z_stream.avail_out],0
1435
			cmp dword[ebx+z_stream.avail_out],0
1436
			jne @f ;if (..==0)
1436
			jne @f ;if (..==0)
1437
				mov dword[edi+deflate_state.last_flush],-1 ;avoid BUF_ERROR next call, see above
1437
				mov dword[edi+deflate_state.last_flush],-1 ;avoid BUF_ERROR next call, see above
1438
			@@:
1438
			@@:
1439
			mov eax,Z_OK
1439
			mov eax,Z_OK
1440
			jmp .end_f
1440
			jmp .end_f
1441
			; If flush != Z_NO_FLUSH && avail_out == 0, the next call
1441
			; If flush != Z_NO_FLUSH && avail_out == 0, the next call
1442
			; of deflate should use the same flush parameter to make sure
1442
			; of deflate should use the same flush parameter to make sure
1443
			; that the flush is complete. So we don't have to output an
1443
			; that the flush is complete. So we don't have to output an
1444
			; empty block here, this will be done at next call. This also
1444
			; empty block here, this will be done at next call. This also
1445
			; ensures that for a very small output buffer, we emit at most
1445
			; ensures that for a very small output buffer, we emit at most
1446
			; one empty block.
1446
			; one empty block.
1447
 
1447
 
1448
		.end19:
1448
		.end19:
1449
		cmp edx,block_done
1449
		cmp edx,block_done
1450
		jne .end11 ;if (..==..)
1450
		jne .end11 ;if (..==..)
1451
			cmp dword[flush],Z_PARTIAL_FLUSH
1451
			cmp dword[flush],Z_PARTIAL_FLUSH
1452
			jne @f ;if (..==..)
1452
			jne @f ;if (..==..)
1453
				stdcall _tr_align, edi
1453
				stdcall _tr_align, edi
1454
				jmp .end16
1454
				jmp .end16
1455
			@@:
1455
			@@:
1456
			cmp dword[flush],Z_BLOCK
1456
			cmp dword[flush],Z_BLOCK
1457
			je .end16 ;else if (..!=..) ;FULL_FLUSH or SYNC_FLUSH
1457
			je .end16 ;else if (..!=..) ;FULL_FLUSH or SYNC_FLUSH
1458
				stdcall _tr_stored_block, edi, 0, 0, 0
1458
				stdcall _tr_stored_block, edi, 0, 0, 0
1459
				; For a full flush, this empty block will be recognized
1459
				; For a full flush, this empty block will be recognized
1460
				; as a special marker by inflate_sync().
1460
				; as a special marker by inflate_sync().
1461
 
1461
 
1462
			cmp dword[flush],Z_FULL_FLUSH
1462
			cmp dword[flush],Z_FULL_FLUSH
1463
			jne .end16 ;if (..==..)
1463
			jne .end16 ;if (..==..)
1464
				CLEAR_HASH edi ;forget history
1464
				CLEAR_HASH edi ;forget history
1465
				cmp dword[edi+deflate_state.lookahead],0
1465
				cmp dword[edi+deflate_state.lookahead],0
1466
				jne .end16 ;if (..==0)
1466
				jne .end16 ;if (..==0)
1467
					mov dword[edi+deflate_state.strstart],0
1467
					mov dword[edi+deflate_state.strstart],0
1468
					mov dword[edi+deflate_state.block_start],0
1468
					mov dword[edi+deflate_state.block_start],0
1469
					mov dword[edi+deflate_state.insert],0
1469
					mov dword[edi+deflate_state.insert],0
1470
		.end16:
1470
		.end16:
1471
		stdcall flush_pending, ebx
1471
		stdcall flush_pending, ebx
1472
		cmp dword[ebx+z_stream.avail_out],0
1472
		cmp dword[ebx+z_stream.avail_out],0
1473
		jne .end11 ;if (..==0)
1473
		jne .end11 ;if (..==0)
1474
			mov dword[edi+deflate_state.last_flush],-1 ;avoid BUF_ERROR at next call, see above
1474
			mov dword[edi+deflate_state.last_flush],-1 ;avoid BUF_ERROR at next call, see above
1475
			mov eax,Z_OK
1475
			mov eax,Z_OK
1476
			jmp .end_f
1476
			jmp .end_f
1477
	.end11:
1477
	.end11:
1478
	cmp dword[ebx+z_stream.avail_out],0
1478
	cmp dword[ebx+z_stream.avail_out],0
1479
	jg @f
1479
	jg @f
1480
		zlib_assert 'bug2' ;Assert(..>0)
1480
		zlib_assert 'bug2' ;Assert(..>0)
1481
	@@:
1481
	@@:
1482
 
1482
 
1483
	cmp dword[flush],Z_FINISH
1483
	cmp dword[flush],Z_FINISH
1484
	je @f ;if (..!=0)
1484
	je @f ;if (..!=0)
1485
		mov eax,Z_OK
1485
		mov eax,Z_OK
1486
		jmp .end_f
1486
		jmp .end_f
1487
	@@:
1487
	@@:
1488
	cmp dword[edi+deflate_state.wrap],0
1488
	cmp dword[edi+deflate_state.wrap],0
1489
	jg @f ;if (..<=0)
1489
	jg @f ;if (..<=0)
1490
		mov eax,Z_STREAM_END
1490
		mov eax,Z_STREAM_END
1491
		jmp .end_f
1491
		jmp .end_f
1492
	@@:
1492
	@@:
1493
 
1493
 
1494
	; Write the trailer
1494
	; Write the trailer
1495
if GZIP eq 1
1495
if GZIP eq 1
1496
	cmp dword[edi+deflate_state.wrap],2
1496
	cmp dword[edi+deflate_state.wrap],2
1497
	jne @f ;if (..==..)
1497
	jne @f ;if (..==..)
1498
		mov ecx,[ebx+z_stream.adler]
1498
		mov ecx,[ebx+z_stream.adler]
1499
		put_dword edi, ecx
1499
		put_dword edi, ecx
1500
		mov ecx,[ebx+z_stream.total_in]
1500
		mov ecx,[ebx+z_stream.total_in]
1501
		put_dword edi, ecx
1501
		put_dword edi, ecx
1502
		jmp .end17
1502
		jmp .end17
1503
	@@: ;else
1503
	@@: ;else
1504
end if
1504
end if
1505
		mov ecx,[ebx+z_stream.adler]
1505
		mov ecx,[ebx+z_stream.adler]
1506
		bswap ecx
1506
		bswap ecx
1507
		put_dword edi, ecx
1507
		put_dword edi, ecx
1508
	.end17:
1508
	.end17:
1509
	stdcall flush_pending, ebx
1509
	stdcall flush_pending, ebx
1510
	; If avail_out is zero, the application will call deflate again
1510
	; If avail_out is zero, the application will call deflate again
1511
	; to flush the rest.
1511
	; to flush the rest.
1512
 
1512
 
1513
	cmp dword[edi+deflate_state.pending],0
1513
	cmp dword[edi+deflate_state.pending],0
1514
	jle @f ;if (..>0) ;write the trailer only once!
1514
	jle @f ;if (..>0) ;write the trailer only once!
1515
		neg dword[edi+deflate_state.pending]
1515
		neg dword[edi+deflate_state.pending]
1516
		inc dword[edi+deflate_state.pending]
1516
		inc dword[edi+deflate_state.pending]
1517
	@@:
1517
	@@:
1518
	mov eax,Z_OK
1518
	mov eax,Z_OK
1519
	cmp dword[edi+deflate_state.pending],0
1519
	cmp dword[edi+deflate_state.pending],0
1520
	je .end_f
1520
	je .end_f
1521
		mov eax,Z_STREAM_END
1521
		mov eax,Z_STREAM_END
1522
.end_f:
1522
.end_f:
1523
zlib_debug '  deflate.ret = %d',eax
1523
zlib_debug '  deflate.ret = %d',eax
1524
	ret
1524
	ret
1525
endp
1525
endp
1526
 
1526
 
1527
; =========================================================================
1527
; =========================================================================
1528
;int (strm)
1528
;int (strm)
1529
;    z_streamp strm
1529
;    z_streamp strm
1530
align 4
1530
align 4
1531
proc deflateEnd uses ebx ecx edx, strm:dword
1531
proc deflateEnd uses ebx ecx edx, strm:dword
1532
	mov ebx,[strm]
1532
	mov ebx,[strm]
1533
zlib_debug 'deflateEnd'
1533
zlib_debug 'deflateEnd'
1534
	cmp ebx,Z_NULL
1534
	cmp ebx,Z_NULL
1535
	je @f
1535
	je @f
1536
	mov edx,[ebx+z_stream.state]
1536
	mov edx,[ebx+z_stream.state]
1537
	cmp edx,Z_NULL
1537
	cmp edx,Z_NULL
1538
	jne .end0
1538
	jne .end0
1539
	@@: ;if (..==0 || ..==0) return ..
1539
	@@: ;if (..==0 || ..==0) return ..
1540
		mov eax,Z_STREAM_ERROR
1540
		mov eax,Z_STREAM_ERROR
1541
		jmp .end_f
1541
		jmp .end_f
1542
	.end0:
1542
	.end0:
1543
 
1543
 
1544
	mov ecx,[edx+deflate_state.status]
1544
	mov ecx,[edx+deflate_state.status]
1545
	cmp ecx,INIT_STATE
1545
	cmp ecx,INIT_STATE
1546
	je @f
1546
	je @f
1547
	cmp ecx,EXTRA_STATE
1547
	cmp ecx,EXTRA_STATE
1548
	je @f
1548
	je @f
1549
	cmp ecx,NAME_STATE
1549
	cmp ecx,NAME_STATE
1550
	je @f
1550
	je @f
1551
	cmp ecx,COMMENT_STATE
1551
	cmp ecx,COMMENT_STATE
1552
	je @f
1552
	je @f
1553
	cmp ecx,HCRC_STATE
1553
	cmp ecx,HCRC_STATE
1554
	je @f
1554
	je @f
1555
	cmp ecx,BUSY_STATE
1555
	cmp ecx,BUSY_STATE
1556
	je @f
1556
	je @f
1557
	cmp ecx,FINISH_STATE
1557
	cmp ecx,FINISH_STATE
1558
	je @f ;if (..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=..)
1558
	je @f ;if (..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=.. && ..!=..)
1559
		mov eax,Z_STREAM_ERROR
1559
		mov eax,Z_STREAM_ERROR
1560
		jmp .end_f
1560
		jmp .end_f
1561
	@@:
1561
	@@:
1562
 
1562
 
1563
	; Deallocate in reverse order of allocations:
1563
	; Deallocate in reverse order of allocations:
1564
	TRY_FREE ebx, dword[edx+deflate_state.pending_buf]
1564
	TRY_FREE ebx, dword[edx+deflate_state.pending_buf]
1565
	TRY_FREE ebx, dword[edx+deflate_state.head]
1565
	TRY_FREE ebx, dword[edx+deflate_state.head]
1566
	TRY_FREE ebx, dword[edx+deflate_state.prev]
1566
	TRY_FREE ebx, dword[edx+deflate_state.prev]
1567
	TRY_FREE ebx, dword[edx+deflate_state.window]
1567
	TRY_FREE ebx, dword[edx+deflate_state.window]
1568
 
1568
 
1569
	ZFREE ebx, dword[ebx+z_stream.state]
1569
	ZFREE ebx, dword[ebx+z_stream.state]
1570
	mov dword[ebx+z_stream.state],Z_NULL
1570
	mov dword[ebx+z_stream.state],Z_NULL
1571
 
1571
 
1572
	mov eax,Z_DATA_ERROR
1572
	mov eax,Z_DATA_ERROR
1573
	cmp ecx,BUSY_STATE
1573
	cmp ecx,BUSY_STATE
1574
	je .end_f
1574
	je .end_f
1575
		mov eax,Z_OK
1575
		mov eax,Z_OK
1576
.end_f:
1576
.end_f:
1577
	ret
1577
	ret
1578
endp
1578
endp
1579
 
1579
 
1580
; =========================================================================
1580
; =========================================================================
1581
; Copy the source state to the destination state.
1581
; Copy the source state to the destination state.
1582
; To simplify the source, this is not supported for 16-bit MSDOS (which
1582
; To simplify the source, this is not supported for 16-bit MSDOS (which
1583
; doesn't have enough memory anyway to duplicate compression states).
1583
; doesn't have enough memory anyway to duplicate compression states).
1584
 
1584
 
1585
;int (dest, source)
1585
;int (dest, source)
1586
;    z_streamp dest
1586
;    z_streamp dest
1587
;    z_streamp source
1587
;    z_streamp source
1588
align 4
1588
align 4
1589
proc deflateCopy uses ebx edx edi esi, dest:dword, source:dword
1589
proc deflateCopy uses ebx edx edi esi, dest:dword, source:dword
1590
;ebx = overlay ;uint_16p
1590
;ebx = overlay ;uint_16p
1591
;edi = ds ;deflate_state*
1591
;edi = ds ;deflate_state*
1592
;esi = ss ;deflate_state*
1592
;esi = ss ;deflate_state*
1593
 
1593
 
1594
	mov esi,[source]
1594
	mov esi,[source]
1595
	cmp esi,Z_NULL
1595
	cmp esi,Z_NULL
1596
	je @f
1596
	je @f
1597
	mov edx,[dest]
1597
	mov edx,[dest]
1598
	cmp edx,Z_NULL
1598
	cmp edx,Z_NULL
1599
	je @f
1599
	je @f
1600
	mov esi,[esi+z_stream.state]
1600
	mov esi,[esi+z_stream.state]
1601
	cmp esi,Z_NULL
1601
	cmp esi,Z_NULL
1602
	jne .end0
1602
	jne .end0
1603
	@@: ;if (..==0 || ..==0 || ..==0)
1603
	@@: ;if (..==0 || ..==0 || ..==0)
1604
		mov eax,Z_STREAM_ERROR
1604
		mov eax,Z_STREAM_ERROR
1605
		jmp .end_f
1605
		jmp .end_f
1606
	.end0:
1606
	.end0:
1607
 
1607
 
1608
	stdcall zmemcpy, edx, [source], sizeof.z_stream
1608
	stdcall zmemcpy, edx, [source], sizeof.z_stream
1609
 
1609
 
1610
	ZALLOC edx, 1, sizeof.deflate_state
1610
	ZALLOC edx, 1, sizeof.deflate_state
1611
	cmp eax,0
1611
	cmp eax,0
1612
	jne @f ;if (..==0) return ..
1612
	jne @f ;if (..==0) return ..
1613
		mov eax,Z_MEM_ERROR
1613
		mov eax,Z_MEM_ERROR
1614
		jmp .end_f
1614
		jmp .end_f
1615
	@@:
1615
	@@:
1616
	mov edi,eax
1616
	mov edi,eax
1617
	mov [edx+z_stream.state],eax
1617
	mov [edx+z_stream.state],eax
1618
	stdcall zmemcpy, edi, esi, sizeof.deflate_state
1618
	stdcall zmemcpy, edi, esi, sizeof.deflate_state
1619
	mov dword[edi+deflate_state.strm],edx
1619
	mov dword[edi+deflate_state.strm],edx
1620
 
1620
 
1621
	ZALLOC edx, [edi+deflate_state.w_size], 2 ;2*sizeof.db
1621
	ZALLOC edx, [edi+deflate_state.w_size], 2 ;2*sizeof.db
1622
	mov dword[edi+deflate_state.window],eax
1622
	mov dword[edi+deflate_state.window],eax
1623
	ZALLOC edx, [edi+deflate_state.w_size], 4 ;sizeof.dd
1623
	ZALLOC edx, [edi+deflate_state.w_size], 4 ;sizeof.dd
1624
	mov dword[edi+deflate_state.prev],eax
1624
	mov dword[edi+deflate_state.prev],eax
1625
	ZALLOC edx, [edi+deflate_state.hash_size], 4 ;sizeof.dd
1625
	ZALLOC edx, [edi+deflate_state.hash_size], 4 ;sizeof.dd
1626
	mov dword[edi+deflate_state.head],eax
1626
	mov dword[edi+deflate_state.head],eax
1627
	ZALLOC edx, [edi+deflate_state.lit_bufsize], 4 ;sizeof.dw+2
1627
	ZALLOC edx, [edi+deflate_state.lit_bufsize], 4 ;sizeof.dw+2
1628
	mov ebx,eax
1628
	mov ebx,eax
1629
	mov dword[edi+deflate_state.pending_buf],eax
1629
	mov dword[edi+deflate_state.pending_buf],eax
1630
 
1630
 
1631
	cmp dword[edi+deflate_state.window],Z_NULL
1631
	cmp dword[edi+deflate_state.window],Z_NULL
1632
	je @f
1632
	je @f
1633
	cmp dword[edi+deflate_state.prev],Z_NULL
1633
	cmp dword[edi+deflate_state.prev],Z_NULL
1634
	je @f
1634
	je @f
1635
	cmp dword[edi+deflate_state.head],Z_NULL
1635
	cmp dword[edi+deflate_state.head],Z_NULL
1636
	je @f
1636
	je @f
1637
	cmp dword[edi+deflate_state.pending_buf],Z_NULL
1637
	cmp dword[edi+deflate_state.pending_buf],Z_NULL
1638
	jne .end1
1638
	jne .end1
1639
	@@: ;if (..==0 || ..==0 || ..==0 || ..==0)
1639
	@@: ;if (..==0 || ..==0 || ..==0 || ..==0)
1640
		stdcall deflateEnd, edx
1640
		stdcall deflateEnd, edx
1641
		mov eax,Z_MEM_ERROR
1641
		mov eax,Z_MEM_ERROR
1642
		jmp .end_f
1642
		jmp .end_f
1643
	.end1:
1643
	.end1:
1644
 
1644
 
1645
	; following zmemcpy do not work for 16-bit MSDOS
1645
	; following zmemcpy do not work for 16-bit MSDOS
1646
	mov eax,[edi+deflate_state.w_size]
1646
	mov eax,[edi+deflate_state.w_size]
1647
	shl eax,1 ;*= 2*sizeof.db
1647
	shl eax,1 ;*= 2*sizeof.db
1648
	stdcall zmemcpy, [edi+deflate_state.window], [esi+deflate_state.window], eax
1648
	stdcall zmemcpy, [edi+deflate_state.window], [esi+deflate_state.window], eax
1649
	mov eax,[edi+deflate_state.w_size]
1649
	mov eax,[edi+deflate_state.w_size]
1650
	shl eax,2 ;*= sizeof.dd
1650
	shl eax,2 ;*= sizeof.dd
1651
	stdcall zmemcpy, [edi+deflate_state.prev], [esi+deflate_state.prev], eax
1651
	stdcall zmemcpy, [edi+deflate_state.prev], [esi+deflate_state.prev], eax
1652
	mov eax,[edi+deflate_state.hash_size]
1652
	mov eax,[edi+deflate_state.hash_size]
1653
	shl eax,2 ;*= sizeof.dd
1653
	shl eax,2 ;*= sizeof.dd
1654
	stdcall zmemcpy, [edi+deflate_state.head], [esi+deflate_state.head], eax
1654
	stdcall zmemcpy, [edi+deflate_state.head], [esi+deflate_state.head], eax
1655
	stdcall zmemcpy, [edi+deflate_state.pending_buf], [esi+deflate_state.pending_buf], [edi+deflate_state.pending_buf_size]
1655
	stdcall zmemcpy, [edi+deflate_state.pending_buf], [esi+deflate_state.pending_buf], [edi+deflate_state.pending_buf_size]
1656
 
1656
 
1657
	mov eax,[edi+deflate_state.pending_buf]
1657
	mov eax,[edi+deflate_state.pending_buf]
1658
	add eax,[esi+deflate_state.pending_out]
1658
	add eax,[esi+deflate_state.pending_out]
1659
	sub eax,[esi+deflate_state.pending_buf]
1659
	sub eax,[esi+deflate_state.pending_buf]
1660
	mov [edi+deflate_state.pending_out],eax
1660
	mov [edi+deflate_state.pending_out],eax
1661
	mov eax,[edi+deflate_state.lit_bufsize]
1661
	mov eax,[edi+deflate_state.lit_bufsize]
1662
	shr eax,1 ;/=sizeof.uint_16
1662
	shr eax,1 ;/=sizeof.uint_16
1663
	add eax,ebx
1663
	add eax,ebx
1664
	mov [edi+deflate_state.d_buf],eax
1664
	mov [edi+deflate_state.d_buf],eax
1665
	mov eax,[edi+deflate_state.lit_bufsize]
1665
	mov eax,[edi+deflate_state.lit_bufsize]
1666
	imul eax,3 ;*=1+sizeof.uint_16
1666
	imul eax,3 ;*=1+sizeof.uint_16
1667
	add eax,[edi+deflate_state.pending_buf]
1667
	add eax,[edi+deflate_state.pending_buf]
1668
	mov [edi+deflate_state.l_buf],eax
1668
	mov [edi+deflate_state.l_buf],eax
1669
 
1669
 
1670
	mov eax,edi
1670
	mov eax,edi
1671
	add eax,deflate_state.dyn_ltree
1671
	add eax,deflate_state.dyn_ltree
1672
	mov [edi+deflate_state.l_desc.dyn_tree],eax
1672
	mov [edi+deflate_state.l_desc.dyn_tree],eax
1673
	add eax,deflate_state.dyn_dtree-deflate_state.dyn_ltree
1673
	add eax,deflate_state.dyn_dtree-deflate_state.dyn_ltree
1674
	mov [edi+deflate_state.d_desc.dyn_tree],eax
1674
	mov [edi+deflate_state.d_desc.dyn_tree],eax
1675
	add eax,deflate_state.bl_tree-deflate_state.dyn_dtree
1675
	add eax,deflate_state.bl_tree-deflate_state.dyn_dtree
1676
	mov [edi+deflate_state.bl_desc.dyn_tree],eax
1676
	mov [edi+deflate_state.bl_desc.dyn_tree],eax
1677
 
1677
 
1678
	mov eax,Z_OK
1678
	mov eax,Z_OK
1679
.end_f:
1679
.end_f:
1680
	ret
1680
	ret
1681
endp
1681
endp
1682
 
1682
 
1683
; ===========================================================================
1683
; ===========================================================================
1684
; Read a new buffer from the current input stream, update the adler32
1684
; Read a new buffer from the current input stream, update the adler32
1685
; and total number of bytes read.  All deflate() input goes through
1685
; and total number of bytes read.  All deflate() input goes through
1686
; this function so some applications may wish to modify it to avoid
1686
; this function so some applications may wish to modify it to avoid
1687
; allocating a large strm->next_in buffer and copying from it.
1687
; allocating a large strm->next_in buffer and copying from it.
1688
; (See also flush_pending()).
1688
; (See also flush_pending()).
1689
 
1689
 
1690
;int (strm, buf, size)
1690
;int (strm, buf, size)
1691
;    z_streamp strm
1691
;    z_streamp strm
1692
;    Bytef *buf
1692
;    Bytef *buf
1693
;    unsigned size
1693
;    unsigned size
1694
align 4
1694
align 4
1695
proc read_buf uses ebx ecx, strm:dword, buf:dword, size:dword
1695
proc read_buf uses ebx ecx, strm:dword, buf:dword, size:dword
1696
	mov ebx,[strm]
1696
	mov ebx,[strm]
1697
	mov eax,[ebx+z_stream.avail_in]
1697
	mov eax,[ebx+z_stream.avail_in]
1698
 
1698
 
1699
	cmp eax,[size]
1699
	cmp eax,[size]
1700
	jle @f ;if (..>..)
1700
	jle @f ;if (..>..)
1701
		mov eax,[size]
1701
		mov eax,[size]
1702
	@@:
1702
	@@:
1703
	cmp eax,0
1703
	cmp eax,0
1704
	jg @f
1704
	jg @f
1705
		xor eax,eax
1705
		xor eax,eax
1706
		jmp .end_f ;if (..==0) return 0
1706
		jmp .end_f ;if (..==0) return 0
1707
	@@:
1707
	@@:
1708
 
1708
 
1709
	sub [ebx+z_stream.avail_in],eax
1709
	sub [ebx+z_stream.avail_in],eax
1710
 
1710
 
1711
	stdcall zmemcpy, [buf],[ebx+z_stream.next_in],eax
1711
	stdcall zmemcpy, [buf],[ebx+z_stream.next_in],eax
1712
	mov ecx,[ebx+z_stream.state]
1712
	mov ecx,[ebx+z_stream.state]
1713
	cmp dword[ecx+deflate_state.wrap],1
1713
	cmp dword[ecx+deflate_state.wrap],1
1714
	jne @f ;if (..==..)
1714
	jne @f ;if (..==..)
1715
		push eax
1715
		push eax
1716
		stdcall adler32, [ebx+z_stream.adler], [buf], eax
1716
		stdcall adler32, [ebx+z_stream.adler], [buf], eax
1717
		mov [ebx+z_stream.adler],eax
1717
		mov [ebx+z_stream.adler],eax
1718
		pop eax
1718
		pop eax
1719
		jmp .end0
1719
		jmp .end0
1720
	@@:
1720
	@@:
1721
if GZIP eq 1
1721
if GZIP eq 1
1722
	cmp dword[ecx+deflate_state.wrap],2
1722
	cmp dword[ecx+deflate_state.wrap],2
1723
	jne .end0 ;else if (..==..)
1723
	jne .end0 ;else if (..==..)
1724
		push eax
1724
		push eax
1725
		stdcall calc_crc32, [ebx+z_stream.adler], [buf], eax
1725
		stdcall calc_crc32, [ebx+z_stream.adler], [buf], eax
1726
		mov [ebx+z_stream.adler],eax
1726
		mov [ebx+z_stream.adler],eax
1727
		pop eax
1727
		pop eax
1728
end if
1728
end if
1729
	.end0:
1729
	.end0:
1730
	add [ebx+z_stream.next_in],eax
1730
	add [ebx+z_stream.next_in],eax
1731
	add [ebx+z_stream.total_in],eax
1731
	add [ebx+z_stream.total_in],eax
1732
 
1732
 
1733
.end_f:
1733
.end_f:
1734
;zlib_debug '  read_buf.ret = %d',eax
1734
;zlib_debug '  read_buf.ret = %d',eax
1735
	ret
1735
	ret
1736
endp
1736
endp
1737
 
1737
 
1738
; ===========================================================================
1738
; ===========================================================================
1739
; Initialize the "longest match" routines for a new zlib stream
1739
; Initialize the "longest match" routines for a new zlib stream
1740
 
1740
 
1741
;void (s)
1741
;void (s)
1742
;    deflate_state *s
1742
;    deflate_state *s
1743
align 4
1743
align 4
1744
proc lm_init uses eax ebx edi, s:dword
1744
proc lm_init uses eax ebx edi, s:dword
1745
	mov edi,[s]
1745
	mov edi,[s]
1746
	mov eax,[edi+deflate_state.w_size]
1746
	mov eax,[edi+deflate_state.w_size]
1747
	shl eax,1
1747
	shl eax,1
1748
	mov [edi+deflate_state.window_size],eax
1748
	mov [edi+deflate_state.window_size],eax
1749
 
1749
 
1750
	CLEAR_HASH edi
1750
	CLEAR_HASH edi
1751
 
1751
 
1752
	; Set the default configuration parameters:
1752
	; Set the default configuration parameters:
1753
 
1753
 
1754
	movzx eax,word[edi+deflate_state.level]
1754
	movzx eax,word[edi+deflate_state.level]
1755
	imul eax,sizeof.config_s
1755
	imul eax,sizeof.config_s
1756
	add eax,configuration_table
1756
	add eax,configuration_table
1757
	movzx ebx,word[eax+config_s.max_lazy]
1757
	movzx ebx,word[eax+config_s.max_lazy]
1758
	mov [edi+deflate_state.max_lazy_match],ebx
1758
	mov [edi+deflate_state.max_lazy_match],ebx
1759
	movzx ebx,word[eax+config_s.good_length]
1759
	movzx ebx,word[eax+config_s.good_length]
1760
	mov [edi+deflate_state.good_match],ebx
1760
	mov [edi+deflate_state.good_match],ebx
1761
	movzx ebx,word[eax+config_s.nice_length]
1761
	movzx ebx,word[eax+config_s.nice_length]
1762
	mov [edi+deflate_state.nice_match],ebx
1762
	mov [edi+deflate_state.nice_match],ebx
1763
	movzx ebx,word[eax+config_s.max_chain]
1763
	movzx ebx,word[eax+config_s.max_chain]
1764
	mov [edi+deflate_state.max_chain_length],ebx
1764
	mov [edi+deflate_state.max_chain_length],ebx
1765
 
1765
 
1766
	mov dword[edi+deflate_state.strstart],0
1766
	mov dword[edi+deflate_state.strstart],0
1767
	mov dword[edi+deflate_state.block_start],0
1767
	mov dword[edi+deflate_state.block_start],0
1768
	mov dword[edi+deflate_state.lookahead],0
1768
	mov dword[edi+deflate_state.lookahead],0
1769
	mov dword[edi+deflate_state.insert],0
1769
	mov dword[edi+deflate_state.insert],0
1770
	mov dword[edi+deflate_state.prev_length],MIN_MATCH-1
1770
	mov dword[edi+deflate_state.prev_length],MIN_MATCH-1
1771
	mov dword[edi+deflate_state.match_length],MIN_MATCH-1
1771
	mov dword[edi+deflate_state.match_length],MIN_MATCH-1
1772
	mov dword[edi+deflate_state.match_available],0
1772
	mov dword[edi+deflate_state.match_available],0
1773
	mov dword[edi+deflate_state.ins_h],0
1773
	mov dword[edi+deflate_state.ins_h],0
1774
if FASTEST eq 0
1774
if FASTEST eq 0
1775
;if ASMV
1775
;if ASMV
1776
;    call match_init ;initialize the asm code
1776
;    call match_init ;initialize the asm code
1777
;end if
1777
;end if
1778
end if
1778
end if
1779
	ret
1779
	ret
1780
endp
1780
endp
1781
 
1781
 
1782
;uInt (s, cur_match)
1782
;uInt (s, cur_match)
1783
;    deflate_state *s
1783
;    deflate_state *s
1784
;    IPos cur_match ;current match
1784
;    IPos cur_match ;current match
1785
align 4
1785
align 4
1786
proc longest_match uses ebx ecx edx edi esi, s:dword, cur_match:dword
1786
proc longest_match uses ebx ecx edx edi esi, s:dword, cur_match:dword
1787
if FASTEST eq 0
1787
if FASTEST eq 0
1788
; ===========================================================================
1788
; ===========================================================================
1789
; Set match_start to the longest match starting at the given string and
1789
; Set match_start to the longest match starting at the given string and
1790
; return its length. Matches shorter or equal to prev_length are discarded,
1790
; return its length. Matches shorter or equal to prev_length are discarded,
1791
; in which case the result is equal to prev_length and match_start is
1791
; in which case the result is equal to prev_length and match_start is
1792
; garbage.
1792
; garbage.
1793
; IN assertions: cur_match is the head of the hash chain for the current
1793
; IN assertions: cur_match is the head of the hash chain for the current
1794
;   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
1794
;   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
1795
; OUT assertion: the match length is not greater than s->lookahead.
1795
; OUT assertion: the match length is not greater than s->lookahead.
1796
 
1796
 
1797
;#ifndef ASMV
1797
;#ifndef ASMV
1798
; For 80x86 and 680x0, an optimized version will be provided in match.asm or
1798
; For 80x86 and 680x0, an optimized version will be provided in match.asm or
1799
; match.S. The code will be functionally equivalent.
1799
; match.S. The code will be functionally equivalent.
1800
locals
1800
locals
1801
	chain_length dd ? ;unsigned ;max hash chain length
1801
	chain_length dd ? ;unsigned ;max hash chain length
1802
	len        dd ? ;int ;length of current match
1802
	len        dd ? ;int ;length of current match
1803
	strend     dd ? ;Bytef *
1803
	strend     dd ? ;Bytef *
1804
	best_len   dd ? ;int ;best match length so far
1804
	best_len   dd ? ;int ;best match length so far
1805
	nice_match dd ? ;int ;stop if match long enough
1805
	nice_match dd ? ;int ;stop if match long enough
1806
	limit      dd NIL ;IPos
1806
	limit      dd NIL ;IPos
1807
	prev       dd ? ;Posf *
1807
	prev       dd ? ;Posf *
1808
	wmask      dd ? ;uInt
1808
	wmask      dd ? ;uInt
1809
endl
1809
endl
1810
	mov edx,[s]
1810
	mov edx,[s]
1811
	mov eax,[edx+deflate_state.max_chain_length]
1811
	mov eax,[edx+deflate_state.max_chain_length]
1812
	mov [chain_length],eax
1812
	mov [chain_length],eax
1813
	mov edi,[edx+deflate_state.window]
1813
	mov edi,[edx+deflate_state.window]
1814
	add edi,[edx+deflate_state.strstart]
1814
	add edi,[edx+deflate_state.strstart]
1815
	;edi - Bytef *scan ;current string
1815
	;edi - Bytef *scan ;current string
1816
	;esi - Bytef *match ;matched string
1816
	;esi - Bytef *match ;matched string
1817
	mov eax,[edx+deflate_state.prev_length]
1817
	mov eax,[edx+deflate_state.prev_length]
1818
	mov [best_len],eax
1818
	mov [best_len],eax
1819
	mov eax,[edx+deflate_state.nice_match]
1819
	mov eax,[edx+deflate_state.nice_match]
1820
	mov [nice_match],eax
1820
	mov [nice_match],eax
1821
 
1821
 
1822
	MAX_DIST edx
1822
	MAX_DIST edx
1823
	cmp [edx+deflate_state.strstart],eax
1823
	cmp [edx+deflate_state.strstart],eax
1824
	jle @f
1824
	jle @f
1825
		mov ecx,[edx+deflate_state.strstart]
1825
		mov ecx,[edx+deflate_state.strstart]
1826
		sub ecx,eax
1826
		sub ecx,eax
1827
		mov [limit],ecx
1827
		mov [limit],ecx
1828
	@@:
1828
	@@:
1829
	; Stop when cur_match becomes <= limit. To simplify the code,
1829
	; Stop when cur_match becomes <= limit. To simplify the code,
1830
	; we prevent matches with the string of window index 0.
1830
	; we prevent matches with the string of window index 0.
1831
	mov eax,[edx+deflate_state.prev]
1831
	mov eax,[edx+deflate_state.prev]
1832
	mov [prev],eax
1832
	mov [prev],eax
1833
	mov eax,[edx+deflate_state.w_mask]
1833
	mov eax,[edx+deflate_state.w_mask]
1834
	mov [wmask],eax
1834
	mov [wmask],eax
1835
	mov eax,edi
1835
	mov eax,edi
1836
	add eax,MAX_MATCH ;-1 ???
1836
	add eax,MAX_MATCH ;-1 ???
1837
	mov [strend],eax
1837
	mov [strend],eax
1838
	mov eax,[best_len]
1838
	mov eax,[best_len]
1839
	dec eax
1839
	dec eax
1840
	mov bx,[edi+eax]
1840
	mov bx,[edi+eax]
1841
	;bl - Byte scan_end1
1841
	;bl - Byte scan_end1
1842
	;bh - Byte scan_end
1842
	;bh - Byte scan_end
1843
 
1843
 
1844
	; The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1844
	; The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1845
	; It is easy to get rid of this optimization if necessary.
1845
	; It is easy to get rid of this optimization if necessary.
1846
 
1846
 
1847
if MAX_MATCH <> 258
1847
if MAX_MATCH <> 258
1848
	cmp dword[edx+deflate_state.hash_bits],8
1848
	cmp dword[edx+deflate_state.hash_bits],8
1849
	jge @f
1849
	jge @f
1850
		zlib_assert 'Code too clever' ;Assert(..>=.. && ..==..)
1850
		zlib_assert 'Code too clever' ;Assert(..>=.. && ..==..)
1851
	@@:
1851
	@@:
1852
end if
1852
end if
1853
 
1853
 
1854
	; Do not waste too much time if we already have a good match:
1854
	; Do not waste too much time if we already have a good match:
1855
	mov eax,[edx+deflate_state.good_match]
1855
	mov eax,[edx+deflate_state.good_match]
1856
	cmp [edx+deflate_state.prev_length],eax
1856
	cmp [edx+deflate_state.prev_length],eax
1857
	jl @f ;if (..>=..)
1857
	jl @f ;if (..>=..)
1858
		shr dword[chain_length],2
1858
		shr dword[chain_length],2
1859
	@@:
1859
	@@:
1860
	; Do not look for matches beyond the end of the input. This is necessary
1860
	; Do not look for matches beyond the end of the input. This is necessary
1861
	; to make deflate deterministic.
1861
	; to make deflate deterministic.
1862
 
1862
 
1863
	mov eax,[edx+deflate_state.lookahead]
1863
	mov eax,[edx+deflate_state.lookahead]
1864
	cmp dword[nice_match],eax
1864
	cmp dword[nice_match],eax
1865
	jle @f ;if (..>..)
1865
	jle @f ;if (..>..)
1866
		mov [nice_match],eax
1866
		mov [nice_match],eax
1867
	@@:
1867
	@@:
1868
 
1868
 
1869
	mov eax,[edx+deflate_state.window_size]
1869
	mov eax,[edx+deflate_state.window_size]
1870
	sub eax,MIN_LOOKAHEAD
1870
	sub eax,MIN_LOOKAHEAD
1871
	cmp [edx+deflate_state.strstart],eax
1871
	cmp [edx+deflate_state.strstart],eax
1872
	jle .cycle0
1872
	jle .cycle0
1873
		zlib_assert 'need lookahead' ;Assert(..<=..)
1873
		zlib_assert 'need lookahead' ;Assert(..<=..)
1874
 
1874
 
1875
align 4
1875
align 4
1876
	.cycle0: ;do
1876
	.cycle0: ;do
1877
		mov eax,[edx+deflate_state.strstart]
1877
		mov eax,[edx+deflate_state.strstart]
1878
		cmp [cur_match],eax
1878
		cmp [cur_match],eax
1879
		jl @f
1879
		jl @f
1880
			zlib_assert 'no future' ;Assert(..<..)
1880
			zlib_assert 'no future' ;Assert(..<..)
1881
		@@:
1881
		@@:
1882
		mov esi,[edx+deflate_state.window]
1882
		mov esi,[edx+deflate_state.window]
1883
		add esi,[cur_match]
1883
		add esi,[cur_match]
1884
 
1884
 
1885
		; Skip to next match if the match length cannot increase
1885
		; Skip to next match if the match length cannot increase
1886
		; or if the match length is less than 2.  Note that the checks below
1886
		; or if the match length is less than 2.  Note that the checks below
1887
		; for insufficient lookahead only occur occasionally for performance
1887
		; for insufficient lookahead only occur occasionally for performance
1888
		; reasons.  Therefore uninitialized memory will be accessed, and
1888
		; reasons.  Therefore uninitialized memory will be accessed, and
1889
		; conditional jumps will be made that depend on those values.
1889
		; conditional jumps will be made that depend on those values.
1890
		; However the length of the match is limited to the lookahead, so
1890
		; However the length of the match is limited to the lookahead, so
1891
		; the output of deflate is not affected by the uninitialized values.
1891
		; the output of deflate is not affected by the uninitialized values.
1892
 
1892
 
1893
		mov eax,[best_len]
1893
		mov eax,[best_len]
1894
		dec eax
1894
		dec eax
1895
		cmp word[esi+eax],bx
1895
		cmp word[esi+eax],bx
1896
		jne .cycle0cont
1896
		jne .cycle0cont
1897
		mov al,byte[esi]
1897
		mov al,byte[esi]
1898
		cmp al,byte[edi]
1898
		cmp al,byte[edi]
1899
		jne .cycle0cont
1899
		jne .cycle0cont
1900
		inc esi
1900
		inc esi
1901
		mov al,byte[esi]
1901
		mov al,byte[esi]
1902
		cmp al,[edi+1]
1902
		cmp al,[edi+1]
1903
		jne .cycle0cont ;if (..!=.. || ..!=.. || ..!=.. || ..!=..) continue
1903
		jne .cycle0cont ;if (..!=.. || ..!=.. || ..!=.. || ..!=..) continue
1904
 
1904
 
1905
		; The check at best_len-1 can be removed because it will be made
1905
		; The check at best_len-1 can be removed because it will be made
1906
		; again later. (This heuristic is not always a win.)
1906
		; again later. (This heuristic is not always a win.)
1907
		; It is not necessary to compare scan[2] and match[2] since they
1907
		; It is not necessary to compare scan[2] and match[2] since they
1908
		; are always equal when the other bytes match, given that
1908
		; are always equal when the other bytes match, given that
1909
		; the hash keys are equal and that HASH_BITS >= 8.
1909
		; the hash keys are equal and that HASH_BITS >= 8.
1910
 
1910
 
1911
		add edi,2
1911
		add edi,2
1912
		inc esi
1912
		inc esi
1913
		mov al,byte[edi]
1913
		mov al,byte[edi]
1914
		cmp al,byte[esi]
1914
		cmp al,byte[esi]
1915
		je @f
1915
		je @f
1916
			zlib_assert 'match[2]?' ;Assert(..==..)
1916
			zlib_assert 'match[2]?' ;Assert(..==..)
1917
		@@:
1917
		@@:
1918
 
1918
 
1919
		; We check for insufficient lookahead only every 8th comparison;
1919
		; We check for insufficient lookahead only every 8th comparison;
1920
		; the 256th check will be made at strstart+258.
1920
		; the 256th check will be made at strstart+258.
1921
 
1921
 
1922
		inc edi
1922
		inc edi
1923
		inc esi
1923
		inc esi
1924
		mov ecx,[strend]
1924
		mov ecx,[strend]
1925
		sub ecx,edi
1925
		sub ecx,edi
1926
		jz @f
1926
		jz @f
1927
			repe cmpsb
1927
			repe cmpsb
1928
			dec edi
1928
			dec edi
1929
			dec esi
1929
			dec esi
1930
		@@:
1930
		@@:
1931
 
1931
 
1932
		mov eax,[edx+deflate_state.window_size]
1932
		mov eax,[edx+deflate_state.window_size]
1933
		dec eax
1933
		dec eax
1934
		add eax,[edx+deflate_state.window]
1934
		add eax,[edx+deflate_state.window]
1935
		cmp edi,eax
1935
		cmp edi,eax
1936
		jle @f
1936
		jle @f
1937
			zlib_assert 'wild scan' ;Assert(..<=..)
1937
			zlib_assert 'wild scan' ;Assert(..<=..)
1938
		@@:
1938
		@@:
1939
 
1939
 
1940
		mov eax,MAX_MATCH
1940
		mov eax,MAX_MATCH
1941
		add eax,edi
1941
		add eax,edi
1942
		sub eax,[strend]
1942
		sub eax,[strend]
1943
		mov [len],eax
1943
		mov [len],eax
1944
		mov edi,[strend]
1944
		mov edi,[strend]
1945
		sub edi,MAX_MATCH
1945
		sub edi,MAX_MATCH
1946
 
1946
 
1947
		mov eax,[best_len]
1947
		mov eax,[best_len]
1948
		cmp [len],eax
1948
		cmp [len],eax
1949
		jle .cycle0cont ;if (..>..)
1949
		jle .cycle0cont ;if (..>..)
1950
			mov eax,[cur_match]
1950
			mov eax,[cur_match]
1951
			mov [edx+deflate_state.match_start],eax
1951
			mov [edx+deflate_state.match_start],eax
1952
			mov eax,[len]
1952
			mov eax,[len]
1953
			mov [best_len],eax
1953
			mov [best_len],eax
1954
			mov eax,[nice_match]
1954
			mov eax,[nice_match]
1955
			cmp [len],eax
1955
			cmp [len],eax
1956
			jge .cycle0end ;if (..>=..) break
1956
			jge .cycle0end ;if (..>=..) break
1957
			mov eax,[best_len]
1957
			mov eax,[best_len]
1958
			dec eax
1958
			dec eax
1959
			mov bx,[edi+eax]
1959
			mov bx,[edi+eax]
1960
 
1960
 
1961
		.cycle0cont:
1961
		.cycle0cont:
1962
		mov eax,[cur_match]
1962
		mov eax,[cur_match]
1963
		and eax,[wmask]
1963
		and eax,[wmask]
1964
		shl eax,2
1964
		shl eax,2
1965
		add eax,[prev]
1965
		add eax,[prev]
1966
		mov eax,[eax] ;eax = prev[cur_match & wmask]
1966
		mov eax,[eax] ;eax = prev[cur_match & wmask]
1967
		mov [cur_match],eax
1967
		mov [cur_match],eax
1968
		cmp eax,[limit]
1968
		cmp eax,[limit]
1969
		jle .cycle0end
1969
		jle .cycle0end
1970
		dec dword[chain_length]
1970
		dec dword[chain_length]
1971
		cmp dword[chain_length],0
1971
		cmp dword[chain_length],0
1972
		jne .cycle0
1972
		jne .cycle0
1973
align 4
1973
align 4
1974
	.cycle0end: ;while (..>.. && ..!=0)
1974
	.cycle0end: ;while (..>.. && ..!=0)
1975
 
1975
 
1976
	mov eax,[edx+deflate_state.lookahead]
1976
	mov eax,[edx+deflate_state.lookahead]
1977
	cmp [best_len],eax
1977
	cmp [best_len],eax
1978
	jg @f ;if (..<=..)
1978
	jg @f ;if (..<=..)
1979
		mov eax,[best_len]
1979
		mov eax,[best_len]
1980
	@@:	
1980
	@@:	
1981
;end if ;ASMV
1981
;end if ;ASMV
1982
 
1982
 
1983
else ;FASTEST
1983
else ;FASTEST
1984
 
1984
 
1985
; ---------------------------------------------------------------------------
1985
; ---------------------------------------------------------------------------
1986
; Optimized version for FASTEST only
1986
; Optimized version for FASTEST only
1987
	mov edx,[s]
1987
	mov edx,[s]
1988
	zlib_debug 'longest_match'
1988
	zlib_debug 'longest_match'
1989
 
1989
 
1990
	; The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1990
	; The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
1991
	; It is easy to get rid of this optimization if necessary.
1991
	; It is easy to get rid of this optimization if necessary.
1992
 
1992
 
1993
if MAX_MATCH <> 258
1993
if MAX_MATCH <> 258
1994
	cmp dword[edx+deflate_state.hash_bits],8
1994
	cmp dword[edx+deflate_state.hash_bits],8
1995
	jge @f
1995
	jge @f
1996
		zlib_assert 'Code too clever' ;Assert(..>=.. && ..==..)
1996
		zlib_assert 'Code too clever' ;Assert(..>=.. && ..==..)
1997
	@@:
1997
	@@:
1998
end if
1998
end if
1999
	mov eax,[edx+deflate_state.window_size]
1999
	mov eax,[edx+deflate_state.window_size]
2000
	sub eax,MIN_LOOKAHEAD
2000
	sub eax,MIN_LOOKAHEAD
2001
	cmp [edx+deflate_state.strstart],eax
2001
	cmp [edx+deflate_state.strstart],eax
2002
	jle @f
2002
	jle @f
2003
		zlib_assert 'need lookahead' ;Assert(..<=..)
2003
		zlib_assert 'need lookahead' ;Assert(..<=..)
2004
	@@:
2004
	@@:
2005
	mov eax,[edx+deflate_state.strstart]
2005
	mov eax,[edx+deflate_state.strstart]
2006
	cmp [cur_match],eax
2006
	cmp [cur_match],eax
2007
	jl @f
2007
	jl @f
2008
		zlib_assert 'no future' ;Assert(..<..)
2008
		zlib_assert 'no future' ;Assert(..<..)
2009
	@@:
2009
	@@:
2010
 
2010
 
2011
	mov esi,[edx+deflate_state.window]
2011
	mov esi,[edx+deflate_state.window]
2012
	mov edi,esi
2012
	mov edi,esi
2013
	add esi,[cur_match]
2013
	add esi,[cur_match]
2014
	add edi,[edx+deflate_state.strstart]
2014
	add edi,[edx+deflate_state.strstart]
2015
	;edi = scan
2015
	;edi = scan
2016
	;esi = match
2016
	;esi = match
2017
 
2017
 
2018
	; Return failure if the match length is less than 2:
2018
	; Return failure if the match length is less than 2:
2019
 
2019
 
2020
	lodsw
2020
	lodsw
2021
	cmp ax,word[edi]
2021
	cmp ax,word[edi]
2022
	je @f ;if (word[edi] != word[esi]) return 
2022
	je @f ;if (word[edi] != word[esi]) return 
2023
		mov eax,MIN_MATCH-1
2023
		mov eax,MIN_MATCH-1
2024
		jmp .end_f
2024
		jmp .end_f
2025
	@@:
2025
	@@:
2026
 
2026
 
2027
	; The check at best_len-1 can be removed because it will be made
2027
	; The check at best_len-1 can be removed because it will be made
2028
	; again later. (This heuristic is not always a win.)
2028
	; again later. (This heuristic is not always a win.)
2029
	; It is not necessary to compare scan[2] and match[2] since they
2029
	; It is not necessary to compare scan[2] and match[2] since they
2030
	; are always equal when the other bytes match, given that
2030
	; are always equal when the other bytes match, given that
2031
	; the hash keys are equal and that HASH_BITS >= 8.
2031
	; the hash keys are equal and that HASH_BITS >= 8.
2032
 
2032
 
2033
	add edi,2
2033
	add edi,2
2034
	mov al,byte[edi]
2034
	mov al,byte[edi]
2035
	cmp al,byte[esi]
2035
	cmp al,byte[esi]
2036
	je @f
2036
	je @f
2037
		zlib_assert 'match[2]?' ;Assert(..==..)
2037
		zlib_assert 'match[2]?' ;Assert(..==..)
2038
	@@:
2038
	@@:
2039
 
2039
 
2040
	; We check for insufficient lookahead only every 8th comparison;
2040
	; We check for insufficient lookahead only every 8th comparison;
2041
	; the 256th check will be made at strstart+258.
2041
	; the 256th check will be made at strstart+258.
2042
 
2042
 
2043
	mov ebx,edi
2043
	mov ebx,edi
2044
	mov ecx,MAX_MATCH
2044
	mov ecx,MAX_MATCH
2045
align 4
2045
align 4
2046
	@@:
2046
	@@:
2047
		lodsb
2047
		lodsb
2048
		scasb
2048
		scasb
2049
		loope @b
2049
		loope @b
2050
 
2050
 
2051
	mov eax,[edx+deflate_state.window_size]
2051
	mov eax,[edx+deflate_state.window_size]
2052
	dec eax
2052
	dec eax
2053
	add eax,[edx+deflate_state.window]
2053
	add eax,[edx+deflate_state.window]
2054
	cmp edi,eax
2054
	cmp edi,eax
2055
	jle @f
2055
	jle @f
2056
		zlib_assert 'wild scan' ;Assert(..<=..)
2056
		zlib_assert 'wild scan' ;Assert(..<=..)
2057
	@@:
2057
	@@:
2058
	sub edi,ebx
2058
	sub edi,ebx
2059
	;edi = len
2059
	;edi = len
2060
 
2060
 
2061
	cmp edi,MIN_MATCH
2061
	cmp edi,MIN_MATCH
2062
	jge @f ;if (..<..) 
2062
	jge @f ;if (..<..) 
2063
		mov eax,MIN_MATCH-1
2063
		mov eax,MIN_MATCH-1
2064
		jmp .end_f
2064
		jmp .end_f
2065
	@@:
2065
	@@:
2066
	mov eax,[cur_match]
2066
	mov eax,[cur_match]
2067
	mov [edx+deflate_state.match_start],eax
2067
	mov [edx+deflate_state.match_start],eax
2068
	mov eax,[edx+deflate_state.lookahead]
2068
	mov eax,[edx+deflate_state.lookahead]
2069
	cmp edi,eax
2069
	cmp edi,eax
2070
	jg @f ;if (len <= s.lookahead) ? len : s.lookahead
2070
	jg @f ;if (len <= s.lookahead) ? len : s.lookahead
2071
		mov eax,edi
2071
		mov eax,edi
2072
	@@:
2072
	@@:
2073
end if ;FASTEST
2073
end if ;FASTEST
2074
.end_f:
2074
.end_f:
2075
;zlib_debug '  longest_match.ret = %d',eax
2075
;zlib_debug '  longest_match.ret = %d',eax
2076
	ret
2076
	ret
2077
endp
2077
endp
2078
 
2078
 
2079
 
2079
 
2080
; ===========================================================================
2080
; ===========================================================================
2081
; Check that the match at match_start is indeed a match.
2081
; Check that the match at match_start is indeed a match.
2082
 
2082
 
2083
;void (s, start, match, length)
2083
;void (s, start, match, length)
2084
;    deflate_state *s
2084
;    deflate_state *s
2085
;    IPos start, match
2085
;    IPos start, match
2086
;    int length
2086
;    int length
2087
align 4
2087
align 4
2088
proc check_match, s:dword, start:dword, p3match:dword, length:dword
2088
proc check_match, s:dword, start:dword, p3match:dword, length:dword
2089
if DEBUG eq 1
2089
if DEBUG eq 1
2090
	; check that the match is indeed a match
2090
	; check that the match is indeed a match
2091
;    if (zmemcmp(s->window + match,
2091
;    if (zmemcmp(s->window + match,
2092
;                s->window + start, length) != EQUAL) {
2092
;                s->window + start, length) != EQUAL) {
2093
;        fprintf(stderr, " start %u, match %u, length %d\n",
2093
;        fprintf(stderr, " start %u, match %u, length %d\n",
2094
;                start, match, length);
2094
;                start, match, length);
2095
;        do {
2095
;        do {
2096
;            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
2096
;            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
2097
;        } while (--length != 0);
2097
;        } while (--length != 0);
2098
;        z_error("invalid match");
2098
;        z_error("invalid match");
2099
;    }
2099
;    }
2100
;    if (z_verbose > 1) {
2100
;    if (z_verbose > 1) {
2101
;        fprintf(stderr,"\\[%d,%d]", start-match, length);
2101
;        fprintf(stderr,"\\[%d,%d]", start-match, length);
2102
;        do { putc(s->window[start++], stderr); } while (--length != 0);
2102
;        do { putc(s->window[start++], stderr); } while (--length != 0);
2103
;    }
2103
;    }
2104
end if ;DEBUG
2104
end if ;DEBUG
2105
	ret
2105
	ret
2106
endp
2106
endp
2107
 
2107
 
2108
 
2108
 
2109
; ===========================================================================
2109
; ===========================================================================
2110
; Fill the window when the lookahead becomes insufficient.
2110
; Fill the window when the lookahead becomes insufficient.
2111
; Updates strstart and lookahead.
2111
; Updates strstart and lookahead.
2112
 
2112
 
2113
; IN assertion: lookahead < MIN_LOOKAHEAD
2113
; IN assertion: lookahead < MIN_LOOKAHEAD
2114
; OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
2114
; OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
2115
;    At least one byte has been read, or avail_in == 0; reads are
2115
;    At least one byte has been read, or avail_in == 0; reads are
2116
;    performed for at least two bytes (required for the zip translate_eol
2116
;    performed for at least two bytes (required for the zip translate_eol
2117
;    option -- not supported here).
2117
;    option -- not supported here).
2118
 
2118
 
2119
;void (s)
2119
;void (s)
2120
;    deflate_state *s
2120
;    deflate_state *s
2121
align 4
2121
align 4
2122
proc fill_window, s:dword
2122
proc fill_window, s:dword
2123
pushad
2123
pushad
2124
;esi = p, str, curr
2124
;esi = p, str, curr
2125
;ebx = more ;Amount of free space at the end of the window.
2125
;ebx = more ;Amount of free space at the end of the window.
2126
	;Объем свободного пространства в конце окна.
2126
	;Объем свободного пространства в конце окна.
2127
;ecx = wsize ;uInt
2127
;ecx = wsize ;uInt
2128
;edx = s.strm
2128
;edx = s.strm
2129
	zlib_debug 'fill_window'
2129
	zlib_debug 'fill_window'
2130
	mov edi,[s]
2130
	mov edi,[s]
2131
	cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2131
	cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2132
	jl @f
2132
	jl @f
2133
		zlib_assert 'already enough lookahead' ;Assert(..<..)
2133
		zlib_assert 'already enough lookahead' ;Assert(..<..)
2134
	@@:
2134
	@@:
2135
 
2135
 
2136
	mov ecx,[edi+deflate_state.w_size]
2136
	mov ecx,[edi+deflate_state.w_size]
2137
	mov edx,[edi+deflate_state.strm]
2137
	mov edx,[edi+deflate_state.strm]
2138
	.cycle0: ;do
2138
	.cycle0: ;do
2139
	zlib_debug 'do'
2139
	zlib_debug 'do'
2140
		mov ebx,[edi+deflate_state.window_size]
2140
		mov ebx,[edi+deflate_state.window_size]
2141
		sub ebx,[edi+deflate_state.lookahead]
2141
		sub ebx,[edi+deflate_state.lookahead]
2142
		sub ebx,[edi+deflate_state.strstart]
2142
		sub ebx,[edi+deflate_state.strstart]
2143
 
2143
 
2144
		; If the window is almost full and there is insufficient lookahead,
2144
		; If the window is almost full and there is insufficient lookahead,
2145
		; move the upper half to the lower one to make room in the upper half.
2145
		; move the upper half to the lower one to make room in the upper half.
2146
 
2146
 
2147
		MAX_DIST edi
2147
		MAX_DIST edi
2148
		add eax,ecx
2148
		add eax,ecx
2149
		cmp [edi+deflate_state.strstart],eax
2149
		cmp [edi+deflate_state.strstart],eax
2150
		jl .end0 ;if (..>=..)
2150
		jl .end0 ;if (..>=..)
2151
			push ecx
2151
			push ecx
2152
			mov eax,[edi+deflate_state.window]
2152
			mov eax,[edi+deflate_state.window]
2153
			add eax,ecx
2153
			add eax,ecx
2154
			stdcall zmemcpy, [edi+deflate_state.window], eax
2154
			stdcall zmemcpy, [edi+deflate_state.window], eax
2155
			sub [edi+deflate_state.match_start],ecx
2155
			sub [edi+deflate_state.match_start],ecx
2156
			sub [edi+deflate_state.strstart],ecx ;we now have strstart >= MAX_DIST
2156
			sub [edi+deflate_state.strstart],ecx ;we now have strstart >= MAX_DIST
2157
			sub [edi+deflate_state.block_start],ecx
2157
			sub [edi+deflate_state.block_start],ecx
2158
 
2158
 
2159
			; Slide the hash table (could be avoided with 32 bit values
2159
			; Slide the hash table (could be avoided with 32 bit values
2160
			; at the expense of memory usage). We slide even when level == 0
2160
			; at the expense of memory usage). We slide even when level == 0
2161
			; to keep the hash table consistent if we switch back to level > 0
2161
			; to keep the hash table consistent if we switch back to level > 0
2162
			; later. (Using level 0 permanently is not an optimal usage of
2162
			; later. (Using level 0 permanently is not an optimal usage of
2163
			; zlib, so we don't care about this pathological case.)
2163
			; zlib, so we don't care about this pathological case.)
2164
 
2164
 
2165
			push ebx ecx
2165
			push ebx ecx
2166
			;ebx = wsize
2166
			;ebx = wsize
2167
			;ecx = n
2167
			;ecx = n
2168
			mov ebx,ecx
2168
			mov ebx,ecx
2169
			mov ecx,[edi+deflate_state.hash_size]
2169
			mov ecx,[edi+deflate_state.hash_size]
2170
			mov esi,ecx
2170
			mov esi,ecx
2171
			shl esi,2
2171
			shl esi,2
2172
			add esi,[edi+deflate_state.head]
2172
			add esi,[edi+deflate_state.head]
2173
			.cycle1: ;do
2173
			.cycle1: ;do
2174
				sub esi,4
2174
				sub esi,4
2175
				mov eax,[esi]
2175
				mov eax,[esi]
2176
				mov dword[esi],NIL
2176
				mov dword[esi],NIL
2177
				cmp eax,ebx
2177
				cmp eax,ebx
2178
				jl @f
2178
				jl @f
2179
					sub eax,ebx
2179
					sub eax,ebx
2180
					mov dword[esi],eax
2180
					mov dword[esi],eax
2181
				@@:
2181
				@@:
2182
			loop .cycle1 ;while (..)
2182
			loop .cycle1 ;while (..)
2183
 
2183
 
2184
if FASTEST eq 0
2184
if FASTEST eq 0
2185
			mov ecx,ebx
2185
			mov ecx,ebx
2186
			mov esi,ecx
2186
			mov esi,ecx
2187
			shl esi,2
2187
			shl esi,2
2188
			add esi,[edi+deflate_state.prev]
2188
			add esi,[edi+deflate_state.prev]
2189
			.cycle2: ;do
2189
			.cycle2: ;do
2190
				sub esi,4
2190
				sub esi,4
2191
				mov eax,[esi]
2191
				mov eax,[esi]
2192
				mov dword[esi],NIL
2192
				mov dword[esi],NIL
2193
				cmp eax,ebx
2193
				cmp eax,ebx
2194
				jl @f
2194
				jl @f
2195
					sub eax,ebx
2195
					sub eax,ebx
2196
					mov dword[esi],eax
2196
					mov dword[esi],eax
2197
				@@:
2197
				@@:
2198
				; If n is not on any hash chain, prev[n] is garbage but
2198
				; If n is not on any hash chain, prev[n] is garbage but
2199
				; its value will never be used.
2199
				; its value will never be used.
2200
 
2200
 
2201
			loop .cycle2 ;while (..)
2201
			loop .cycle2 ;while (..)
2202
end if
2202
end if
2203
			pop ecx ebx
2203
			pop ecx ebx
2204
			add ebx,ecx
2204
			add ebx,ecx
2205
		.end0:
2205
		.end0:
2206
		cmp dword[edx+z_stream.avail_in],0
2206
		cmp dword[edx+z_stream.avail_in],0
2207
		je .cycle0end ;if (..==0) break
2207
		je .cycle0end ;if (..==0) break
2208
 
2208
 
2209
		; If there was no sliding:
2209
		; If there was no sliding:
2210
		;    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
2210
		;    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
2211
		;    more == window_size - lookahead - strstart
2211
		;    more == window_size - lookahead - strstart
2212
		; => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
2212
		; => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
2213
		; => more >= window_size - 2*WSIZE + 2
2213
		; => more >= window_size - 2*WSIZE + 2
2214
		; In the BIG_MEM or MMAP case (not yet supported),
2214
		; In the BIG_MEM or MMAP case (not yet supported),
2215
		;   window_size == input_size + MIN_LOOKAHEAD  &&
2215
		;   window_size == input_size + MIN_LOOKAHEAD  &&
2216
		;   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
2216
		;   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
2217
		; Otherwise, window_size == 2*WSIZE so more >= 2.
2217
		; Otherwise, window_size == 2*WSIZE so more >= 2.
2218
		; If there was sliding, more >= WSIZE. So in all cases, more >= 2.
2218
		; If there was sliding, more >= WSIZE. So in all cases, more >= 2.
2219
 
2219
 
2220
		cmp ebx,2
2220
		cmp ebx,2
2221
		jge @f
2221
		jge @f
2222
			zlib_assert 'more < 2' ;Assert(..>=..)
2222
			zlib_assert 'more < 2' ;Assert(..>=..)
2223
		@@:
2223
		@@:
2224
		mov eax,[edi+deflate_state.window]
2224
		mov eax,[edi+deflate_state.window]
2225
		add eax,[edi+deflate_state.strstart]
2225
		add eax,[edi+deflate_state.strstart]
2226
		add eax,[edi+deflate_state.lookahead]
2226
		add eax,[edi+deflate_state.lookahead]
2227
		stdcall read_buf, edx, eax, ebx
2227
		stdcall read_buf, edx, eax, ebx
2228
		add [edi+deflate_state.lookahead],eax
2228
		add [edi+deflate_state.lookahead],eax
2229
 
2229
 
2230
		; Initialize the hash value now that we have some input:
2230
		; Initialize the hash value now that we have some input:
2231
		mov eax,[edi+deflate_state.lookahead]
2231
		mov eax,[edi+deflate_state.lookahead]
2232
		add eax,[edi+deflate_state.insert]
2232
		add eax,[edi+deflate_state.insert]
2233
		cmp eax,MIN_MATCH
2233
		cmp eax,MIN_MATCH
2234
		jl .end1 ;if (..>=..)
2234
		jl .end1 ;if (..>=..)
2235
			mov esi,[edi+deflate_state.strstart]
2235
			mov esi,[edi+deflate_state.strstart]
2236
			sub esi,[edi+deflate_state.insert]
2236
			sub esi,[edi+deflate_state.insert]
2237
			;esi = str
2237
			;esi = str
2238
			mov eax,[edi+deflate_state.window]
2238
			mov eax,[edi+deflate_state.window]
2239
			add eax,esi
2239
			add eax,esi
2240
			mov [edi+deflate_state.ins_h],eax
2240
			mov [edi+deflate_state.ins_h],eax
2241
			inc eax
2241
			inc eax
2242
			movzx eax,byte[eax]
2242
			movzx eax,byte[eax]
2243
            UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2243
            UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2244
if MIN_MATCH <> 3
2244
if MIN_MATCH <> 3
2245
;            Call UPDATE_HASH() MIN_MATCH-3 more times
2245
;            Call UPDATE_HASH() MIN_MATCH-3 more times
2246
end if
2246
end if
2247
			.cycle3: ;while (..)
2247
			.cycle3: ;while (..)
2248
			cmp dword[edi+deflate_state.insert],0
2248
			cmp dword[edi+deflate_state.insert],0
2249
			je .end1
2249
			je .end1
2250
				mov eax,esi
2250
				mov eax,esi
2251
				add eax,MIN_MATCH-1
2251
				add eax,MIN_MATCH-1
2252
				add eax,[edi+deflate_state.window]
2252
				add eax,[edi+deflate_state.window]
2253
				movzx eax,byte[eax]
2253
				movzx eax,byte[eax]
2254
				UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2254
				UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2255
if FASTEST eq 0
2255
if FASTEST eq 0
2256
				mov eax,[edi+deflate_state.ins_h]
2256
				mov eax,[edi+deflate_state.ins_h]
2257
				shl eax,2
2257
				shl eax,2
2258
				add eax,[edi+deflate_state.head]
2258
				add eax,[edi+deflate_state.head]
2259
				push ebx
2259
				push ebx
2260
				mov ebx,[edi+deflate_state.w_mask]
2260
				mov ebx,[edi+deflate_state.w_mask]
2261
				and ebx,esi
2261
				and ebx,esi
2262
				shl ebx,2
2262
				shl ebx,2
2263
				add ebx,[edi+deflate_state.prev]
2263
				add ebx,[edi+deflate_state.prev]
2264
				mov eax,[eax]
2264
				mov eax,[eax]
2265
				mov [ebx],eax
2265
				mov [ebx],eax
2266
				pop ebx
2266
				pop ebx
2267
end if
2267
end if
2268
				mov eax,[edi+deflate_state.ins_h]
2268
				mov eax,[edi+deflate_state.ins_h]
2269
				shl eax,2
2269
				shl eax,2
2270
				add eax,[edi+deflate_state.head]
2270
				add eax,[edi+deflate_state.head]
2271
				mov [eax],esi
2271
				mov [eax],esi
2272
				inc esi
2272
				inc esi
2273
				dec dword[edi+deflate_state.insert]
2273
				dec dword[edi+deflate_state.insert]
2274
				mov eax,[edi+deflate_state.lookahead]
2274
				mov eax,[edi+deflate_state.lookahead]
2275
				add eax,[edi+deflate_state.insert]
2275
				add eax,[edi+deflate_state.insert]
2276
				cmp eax,MIN_MATCH
2276
				cmp eax,MIN_MATCH
2277
				jl .end1 ;if (..<..) break
2277
				jl .end1 ;if (..<..) break
2278
			jmp .cycle3
2278
			jmp .cycle3
2279
		.end1:
2279
		.end1:
2280
		; If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
2280
		; If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
2281
		; but this is not important since only literal bytes will be emitted.
2281
		; but this is not important since only literal bytes will be emitted.
2282
 
2282
 
2283
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2283
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2284
		jge .cycle0end
2284
		jge .cycle0end
2285
		cmp dword[edx+z_stream.avail_in],0
2285
		cmp dword[edx+z_stream.avail_in],0
2286
		jne .cycle0
2286
		jne .cycle0
2287
align 4
2287
align 4
2288
	.cycle0end: ;while (..<.. && ..!=..)
2288
	.cycle0end: ;while (..<.. && ..!=..)
2289
 
2289
 
2290
	; If the WIN_INIT bytes after the end of the current data have never been
2290
	; If the WIN_INIT bytes after the end of the current data have never been
2291
	; written, then zero those bytes in order to avoid memory check reports of
2291
	; written, then zero those bytes in order to avoid memory check reports of
2292
	; the use of uninitialized (or uninitialised as Julian writes) bytes by
2292
	; the use of uninitialized (or uninitialised as Julian writes) bytes by
2293
	; the longest match routines.  Update the high water mark for the next
2293
	; the longest match routines.  Update the high water mark for the next
2294
	; time through here.  WIN_INIT is set to MAX_MATCH since the longest match
2294
	; time through here.  WIN_INIT is set to MAX_MATCH since the longest match
2295
	; routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
2295
	; routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
2296
 
2296
 
2297
	mov eax,[edi+deflate_state.window_size]
2297
	mov eax,[edi+deflate_state.window_size]
2298
	cmp [edi+deflate_state.high_water],eax
2298
	cmp [edi+deflate_state.high_water],eax
2299
	jge .end2 ;if (..<..)
2299
	jge .end2 ;if (..<..)
2300
		mov esi,[edi+deflate_state.lookahead]
2300
		mov esi,[edi+deflate_state.lookahead]
2301
		add esi,[edi+deflate_state.strstart]
2301
		add esi,[edi+deflate_state.strstart]
2302
		;esi = curr
2302
		;esi = curr
2303
 
2303
 
2304
		cmp [edi+deflate_state.high_water],esi
2304
		cmp [edi+deflate_state.high_water],esi
2305
		jge .end3 ;if (..<..)
2305
		jge .end3 ;if (..<..)
2306
			; Previous high water mark below current data -- zero WIN_INIT
2306
			; Previous high water mark below current data -- zero WIN_INIT
2307
			; bytes or up to end of window, whichever is less.
2307
			; bytes or up to end of window, whichever is less.
2308
 
2308
 
2309
			mov eax,[edi+deflate_state.window_size]
2309
			mov eax,[edi+deflate_state.window_size]
2310
			sub eax,esi
2310
			sub eax,esi
2311
			cmp eax,WIN_INIT
2311
			cmp eax,WIN_INIT
2312
			jle @f ;if (..>..)
2312
			jle @f ;if (..>..)
2313
				mov eax,WIN_INIT
2313
				mov eax,WIN_INIT
2314
			@@:
2314
			@@:
2315
			mov edx,[edi+deflate_state.window]
2315
			mov edx,[edi+deflate_state.window]
2316
			add edx,esi
2316
			add edx,esi
2317
			stdcall zmemzero, edx, eax
2317
			stdcall zmemzero, edx, eax
2318
			add eax,esi
2318
			add eax,esi
2319
			mov [edi+deflate_state.high_water],eax
2319
			mov [edi+deflate_state.high_water],eax
2320
			jmp .end2
2320
			jmp .end2
2321
		.end3: ;else if (..<..)
2321
		.end3: ;else if (..<..)
2322
		mov eax,esi
2322
		mov eax,esi
2323
		add eax,WIN_INIT
2323
		add eax,WIN_INIT
2324
		cmp [edi+deflate_state.high_water],eax
2324
		cmp [edi+deflate_state.high_water],eax
2325
		jge .end2
2325
		jge .end2
2326
			; High water mark at or above current data, but below current data
2326
			; High water mark at or above current data, but below current data
2327
			; plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
2327
			; plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
2328
			; to end of window, whichever is less.
2328
			; to end of window, whichever is less.
2329
 
2329
 
2330
			;eax = esi+WIN_INIT
2330
			;eax = esi+WIN_INIT
2331
			sub eax,[edi+deflate_state.high_water]
2331
			sub eax,[edi+deflate_state.high_water]
2332
			mov edx,[edi+deflate_state.window_size]
2332
			mov edx,[edi+deflate_state.window_size]
2333
			sub edx,[edi+deflate_state.high_water]
2333
			sub edx,[edi+deflate_state.high_water]
2334
			cmp eax,edx ;if (..>..)
2334
			cmp eax,edx ;if (..>..)
2335
			jle @f
2335
			jle @f
2336
				mov eax,edx
2336
				mov eax,edx
2337
			@@:
2337
			@@:
2338
			mov edx,[edi+deflate_state.window]
2338
			mov edx,[edi+deflate_state.window]
2339
			add edx,[edi+deflate_state.high_water]
2339
			add edx,[edi+deflate_state.high_water]
2340
			stdcall zmemzero, edx, eax
2340
			stdcall zmemzero, edx, eax
2341
			add [edi+deflate_state.high_water],eax
2341
			add [edi+deflate_state.high_water],eax
2342
	.end2:
2342
	.end2:
2343
 
2343
 
2344
	mov eax,[edi+deflate_state.window_size]
2344
	mov eax,[edi+deflate_state.window_size]
2345
	sub eax,MIN_LOOKAHEAD
2345
	sub eax,MIN_LOOKAHEAD
2346
	cmp [edi+deflate_state.strstart],eax
2346
	cmp [edi+deflate_state.strstart],eax
2347
	jle @f
2347
	jle @f
2348
		zlib_assert 'not enough room for search' ;Assert(..<=..)
2348
		zlib_assert 'not enough room for search' ;Assert(..<=..)
2349
	@@:
2349
	@@:
2350
popad
2350
popad
2351
	ret
2351
	ret
2352
endp
2352
endp
2353
 
2353
 
2354
; ===========================================================================
2354
; ===========================================================================
2355
; Flush the current block, with given end-of-file flag.
2355
; Flush the current block, with given end-of-file flag.
2356
; IN assertion: strstart is set to the end of the current match.
2356
; IN assertion: strstart is set to the end of the current match.
2357
 
2357
 
2358
macro FLUSH_BLOCK_ONLY s, last
2358
macro FLUSH_BLOCK_ONLY s, last
2359
{
2359
{
2360
local .end0
2360
local .end0
2361
	push dword last
2361
	push dword last
2362
	mov eax,[s+deflate_state.strstart]
2362
	mov eax,[s+deflate_state.strstart]
2363
	sub eax,[s+deflate_state.block_start]
2363
	sub eax,[s+deflate_state.block_start]
2364
	push eax
2364
	push eax
2365
	xor eax,eax
2365
	xor eax,eax
2366
	cmp dword[s+deflate_state.block_start],0
2366
	cmp dword[s+deflate_state.block_start],0
2367
	jl .end0
2367
	jl .end0
2368
		mov eax,[s+deflate_state.block_start]
2368
		mov eax,[s+deflate_state.block_start]
2369
		add eax,[s+deflate_state.window]
2369
		add eax,[s+deflate_state.window]
2370
	.end0:
2370
	.end0:
2371
	stdcall _tr_flush_block, s, eax
2371
	stdcall _tr_flush_block, s, eax
2372
	mov eax,[s+deflate_state.strstart]
2372
	mov eax,[s+deflate_state.strstart]
2373
	mov [s+deflate_state.block_start],eax
2373
	mov [s+deflate_state.block_start],eax
2374
	stdcall flush_pending, [s+deflate_state.strm]
2374
	stdcall flush_pending, [s+deflate_state.strm]
2375
;   Tracev((stderr,"[FLUSH]"));
2375
;   Tracev((stderr,"[FLUSH]"));
2376
}
2376
}
2377
 
2377
 
2378
; Same but force premature exit if necessary.
2378
; Same but force premature exit if necessary.
2379
macro FLUSH_BLOCK s, last
2379
macro FLUSH_BLOCK s, last
2380
{
2380
{
2381
local .end0
2381
local .end0
2382
	FLUSH_BLOCK_ONLY s, last
2382
	FLUSH_BLOCK_ONLY s, last
2383
	mov eax,[s+deflate_state.strm]
2383
	mov eax,[s+deflate_state.strm]
2384
	cmp dword[eax+z_stream.avail_out],0
2384
	cmp dword[eax+z_stream.avail_out],0
2385
	jne .end0 ;if (..==0)
2385
	jne .end0 ;if (..==0)
2386
if last eq 1
2386
if last eq 1
2387
		mov eax,finish_started
2387
		mov eax,finish_started
2388
else
2388
else
2389
		mov eax,need_more
2389
		mov eax,need_more
2390
end if
2390
end if
2391
		jmp .end_f
2391
		jmp .end_f
2392
	.end0:
2392
	.end0:
2393
}
2393
}
2394
 
2394
 
2395
; ===========================================================================
2395
; ===========================================================================
2396
; Copy without compression as much as possible from the input stream, return
2396
; Copy without compression as much as possible from the input stream, return
2397
; the current block state.
2397
; the current block state.
2398
; This function does not insert new strings in the dictionary since
2398
; This function does not insert new strings in the dictionary since
2399
; uncompressible data is probably not useful. This function is used
2399
; uncompressible data is probably not useful. This function is used
2400
; only for the level=0 compression option.
2400
; only for the level=0 compression option.
2401
; NOTE: this function should be optimized to avoid extra copying from
2401
; NOTE: this function should be optimized to avoid extra copying from
2402
; window to pending_buf.
2402
; window to pending_buf.
2403
 
2403
 
2404
;block_state (s, flush)
2404
;block_state (s, flush)
2405
;    deflate_state *s
2405
;    deflate_state *s
2406
;    int flush
2406
;    int flush
2407
align 4
2407
align 4
2408
proc deflate_stored uses ebx ecx edi, s:dword, flush:dword
2408
proc deflate_stored uses ebx ecx edi, s:dword, flush:dword
2409
; Stored blocks are limited to 0xffff bytes, pending_buf is limited
2409
; Stored blocks are limited to 0xffff bytes, pending_buf is limited
2410
; to pending_buf_size, and each stored block has a 5 byte header:
2410
; to pending_buf_size, and each stored block has a 5 byte header:
2411
	mov edi,[s]
2411
	mov edi,[s]
2412
	zlib_debug 'deflate_stored'
2412
	zlib_debug 'deflate_stored'
2413
 
2413
 
2414
	mov ecx,0xffff
2414
	mov ecx,0xffff
2415
	mov eax,[edi+deflate_state.pending_buf_size]
2415
	mov eax,[edi+deflate_state.pending_buf_size]
2416
	sub eax,5
2416
	sub eax,5
2417
	cmp ecx,eax
2417
	cmp ecx,eax
2418
	jle .cycle0 ;if (..>..)
2418
	jle .cycle0 ;if (..>..)
2419
		mov ecx,eax
2419
		mov ecx,eax
2420
	;ecx = max_block_size
2420
	;ecx = max_block_size
2421
 
2421
 
2422
	; Copy as much as possible from input to output:
2422
	; Copy as much as possible from input to output:
2423
align 4
2423
align 4
2424
	.cycle0: ;for (;;) {
2424
	.cycle0: ;for (;;) {
2425
		; Fill the window as much as possible:
2425
		; Fill the window as much as possible:
2426
		cmp dword[edi+deflate_state.lookahead],1
2426
		cmp dword[edi+deflate_state.lookahead],1
2427
		jg .end0 ;if (..<=..)
2427
		jg .end0 ;if (..<=..)
2428
;            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
2428
;            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
2429
;                   s->block_start >= (long)s->w_size, "slide too late");
2429
;                   s->block_start >= (long)s->w_size, "slide too late");
2430
 
2430
 
2431
			stdcall fill_window, edi
2431
			stdcall fill_window, edi
2432
			cmp dword[edi+deflate_state.lookahead],0
2432
			cmp dword[edi+deflate_state.lookahead],0
2433
			jne @f
2433
			jne @f
2434
			cmp dword[flush],Z_NO_FLUSH
2434
			cmp dword[flush],Z_NO_FLUSH
2435
			jne @f ;if (..==0 && ..==..)
2435
			jne @f ;if (..==0 && ..==..)
2436
				mov eax,need_more
2436
				mov eax,need_more
2437
				jmp .end_f
2437
				jmp .end_f
2438
			@@:
2438
			@@:
2439
			cmp dword[edi+deflate_state.lookahead],0
2439
			cmp dword[edi+deflate_state.lookahead],0
2440
			je .cycle0end ;if (..==0) break ;flush the current block
2440
			je .cycle0end ;if (..==0) break ;flush the current block
2441
		.end0:
2441
		.end0:
2442
		cmp dword[edi+deflate_state.block_start],0
2442
		cmp dword[edi+deflate_state.block_start],0
2443
		jge @f
2443
		jge @f
2444
			zlib_assert 'block gone' ;Assert(..>=0)
2444
			zlib_assert 'block gone' ;Assert(..>=0)
2445
		@@:
2445
		@@:
2446
 
2446
 
2447
		mov eax,[edi+deflate_state.lookahead]
2447
		mov eax,[edi+deflate_state.lookahead]
2448
		add [edi+deflate_state.strstart],eax
2448
		add [edi+deflate_state.strstart],eax
2449
		mov dword[edi+deflate_state.lookahead],0
2449
		mov dword[edi+deflate_state.lookahead],0
2450
 
2450
 
2451
		; Emit a stored block if pending_buf will be full:
2451
		; Emit a stored block if pending_buf will be full:
2452
		mov ebx,[edi+deflate_state.block_start]
2452
		mov ebx,[edi+deflate_state.block_start]
2453
		add ebx,ecx
2453
		add ebx,ecx
2454
		cmp dword[edi+deflate_state.strstart],0
2454
		cmp dword[edi+deflate_state.strstart],0
2455
		je @f
2455
		je @f
2456
		cmp [edi+deflate_state.strstart],ebx
2456
		cmp [edi+deflate_state.strstart],ebx
2457
		jl .end1
2457
		jl .end1
2458
		@@: ;if (..==0 || ..>=..)
2458
		@@: ;if (..==0 || ..>=..)
2459
			; strstart == 0 is possible when wraparound on 16-bit machine
2459
			; strstart == 0 is possible when wraparound on 16-bit machine
2460
			mov eax,[edi+deflate_state.strstart]
2460
			mov eax,[edi+deflate_state.strstart]
2461
			sub eax,ebx
2461
			sub eax,ebx
2462
			mov [edi+deflate_state.lookahead],eax
2462
			mov [edi+deflate_state.lookahead],eax
2463
			mov [edi+deflate_state.strstart],ebx
2463
			mov [edi+deflate_state.strstart],ebx
2464
			FLUSH_BLOCK edi, 0
2464
			FLUSH_BLOCK edi, 0
2465
		.end1:
2465
		.end1:
2466
		; Flush if we may have to slide, otherwise block_start may become
2466
		; Flush if we may have to slide, otherwise block_start may become
2467
		; negative and the data will be gone:
2467
		; negative and the data will be gone:
2468
 
2468
 
2469
		MAX_DIST edi
2469
		MAX_DIST edi
2470
		mov ebx,[edi+deflate_state.strstart]
2470
		mov ebx,[edi+deflate_state.strstart]
2471
		sub ebx,[edi+deflate_state.block_start]
2471
		sub ebx,[edi+deflate_state.block_start]
2472
		cmp ebx,eax
2472
		cmp ebx,eax
2473
		jl .cycle0 ;if (..>=..)
2473
		jl .cycle0 ;if (..>=..)
2474
			FLUSH_BLOCK edi, 0
2474
			FLUSH_BLOCK edi, 0
2475
		jmp .cycle0
2475
		jmp .cycle0
2476
align 4
2476
align 4
2477
	.cycle0end:
2477
	.cycle0end:
2478
	mov dword[edi+deflate_state.insert],0
2478
	mov dword[edi+deflate_state.insert],0
2479
	cmp dword[flush],Z_FINISH
2479
	cmp dword[flush],Z_FINISH
2480
	jne @f ;if (..==..)
2480
	jne @f ;if (..==..)
2481
		FLUSH_BLOCK edi, 1
2481
		FLUSH_BLOCK edi, 1
2482
		mov eax,finish_done
2482
		mov eax,finish_done
2483
		jmp .end_f
2483
		jmp .end_f
2484
	@@:
2484
	@@:
2485
	mov eax,[edi+deflate_state.block_start]
2485
	mov eax,[edi+deflate_state.block_start]
2486
	cmp [edi+deflate_state.strstart],eax
2486
	cmp [edi+deflate_state.strstart],eax
2487
	jle @f ;if (..>..)
2487
	jle @f ;if (..>..)
2488
		FLUSH_BLOCK edi, 0
2488
		FLUSH_BLOCK edi, 0
2489
	@@:
2489
	@@:
2490
	mov eax,block_done
2490
	mov eax,block_done
2491
.end_f:
2491
.end_f:
2492
	ret
2492
	ret
2493
endp
2493
endp
2494
 
2494
 
2495
; ===========================================================================
2495
; ===========================================================================
2496
; Compress as much as possible from the input stream, return the current
2496
; Compress as much as possible from the input stream, return the current
2497
; block state.
2497
; block state.
2498
; This function does not perform lazy evaluation of matches and inserts
2498
; This function does not perform lazy evaluation of matches and inserts
2499
; new strings in the dictionary only for unmatched strings or for short
2499
; new strings in the dictionary only for unmatched strings or for short
2500
; matches. It is used only for the fast compression options.
2500
; matches. It is used only for the fast compression options.
2501
 
2501
 
2502
;block_state (s, flush)
2502
;block_state (s, flush)
2503
;    deflate_state *s
2503
;    deflate_state *s
2504
;    int flush
2504
;    int flush
2505
align 4
2505
align 4
2506
proc deflate_fast uses ebx ecx edi, s:dword, flush:dword
2506
proc deflate_fast uses ebx ecx edi, s:dword, flush:dword
2507
locals
2507
locals
2508
	bflush dd ? ;int  ;set if current block must be flushed
2508
	bflush dd ? ;int  ;set if current block must be flushed
2509
endl
2509
endl
2510
;ecx = hash_head ;IPos ;head of the hash chain
2510
;ecx = hash_head ;IPos ;head of the hash chain
2511
	mov edi,[s]
2511
	mov edi,[s]
2512
	zlib_debug 'deflate_fast'
2512
	zlib_debug 'deflate_fast'
2513
 
2513
 
2514
	.cycle0: ;for (..)
2514
	.cycle0: ;for (..)
2515
	; Make sure that we always have enough lookahead, except
2515
	; Make sure that we always have enough lookahead, except
2516
	; at the end of the input file. We need MAX_MATCH bytes
2516
	; at the end of the input file. We need MAX_MATCH bytes
2517
	; for the next match, plus MIN_MATCH bytes to insert the
2517
	; for the next match, plus MIN_MATCH bytes to insert the
2518
	; string following the next match.
2518
	; string following the next match.
2519
 
2519
 
2520
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2520
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2521
		jge .end0 ;if (..<..)
2521
		jge .end0 ;if (..<..)
2522
			stdcall fill_window, edi
2522
			stdcall fill_window, edi
2523
			cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2523
			cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2524
			jge @f ;if (..<.. && ..==..)
2524
			jge @f ;if (..<.. && ..==..)
2525
			cmp dword[flush],Z_NO_FLUSH
2525
			cmp dword[flush],Z_NO_FLUSH
2526
			jne @f
2526
			jne @f
2527
				mov eax,need_more
2527
				mov eax,need_more
2528
				jmp .end_f
2528
				jmp .end_f
2529
align 4
2529
align 4
2530
			@@:
2530
			@@:
2531
			cmp dword[edi+deflate_state.lookahead],0
2531
			cmp dword[edi+deflate_state.lookahead],0
2532
			je .cycle0end ;if (..==0) break ;flush the current block
2532
			je .cycle0end ;if (..==0) break ;flush the current block
2533
align 4
2533
align 4
2534
		.end0:
2534
		.end0:
2535
 
2535
 
2536
		; Insert the string window[strstart .. strstart+2] in the
2536
		; Insert the string window[strstart .. strstart+2] in the
2537
		; dictionary, and set hash_head to the head of the hash chain:
2537
		; dictionary, and set hash_head to the head of the hash chain:
2538
 
2538
 
2539
		mov ecx,NIL
2539
		mov ecx,NIL
2540
		cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2540
		cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2541
		jl @f ;if (..>=..)
2541
		jl @f ;if (..>=..)
2542
			INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2542
			INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2543
		@@:
2543
		@@:
2544
 
2544
 
2545
		; Find the longest match, discarding those <= prev_length.
2545
		; Find the longest match, discarding those <= prev_length.
2546
		; At this point we have always match_length < MIN_MATCH
2546
		; At this point we have always match_length < MIN_MATCH
2547
 
2547
 
2548
		cmp ecx,NIL
2548
		cmp ecx,NIL
2549
		je @f
2549
		je @f
2550
		MAX_DIST edi
2550
		MAX_DIST edi
2551
		mov ebx,[edi+deflate_state.strstart]
2551
		mov ebx,[edi+deflate_state.strstart]
2552
		sub ebx,ecx
2552
		sub ebx,ecx
2553
		cmp ebx,eax
2553
		cmp ebx,eax
2554
		jg @f ;if (..!=0 && ..<=..)
2554
		jg @f ;if (..!=0 && ..<=..)
2555
			; To simplify the code, we prevent matches with the string
2555
			; To simplify the code, we prevent matches with the string
2556
			; of window index 0 (in particular we have to avoid a match
2556
			; of window index 0 (in particular we have to avoid a match
2557
			; of the string with itself at the start of the input file).
2557
			; of the string with itself at the start of the input file).
2558
 
2558
 
2559
			stdcall longest_match, edi, ecx
2559
			stdcall longest_match, edi, ecx
2560
			mov [edi+deflate_state.match_length],eax
2560
			mov [edi+deflate_state.match_length],eax
2561
			; longest_match() sets match_start
2561
			; longest_match() sets match_start
2562
		@@:
2562
		@@:
2563
		cmp dword[edi+deflate_state.match_length],MIN_MATCH
2563
		cmp dword[edi+deflate_state.match_length],MIN_MATCH
2564
		jl .end1 ;if (..>=..)
2564
		jl .end1 ;if (..>=..)
2565
			stdcall check_match, edi, [edi+deflate_state.strstart], [edi+deflate_state.match_start], [edi+deflate_state.match_length]
2565
			stdcall check_match, edi, [edi+deflate_state.strstart], [edi+deflate_state.match_start], [edi+deflate_state.match_length]
2566
 
2566
 
2567
			mov eax,[edi+deflate_state.strstart]
2567
			mov eax,[edi+deflate_state.strstart]
2568
			sub eax,[edi+deflate_state.match_start]
2568
			sub eax,[edi+deflate_state.match_start]
2569
			mov ebx,[edi+deflate_state.match_length]
2569
			mov ebx,[edi+deflate_state.match_length]
2570
			sub ebx,MIN_MATCH
2570
			sub ebx,MIN_MATCH
2571
			_tr_tally_dist edi, eax, ebx, [bflush]
2571
			_tr_tally_dist edi, eax, ebx, [bflush]
2572
 
2572
 
2573
			mov eax,[edi+deflate_state.match_length]
2573
			mov eax,[edi+deflate_state.match_length]
2574
			sub [edi+deflate_state.lookahead],eax
2574
			sub [edi+deflate_state.lookahead],eax
2575
 
2575
 
2576
			; Insert new strings in the hash table only if the match length
2576
			; Insert new strings in the hash table only if the match length
2577
			; is not too large. This saves time but degrades compression.
2577
			; is not too large. This saves time but degrades compression.
2578
 
2578
 
2579
if FASTEST eq 0
2579
if FASTEST eq 0
2580
			;;mov eax,[edi+deflate_state.match_length]
2580
			;;mov eax,[edi+deflate_state.match_length]
2581
			cmp eax,[edi+deflate_state.max_insert_length]
2581
			cmp eax,[edi+deflate_state.max_insert_length]
2582
			jg .end3
2582
			jg .end3
2583
			cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2583
			cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2584
			jl .end3 ;if (..<=.. && ..>=..)
2584
			jl .end3 ;if (..<=.. && ..>=..)
2585
				dec dword[edi+deflate_state.match_length] ;string at strstart already in table
2585
				dec dword[edi+deflate_state.match_length] ;string at strstart already in table
2586
				.cycle1: ;do {
2586
				.cycle1: ;do {
2587
					inc dword[edi+deflate_state.strstart]
2587
					inc dword[edi+deflate_state.strstart]
2588
					INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2588
					INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2589
					; strstart never exceeds WSIZE-MAX_MATCH, so there are
2589
					; strstart never exceeds WSIZE-MAX_MATCH, so there are
2590
					; always MIN_MATCH bytes ahead.
2590
					; always MIN_MATCH bytes ahead.
2591
 
2591
 
2592
					dec dword[edi+deflate_state.match_length]
2592
					dec dword[edi+deflate_state.match_length]
2593
					cmp dword[edi+deflate_state.match_length],0
2593
					cmp dword[edi+deflate_state.match_length],0
2594
					jne .cycle1 ;while (..!=0)
2594
					jne .cycle1 ;while (..!=0)
2595
				inc dword[edi+deflate_state.strstart]
2595
				inc dword[edi+deflate_state.strstart]
2596
				jmp .end2
2596
				jmp .end2
2597
			.end3: ;else
2597
			.end3: ;else
2598
end if
2598
end if
2599
 
2599
 
2600
				mov eax,[edi+deflate_state.match_length]
2600
				mov eax,[edi+deflate_state.match_length]
2601
				add [edi+deflate_state.strstart],eax
2601
				add [edi+deflate_state.strstart],eax
2602
				mov dword[edi+deflate_state.match_length],0
2602
				mov dword[edi+deflate_state.match_length],0
2603
				mov eax,[edi+deflate_state.window]
2603
				mov eax,[edi+deflate_state.window]
2604
				add eax,[edi+deflate_state.strstart]
2604
				add eax,[edi+deflate_state.strstart]
2605
				mov [edi+deflate_state.ins_h],eax
2605
				mov [edi+deflate_state.ins_h],eax
2606
				inc eax
2606
				inc eax
2607
				movzx eax,byte[eax]
2607
				movzx eax,byte[eax]
2608
				UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2608
				UPDATE_HASH edi, [edi+deflate_state.ins_h], eax
2609
if MIN_MATCH <> 3
2609
if MIN_MATCH <> 3
2610
;                Call UPDATE_HASH() MIN_MATCH-3 more times
2610
;                Call UPDATE_HASH() MIN_MATCH-3 more times
2611
end if
2611
end if
2612
				; If lookahead < MIN_MATCH, ins_h is garbage, but it does not
2612
				; If lookahead < MIN_MATCH, ins_h is garbage, but it does not
2613
				; matter since it will be recomputed at next deflate call.
2613
				; matter since it will be recomputed at next deflate call.
2614
			jmp .end2
2614
			jmp .end2
2615
		.end1: ;else
2615
		.end1: ;else
2616
			; No match, output a literal byte
2616
			; No match, output a literal byte
2617
			mov eax,[edi+deflate_state.window]
2617
			mov eax,[edi+deflate_state.window]
2618
			add eax,[edi+deflate_state.strstart]
2618
			add eax,[edi+deflate_state.strstart]
2619
			movzx eax,byte[eax]
2619
			movzx eax,byte[eax]
2620
			Tracevv eax,
2620
			Tracevv eax,
2621
			_tr_tally_lit edi, eax, [bflush]
2621
			_tr_tally_lit edi, eax, [bflush]
2622
			dec dword[edi+deflate_state.lookahead]
2622
			dec dword[edi+deflate_state.lookahead]
2623
			inc dword[edi+deflate_state.strstart]
2623
			inc dword[edi+deflate_state.strstart]
2624
		.end2:
2624
		.end2:
2625
		cmp dword[bflush],0
2625
		cmp dword[bflush],0
2626
		je .cycle0 ;if (..)
2626
		je .cycle0 ;if (..)
2627
			FLUSH_BLOCK edi, 0
2627
			FLUSH_BLOCK edi, 0
2628
		jmp .cycle0
2628
		jmp .cycle0
2629
align 4
2629
align 4
2630
	.cycle0end:
2630
	.cycle0end:
2631
	mov eax,[edi+deflate_state.strstart]
2631
	mov eax,[edi+deflate_state.strstart]
2632
	cmp eax,MIN_MATCH-1
2632
	cmp eax,MIN_MATCH-1
2633
	jl @f
2633
	jl @f
2634
		mov eax,MIN_MATCH-1
2634
		mov eax,MIN_MATCH-1
2635
	@@:
2635
	@@:
2636
	mov [edi+deflate_state.insert],eax
2636
	mov [edi+deflate_state.insert],eax
2637
	cmp dword[flush],Z_FINISH
2637
	cmp dword[flush],Z_FINISH
2638
	jne @f ;if (..==..)
2638
	jne @f ;if (..==..)
2639
		FLUSH_BLOCK edi, 1
2639
		FLUSH_BLOCK edi, 1
2640
		mov eax,finish_done
2640
		mov eax,finish_done
2641
		jmp .end_f
2641
		jmp .end_f
2642
	@@:
2642
	@@:
2643
	cmp dword[edi+deflate_state.last_lit],0
2643
	cmp dword[edi+deflate_state.last_lit],0
2644
	je @f ;if (..)
2644
	je @f ;if (..)
2645
		FLUSH_BLOCK edi, 0
2645
		FLUSH_BLOCK edi, 0
2646
	@@:
2646
	@@:
2647
	mov eax,block_done
2647
	mov eax,block_done
2648
.end_f:
2648
.end_f:
2649
	ret
2649
	ret
2650
endp
2650
endp
2651
 
2651
 
2652
; ===========================================================================
2652
; ===========================================================================
2653
; Same as above, but achieves better compression. We use a lazy
2653
; Same as above, but achieves better compression. We use a lazy
2654
; evaluation for matches: a match is finally adopted only if there is
2654
; evaluation for matches: a match is finally adopted only if there is
2655
; no better match at the next window position.
2655
; no better match at the next window position.
2656
 
2656
 
2657
;block_state (s, flush)
2657
;block_state (s, flush)
2658
;    deflate_state *s
2658
;    deflate_state *s
2659
;    int flush
2659
;    int flush
2660
align 4
2660
align 4
2661
proc deflate_slow uses ebx ecx edx edi, s:dword, flush:dword
2661
proc deflate_slow uses ebx ecx edx edi, s:dword, flush:dword
2662
locals
2662
locals
2663
	bflush dd ? ;int  ;set if current block must be flushed
2663
	bflush dd ? ;int  ;set if current block must be flushed
2664
endl
2664
endl
2665
;ecx = hash_head ;IPos ;head of the hash chain
2665
;ecx = hash_head ;IPos ;head of the hash chain
2666
	mov edi,[s]
2666
	mov edi,[s]
2667
	zlib_debug 'deflate_slow'
2667
	zlib_debug 'deflate_slow'
2668
 
2668
 
2669
	; Process the input block.
2669
	; Process the input block.
2670
	.cycle0: ;for (;;)
2670
	.cycle0: ;for (;;)
2671
	; Make sure that we always have enough lookahead, except
2671
	; Make sure that we always have enough lookahead, except
2672
	; at the end of the input file. We need MAX_MATCH bytes
2672
	; at the end of the input file. We need MAX_MATCH bytes
2673
	; for the next match, plus MIN_MATCH bytes to insert the
2673
	; for the next match, plus MIN_MATCH bytes to insert the
2674
	; string following the next match.
2674
	; string following the next match.
2675
 
2675
 
2676
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2676
		cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2677
		jge .end0 ;if (..<..)
2677
		jge .end0 ;if (..<..)
2678
			stdcall fill_window, edi
2678
			stdcall fill_window, edi
2679
			cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2679
			cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
2680
			jge @f ;if (..<.. && ..==..)
2680
			jge @f ;if (..<.. && ..==..)
2681
			cmp dword[flush],Z_NO_FLUSH
2681
			cmp dword[flush],Z_NO_FLUSH
2682
			jne @f
2682
			jne @f
2683
				mov eax,need_more
2683
				mov eax,need_more
2684
				jmp .end_f
2684
				jmp .end_f
2685
align 4
2685
align 4
2686
			@@:
2686
			@@:
2687
			cmp dword[edi+deflate_state.lookahead],0
2687
			cmp dword[edi+deflate_state.lookahead],0
2688
			je .cycle0end ;if (..==0) break ;flush the current block
2688
			je .cycle0end ;if (..==0) break ;flush the current block
2689
align 4
2689
align 4
2690
		.end0:
2690
		.end0:
2691
 
2691
 
2692
		; Insert the string window[strstart .. strstart+2] in the
2692
		; Insert the string window[strstart .. strstart+2] in the
2693
		; dictionary, and set hash_head to the head of the hash chain:
2693
		; dictionary, and set hash_head to the head of the hash chain:
2694
 
2694
 
2695
		mov ecx,NIL
2695
		mov ecx,NIL
2696
		cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2696
		cmp dword[edi+deflate_state.lookahead],MIN_MATCH
2697
		jl @f ;if (..>=..)
2697
		jl @f ;if (..>=..)
2698
			INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2698
			INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2699
		@@:
2699
		@@:
2700
 
2700
 
2701
		; Find the longest match, discarding those <= prev_length.
2701
		; Find the longest match, discarding those <= prev_length.
2702
 
2702
 
2703
		mov eax,[edi+deflate_state.match_length]
2703
		mov eax,[edi+deflate_state.match_length]
2704
		mov [edi+deflate_state.prev_length],eax
2704
		mov [edi+deflate_state.prev_length],eax
2705
		mov eax,[edi+deflate_state.match_start]
2705
		mov eax,[edi+deflate_state.match_start]
2706
		mov [edi+deflate_state.prev_match],eax
2706
		mov [edi+deflate_state.prev_match],eax
2707
		mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2707
		mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2708
 
2708
 
2709
		cmp ecx,NIL
2709
		cmp ecx,NIL
2710
		je .end1
2710
		je .end1
2711
		mov eax,[edi+deflate_state.prev_length]
2711
		mov eax,[edi+deflate_state.prev_length]
2712
		cmp eax,[edi+deflate_state.max_lazy_match]
2712
		cmp eax,[edi+deflate_state.max_lazy_match]
2713
		jge .end1
2713
		jge .end1
2714
		MAX_DIST edi
2714
		MAX_DIST edi
2715
		mov ebx,[edi+deflate_state.strstart]
2715
		mov ebx,[edi+deflate_state.strstart]
2716
		sub ebx,ecx
2716
		sub ebx,ecx
2717
		cmp ebx,eax
2717
		cmp ebx,eax
2718
		jg .end1 ;if (..!=0 && ..<.. && ..<=..)
2718
		jg .end1 ;if (..!=0 && ..<.. && ..<=..)
2719
			; To simplify the code, we prevent matches with the string
2719
			; To simplify the code, we prevent matches with the string
2720
			; of window index 0 (in particular we have to avoid a match
2720
			; of window index 0 (in particular we have to avoid a match
2721
			; of the string with itself at the start of the input file).
2721
			; of the string with itself at the start of the input file).
2722
 
2722
 
2723
			stdcall longest_match, edi, ecx
2723
			stdcall longest_match, edi, ecx
2724
			mov [edi+deflate_state.match_length],eax
2724
			mov [edi+deflate_state.match_length],eax
2725
			; longest_match() sets match_start
2725
			; longest_match() sets match_start
2726
 
2726
 
2727
			cmp dword[edi+deflate_state.match_length],5
2727
			cmp dword[edi+deflate_state.match_length],5
2728
			jg .end1
2728
			jg .end1
2729
			cmp word[edi+deflate_state.strategy],Z_FILTERED
2729
			cmp word[edi+deflate_state.strategy],Z_FILTERED
2730
if TOO_FAR <= 32767
2730
if TOO_FAR <= 32767
2731
			je @f
2731
			je @f
2732
				cmp dword[edi+deflate_state.match_length],MIN_MATCH
2732
				cmp dword[edi+deflate_state.match_length],MIN_MATCH
2733
				jne .end1
2733
				jne .end1
2734
				mov eax,[edi+deflate_state.strstart]
2734
				mov eax,[edi+deflate_state.strstart]
2735
				sub eax,[edi+deflate_state.match_start]
2735
				sub eax,[edi+deflate_state.match_start]
2736
				cmp eax,TOO_FAR
2736
				cmp eax,TOO_FAR
2737
				jle .end1 ;if (..<=.. && (..==.. || (..==.. && ..>..)))
2737
				jle .end1 ;if (..<=.. && (..==.. || (..==.. && ..>..)))
2738
			@@:
2738
			@@:
2739
else
2739
else
2740
			jne .end1 ;if (..<=.. && ..==..)
2740
			jne .end1 ;if (..<=.. && ..==..)
2741
end if
2741
end if
2742
				; If prev_match is also MIN_MATCH, match_start is garbage
2742
				; If prev_match is also MIN_MATCH, match_start is garbage
2743
				; but we will ignore the current match anyway.
2743
				; but we will ignore the current match anyway.
2744
 
2744
 
2745
				mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2745
				mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2746
		.end1:
2746
		.end1:
2747
		; If there was a match at the previous step and the current
2747
		; If there was a match at the previous step and the current
2748
		; match is not better, output the previous match:
2748
		; match is not better, output the previous match:
2749
 
2749
 
2750
 
2750
 
2751
		mov eax,[edi+deflate_state.prev_length]
2751
		mov eax,[edi+deflate_state.prev_length]
2752
		cmp eax,MIN_MATCH
2752
		cmp eax,MIN_MATCH
2753
		jl .end2
2753
		jl .end2
2754
		cmp [edi+deflate_state.match_length],eax
2754
		cmp [edi+deflate_state.match_length],eax
2755
		jg .end2 ;if (..>=.. && ..<=..)
2755
		jg .end2 ;if (..>=.. && ..<=..)
2756
			mov edx,[edi+deflate_state.strstart]
2756
			mov edx,[edi+deflate_state.strstart]
2757
			add edx,[edi+deflate_state.lookahead]
2757
			add edx,[edi+deflate_state.lookahead]
2758
			sub edx,MIN_MATCH
2758
			sub edx,MIN_MATCH
2759
			;edx = max_insert
2759
			;edx = max_insert
2760
			; Do not insert strings in hash table beyond this.
2760
			; Do not insert strings in hash table beyond this.
2761
 
2761
 
2762
			mov eax,[edi+deflate_state.strstart]
2762
			mov eax,[edi+deflate_state.strstart]
2763
			dec eax
2763
			dec eax
2764
			stdcall check_match, edi, eax, [edi+deflate_state.prev_match], [edi+deflate_state.prev_length]
2764
			stdcall check_match, edi, eax, [edi+deflate_state.prev_match], [edi+deflate_state.prev_length]
2765
 
2765
 
2766
			mov eax,[edi+deflate_state.strstart]
2766
			mov eax,[edi+deflate_state.strstart]
2767
			dec eax
2767
			dec eax
2768
			sub eax,[edi+deflate_state.prev_match]
2768
			sub eax,[edi+deflate_state.prev_match]
2769
			mov ebx,[edi+deflate_state.prev_length]
2769
			mov ebx,[edi+deflate_state.prev_length]
2770
			sub ebx,MIN_MATCH
2770
			sub ebx,MIN_MATCH
2771
			_tr_tally_dist edi, eax, ebx, [bflush]
2771
			_tr_tally_dist edi, eax, ebx, [bflush]
2772
 
2772
 
2773
			; Insert in hash table all strings up to the end of the match.
2773
			; Insert in hash table all strings up to the end of the match.
2774
			; strstart-1 and strstart are already inserted. If there is not
2774
			; strstart-1 and strstart are already inserted. If there is not
2775
			; enough lookahead, the last two strings are not inserted in
2775
			; enough lookahead, the last two strings are not inserted in
2776
			; the hash table.
2776
			; the hash table.
2777
 
2777
 
2778
			mov eax,[edi+deflate_state.prev_length]
2778
			mov eax,[edi+deflate_state.prev_length]
2779
			dec eax
2779
			dec eax
2780
			sub [edi+deflate_state.lookahead],eax
2780
			sub [edi+deflate_state.lookahead],eax
2781
			sub dword[edi+deflate_state.prev_length],2
2781
			sub dword[edi+deflate_state.prev_length],2
2782
			.cycle1: ;do
2782
			.cycle1: ;do
2783
				inc dword[edi+deflate_state.strstart]
2783
				inc dword[edi+deflate_state.strstart]
2784
				cmp [edi+deflate_state.strstart],edx
2784
				cmp [edi+deflate_state.strstart],edx
2785
				jg @f ;if (..<=..)
2785
				jg @f ;if (..<=..)
2786
					INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2786
					INSERT_STRING edi, [edi+deflate_state.strstart], ecx
2787
				@@:
2787
				@@:
2788
				dec dword[edi+deflate_state.prev_length]
2788
				dec dword[edi+deflate_state.prev_length]
2789
				cmp dword[edi+deflate_state.prev_length],0
2789
				cmp dword[edi+deflate_state.prev_length],0
2790
				jne .cycle1 ;while (..!=0)
2790
				jne .cycle1 ;while (..!=0)
2791
			mov dword[edi+deflate_state.match_available],0
2791
			mov dword[edi+deflate_state.match_available],0
2792
			mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2792
			mov dword[edi+deflate_state.match_length],MIN_MATCH-1
2793
			inc dword[edi+deflate_state.strstart]
2793
			inc dword[edi+deflate_state.strstart]
2794
 
2794
 
2795
			cmp dword[bflush],0
2795
			cmp dword[bflush],0
2796
			je .cycle0 ;if (..)
2796
			je .cycle0 ;if (..)
2797
				FLUSH_BLOCK edi, 0
2797
				FLUSH_BLOCK edi, 0
2798
			jmp .cycle0
2798
			jmp .cycle0
2799
		.end2: ;else if (..)
2799
		.end2: ;else if (..)
2800
		cmp dword[edi+deflate_state.match_available],0
2800
		cmp dword[edi+deflate_state.match_available],0
2801
		je .end3
2801
		je .end3
2802
			; If there was no match at the previous position, output a
2802
			; If there was no match at the previous position, output a
2803
			; single literal. If there was a match but the current match
2803
			; single literal. If there was a match but the current match
2804
			; is longer, truncate the previous match to a single literal.
2804
			; is longer, truncate the previous match to a single literal.
2805
 
2805
 
2806
			mov eax,[edi+deflate_state.strstart]
2806
			mov eax,[edi+deflate_state.strstart]
2807
			dec eax
2807
			dec eax
2808
			add eax,[edi+deflate_state.window]
2808
			add eax,[edi+deflate_state.window]
2809
			movzx eax,byte[eax]
2809
			movzx eax,byte[eax]
2810
			Tracevv eax,
2810
			Tracevv eax,
2811
			_tr_tally_lit edi, eax, [bflush]
2811
			_tr_tally_lit edi, eax, [bflush]
2812
			cmp dword[bflush],0
2812
			cmp dword[bflush],0
2813
			je @f ;if (..)
2813
			je @f ;if (..)
2814
				FLUSH_BLOCK_ONLY edi, 0
2814
				FLUSH_BLOCK_ONLY edi, 0
2815
			@@:
2815
			@@:
2816
			inc dword[edi+deflate_state.strstart]
2816
			inc dword[edi+deflate_state.strstart]
2817
			dec dword[edi+deflate_state.lookahead]
2817
			dec dword[edi+deflate_state.lookahead]
2818
			mov eax,[edi+deflate_state.strm]
2818
			mov eax,[edi+deflate_state.strm]
2819
			cmp dword[eax+z_stream.avail_out],0
2819
			cmp dword[eax+z_stream.avail_out],0
2820
			jne .cycle0 ;if (..==0) return ..
2820
			jne .cycle0 ;if (..==0) return ..
2821
				mov eax,need_more
2821
				mov eax,need_more
2822
				jmp .end_f
2822
				jmp .end_f
2823
			jmp .cycle0 ;.end4
2823
			jmp .cycle0 ;.end4
2824
		.end3: ;else
2824
		.end3: ;else
2825
			; There is no previous match to compare with, wait for
2825
			; There is no previous match to compare with, wait for
2826
			; the next step to decide.
2826
			; the next step to decide.
2827
 
2827
 
2828
			mov dword[edi+deflate_state.match_available],1
2828
			mov dword[edi+deflate_state.match_available],1
2829
			inc dword[edi+deflate_state.strstart]
2829
			inc dword[edi+deflate_state.strstart]
2830
			dec dword[edi+deflate_state.lookahead]
2830
			dec dword[edi+deflate_state.lookahead]
2831
		;.end4:
2831
		;.end4:
2832
		jmp .cycle0
2832
		jmp .cycle0
2833
align 4
2833
align 4
2834
	.cycle0end:
2834
	.cycle0end:
2835
	cmp dword[flush],Z_NO_FLUSH
2835
	cmp dword[flush],Z_NO_FLUSH
2836
	jne @f
2836
	jne @f
2837
		zlib_assert 'no flush?' ;Assert (..!=..)
2837
		zlib_assert 'no flush?' ;Assert (..!=..)
2838
	@@:
2838
	@@:
2839
	cmp dword[edi+deflate_state.match_available],0
2839
	cmp dword[edi+deflate_state.match_available],0
2840
	je @f ;if (..)
2840
	je @f ;if (..)
2841
		mov eax,[edi+deflate_state.strstart]
2841
		mov eax,[edi+deflate_state.strstart]
2842
		dec eax
2842
		dec eax
2843
		add eax,[edi+deflate_state.window]
2843
		add eax,[edi+deflate_state.window]
2844
		movzx eax,byte[eax]
2844
		movzx eax,byte[eax]
2845
		Tracevv eax,
2845
		Tracevv eax,
2846
		_tr_tally_lit edi, eax, [bflush]
2846
		_tr_tally_lit edi, eax, [bflush]
2847
		mov dword[edi+deflate_state.match_available],0
2847
		mov dword[edi+deflate_state.match_available],0
2848
	@@:
2848
	@@:
2849
	mov eax,[edi+deflate_state.strstart]
2849
	mov eax,[edi+deflate_state.strstart]
2850
	cmp eax,MIN_MATCH-1
2850
	cmp eax,MIN_MATCH-1
2851
	jl @f
2851
	jl @f
2852
		mov eax,MIN_MATCH-1
2852
		mov eax,MIN_MATCH-1
2853
	@@:
2853
	@@:
2854
	mov [edi+deflate_state.insert],eax
2854
	mov [edi+deflate_state.insert],eax
2855
	cmp dword[flush],Z_FINISH
2855
	cmp dword[flush],Z_FINISH
2856
	jne @f ;if (..==..)
2856
	jne @f ;if (..==..)
2857
		FLUSH_BLOCK edi, 1
2857
		FLUSH_BLOCK edi, 1
2858
		mov eax,finish_done
2858
		mov eax,finish_done
2859
		jmp .end_f
2859
		jmp .end_f
2860
	@@:
2860
	@@:
2861
	cmp dword[edi+deflate_state.last_lit],0
2861
	cmp dword[edi+deflate_state.last_lit],0
2862
	je @f ;if (..)
2862
	je @f ;if (..)
2863
		FLUSH_BLOCK edi, 0
2863
		FLUSH_BLOCK edi, 0
2864
	@@:
2864
	@@:
2865
	mov eax,block_done
2865
	mov eax,block_done
2866
.end_f:
2866
.end_f:
2867
	ret
2867
	ret
2868
endp
2868
endp
2869
 
2869
 
2870
; ===========================================================================
2870
; ===========================================================================
2871
; For Z_RLE, simply look for runs of bytes, generate matches only of distance
2871
; For Z_RLE, simply look for runs of bytes, generate matches only of distance
2872
; one.  Do not maintain a hash table.  (It will be regenerated if this run of
2872
; one.  Do not maintain a hash table.  (It will be regenerated if this run of
2873
; deflate switches away from Z_RLE.)
2873
; deflate switches away from Z_RLE.)
2874
 
2874
 
2875
;block_state (s, flush)
2875
;block_state (s, flush)
2876
;    deflate_state *s
2876
;    deflate_state *s
2877
;    int flush
2877
;    int flush
2878
align 4
2878
align 4
2879
proc deflate_rle uses ecx edx edi esi, s:dword, flush:dword
2879
proc deflate_rle uses ecx edx edi esi, s:dword, flush:dword
2880
locals
2880
locals
2881
	bflush dd ? ;int ;set if current block must be flushed
2881
	bflush dd ? ;int ;set if current block must be flushed
2882
endl
2882
endl
2883
	mov edx,[s]
2883
	mov edx,[s]
2884
	zlib_debug 'deflate_rle'
2884
	zlib_debug 'deflate_rle'
2885
align 4
2885
align 4
2886
	.cycle0: ;for (;;)
2886
	.cycle0: ;for (;;)
2887
		; Make sure that we always have enough lookahead, except
2887
		; Make sure that we always have enough lookahead, except
2888
		; at the end of the input file. We need MAX_MATCH bytes
2888
		; at the end of the input file. We need MAX_MATCH bytes
2889
		; for the longest run, plus one for the unrolled loop.
2889
		; for the longest run, plus one for the unrolled loop.
2890
		cmp dword[edx+deflate_state.lookahead],MAX_MATCH
2890
		cmp dword[edx+deflate_state.lookahead],MAX_MATCH
2891
		jg .end0 ;if (..<=..)
2891
		jg .end0 ;if (..<=..)
2892
			stdcall fill_window, edx
2892
			stdcall fill_window, edx
2893
			cmp dword[edx+deflate_state.lookahead],MAX_MATCH
2893
			cmp dword[edx+deflate_state.lookahead],MAX_MATCH
2894
			jg @f
2894
			jg @f
2895
			cmp dword[flush],Z_NO_FLUSH
2895
			cmp dword[flush],Z_NO_FLUSH
2896
			jne @f ;if (..<=.. && ..==..)
2896
			jne @f ;if (..<=.. && ..==..)
2897
				mov eax,need_more
2897
				mov eax,need_more
2898
				jmp .end_f
2898
				jmp .end_f
2899
align 4
2899
align 4
2900
			@@:
2900
			@@:
2901
			cmp dword[edx+deflate_state.lookahead],0
2901
			cmp dword[edx+deflate_state.lookahead],0
2902
			je .cycle0end ;flush the current block
2902
			je .cycle0end ;flush the current block
2903
align 4
2903
align 4
2904
		.end0:
2904
		.end0:
2905
 
2905
 
2906
		; See how many times the previous byte repeats
2906
		; See how many times the previous byte repeats
2907
		mov dword[edx+deflate_state.match_length],0
2907
		mov dword[edx+deflate_state.match_length],0
2908
		cmp dword[edx+deflate_state.lookahead],MIN_MATCH
2908
		cmp dword[edx+deflate_state.lookahead],MIN_MATCH
2909
		jl .end1
2909
		jl .end1
2910
		cmp dword[edx+deflate_state.strstart],0
2910
		cmp dword[edx+deflate_state.strstart],0
2911
		jle .end1 ;if (..>=.. && ..>..)
2911
		jle .end1 ;if (..>=.. && ..>..)
2912
			mov esi,[edx+deflate_state.window]
2912
			mov esi,[edx+deflate_state.window]
2913
			add esi,[edx+deflate_state.strstart]
2913
			add esi,[edx+deflate_state.strstart]
2914
			dec esi
2914
			dec esi
2915
			lodsb
2915
			lodsb ;prev = *scan; ++scan
2916
			mov edi,esi
2916
			mov edi,esi
2917
			scasb
2917
			scasb
2918
			jnz .end2
2918
			jnz .end2
2919
			scasb
2919
			scasb
2920
			jnz .end2
2920
			jnz .end2
2921
			scasb
2921
			scasb
2922
			jnz .end2 ;if (..==.. && ..==.. && ..==..)
2922
			jnz .end2 ;if (..==.. && ..==.. && ..==..)
2923
				;edi = scan ;scan goes up to strend for length of run
2923
				;edi = scan ;scan goes up to strend for length of run
2924
				; al = prev ;byte at distance one to match
2924
				; al = prev ;byte at distance one to match
2925
				;ecx = strend-scan
2925
				;ecx = strend-scan
2926
				mov ecx,MAX_MATCH-2
2926
				mov ecx,MAX_MATCH-2
2927
				repz scasb
2927
				repz scasb
-
 
2928
				dec edi
2928
				sub edi,[edx+deflate_state.window]
2929
				sub edi,[edx+deflate_state.window]
2929
				sub edi,[edx+deflate_state.strstart]
2930
				sub edi,[edx+deflate_state.strstart]
2930
				mov [edx+deflate_state.match_length],edi
2931
				mov [edx+deflate_state.match_length],edi
2931
				mov eax,[edx+deflate_state.lookahead]
2932
				mov eax,[edx+deflate_state.lookahead]
2932
				cmp [edx+deflate_state.match_length],eax
2933
				cmp [edx+deflate_state.match_length],eax
2933
				jle .end2
2934
				jle .end2
2934
					mov [edx+deflate_state.match_length],eax
2935
					mov [edx+deflate_state.match_length],eax
2935
			.end2:
2936
			.end2:
2936
			mov eax,[edx+deflate_state.window_size]
2937
			mov eax,[edx+deflate_state.window_size]
2937
			dec eax
2938
			dec eax
2938
			add eax,[edx+deflate_state.window]
2939
			add eax,[edx+deflate_state.window]
2939
			cmp edi,eax
2940
			cmp edi,eax
2940
			jle .end1
2941
			jle .end1
2941
				zlib_assert 'wild scan' ;Assert(..<=..)
2942
				zlib_assert 'wild scan' ;Assert(..<=..)
2942
		.end1:
2943
		.end1:
2943
 
2944
 
2944
		; Emit match if have run of MIN_MATCH or longer, else emit literal
2945
		; Emit match if have run of MIN_MATCH or longer, else emit literal
2945
		cmp dword[edx+deflate_state.match_length],MIN_MATCH
2946
		cmp dword[edx+deflate_state.match_length],MIN_MATCH
2946
		jl @f ;if (..>=..)
2947
		jl @f ;if (..>=..)
2947
			push dword[edx+deflate_state.match_length]
2948
			push dword[edx+deflate_state.match_length]
2948
			mov eax,[edx+deflate_state.strstart]
2949
			mov eax,[edx+deflate_state.strstart]
2949
			dec eax
2950
			dec eax
2950
			stdcall check_match, edx, [edx+deflate_state.strstart], eax
2951
			stdcall check_match, edx, [edx+deflate_state.strstart], eax
2951
 
2952
 
2952
			mov eax,[edx+deflate_state.match_length]
2953
			mov eax,[edx+deflate_state.match_length]
2953
			sub eax,MIN_MATCH
2954
			sub eax,MIN_MATCH
2954
			_tr_tally_dist edx, 1, eax, [bflush]
2955
			_tr_tally_dist edx, 1, eax, [bflush]
2955
 
2956
 
2956
			mov eax,[edx+deflate_state.match_length]
2957
			mov eax,[edx+deflate_state.match_length]
2957
			sub [edx+deflate_state.lookahead],eax
2958
			sub [edx+deflate_state.lookahead],eax
2958
			add [edx+deflate_state.strstart],eax
2959
			add [edx+deflate_state.strstart],eax
2959
			mov dword[edx+deflate_state.match_length],0
2960
			mov dword[edx+deflate_state.match_length],0
2960
			jmp .end3
2961
			jmp .end3
2961
		@@: ;else
2962
		@@: ;else
2962
			; No match, output a literal byte
2963
			; No match, output a literal byte
2963
			mov eax,[edx+deflate_state.strstart]
2964
			mov eax,[edx+deflate_state.strstart]
2964
			add eax,[edx+deflate_state.window]
2965
			add eax,[edx+deflate_state.window]
2965
			movzx eax,byte[eax]
2966
			movzx eax,byte[eax]
2966
			Tracevv eax,
2967
			Tracevv eax,
2967
			_tr_tally_lit edx, eax, [bflush]
2968
			_tr_tally_lit edx, eax, [bflush]
2968
			dec dword[edx+deflate_state.lookahead]
2969
			dec dword[edx+deflate_state.lookahead]
2969
			inc dword[edx+deflate_state.strstart]
2970
			inc dword[edx+deflate_state.strstart]
2970
		.end3:
2971
		.end3:
2971
		cmp dword[bflush],0
2972
		cmp dword[bflush],0
2972
		je .cycle0 ;if (..)
2973
		je .cycle0 ;if (..)
2973
			FLUSH_BLOCK edx, 0
2974
			FLUSH_BLOCK edx, 0
2974
		jmp .cycle0
2975
		jmp .cycle0
2975
align 4
2976
align 4
2976
	.cycle0end:
2977
	.cycle0end:
2977
	mov dword[edx+deflate_state.insert],0
2978
	mov dword[edx+deflate_state.insert],0
2978
	cmp dword[flush],Z_FINISH
2979
	cmp dword[flush],Z_FINISH
2979
	jne @f ;if (..==..)
2980
	jne @f ;if (..==..)
2980
		FLUSH_BLOCK edx, 1
2981
		FLUSH_BLOCK edx, 1
2981
		mov eax,finish_done
2982
		mov eax,finish_done
2982
		jmp .end_f
2983
		jmp .end_f
2983
	@@:
2984
	@@:
2984
	cmp dword[edx+deflate_state.last_lit],0
2985
	cmp dword[edx+deflate_state.last_lit],0
2985
	je @f ;if (..)
2986
	je @f ;if (..)
2986
		FLUSH_BLOCK edx, 0
2987
		FLUSH_BLOCK edx, 0
2987
	@@:
2988
	@@:
2988
	mov eax,block_done
2989
	mov eax,block_done
2989
.end_f:
2990
.end_f:
2990
	ret
2991
	ret
2991
endp
2992
endp
2992
 
2993
 
2993
; ===========================================================================
2994
; ===========================================================================
2994
; For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
2995
; For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
2995
; (It will be regenerated if this run of deflate switches away from Huffman.)
2996
; (It will be regenerated if this run of deflate switches away from Huffman.)
2996
 
2997
 
2997
;block_state (s, flush)
2998
;block_state (s, flush)
2998
;    deflate_state *s
2999
;    deflate_state *s
2999
;    int flush
3000
;    int flush
3000
align 4
3001
align 4
3001
proc deflate_huff uses ebx edi, s:dword, flush:dword
3002
proc deflate_huff uses ebx edi, s:dword, flush:dword
3002
locals
3003
locals
3003
	bflush dd ? ;int ;set if current block must be flushed
3004
	bflush dd ? ;int ;set if current block must be flushed
3004
endl
3005
endl
3005
	mov edi,[s]
3006
	mov edi,[s]
3006
	zlib_debug 'deflate_huff'
3007
	zlib_debug 'deflate_huff'
3007
align 4
3008
align 4
3008
	.cycle0: ;for (;;)
3009
	.cycle0: ;for (;;)
3009
		; Make sure that we have a literal to write.
3010
		; Make sure that we have a literal to write.
3010
		cmp dword[edi+deflate_state.lookahead],0
3011
		cmp dword[edi+deflate_state.lookahead],0
3011
		jne .end0 ;if (..==0)
3012
		jne .end0 ;if (..==0)
3012
			stdcall fill_window, edi
3013
			stdcall fill_window, edi
3013
			cmp dword[edi+deflate_state.lookahead],0
3014
			cmp dword[edi+deflate_state.lookahead],0
3014
			jne .end0 ;if (..==0)
3015
			jne .end0 ;if (..==0)
3015
				cmp dword[flush],Z_NO_FLUSH
3016
				cmp dword[flush],Z_NO_FLUSH
3016
				jne .cycle0end ;if (..==..)
3017
				jne .cycle0end ;if (..==..)
3017
					mov eax,need_more
3018
					mov eax,need_more
3018
					jmp .end_f
3019
					jmp .end_f
3019
				;flush the current block
3020
				;flush the current block
3020
align 4
3021
align 4
3021
		.end0:
3022
		.end0:
3022
 
3023
 
3023
		; Output a literal byte
3024
		; Output a literal byte
3024
		mov dword[edi+deflate_state.match_length],0
3025
		mov dword[edi+deflate_state.match_length],0
3025
		mov eax,[edi+deflate_state.strstart]
3026
		mov eax,[edi+deflate_state.strstart]
3026
		add eax,[edi+deflate_state.window]
3027
		add eax,[edi+deflate_state.window]
3027
		movzx eax,byte[eax]
3028
		movzx eax,byte[eax]
3028
		Tracevv eax,
3029
		Tracevv eax,
3029
		_tr_tally_lit edi, eax, [bflush]
3030
		_tr_tally_lit edi, eax, [bflush]
3030
		dec dword[edi+deflate_state.lookahead]
3031
		dec dword[edi+deflate_state.lookahead]
3031
		inc dword[edi+deflate_state.strstart]
3032
		inc dword[edi+deflate_state.strstart]
3032
		cmp dword[bflush],0
3033
		cmp dword[bflush],0
3033
		je @f ;if (..)
3034
		je @f ;if (..)
3034
			FLUSH_BLOCK edi, 0
3035
			FLUSH_BLOCK edi, 0
3035
		@@:
3036
		@@:
3036
		jmp .cycle0
3037
		jmp .cycle0
3037
align 4
3038
align 4
3038
	.cycle0end:
3039
	.cycle0end:
3039
	mov dword[edi+deflate_state.insert],0
3040
	mov dword[edi+deflate_state.insert],0
3040
	cmp dword[flush],Z_FINISH
3041
	cmp dword[flush],Z_FINISH
3041
	jne @f ;if (..==..)
3042
	jne @f ;if (..==..)
3042
		FLUSH_BLOCK edi, 1
3043
		FLUSH_BLOCK edi, 1
3043
		mov eax,finish_done
3044
		mov eax,finish_done
3044
		jmp .end_f
3045
		jmp .end_f
3045
	@@:
3046
	@@:
3046
	cmp dword[edi+deflate_state.last_lit],0
3047
	cmp dword[edi+deflate_state.last_lit],0
3047
	je @f ;if (..)
3048
	je @f ;if (..)
3048
		FLUSH_BLOCK edi, 0
3049
		FLUSH_BLOCK edi, 0
3049
	@@:
3050
	@@:
3050
	mov eax,block_done
3051
	mov eax,block_done
3051
.end_f:
3052
.end_f:
3052
	ret
3053
	ret
3053
endp
3054
endp
3054
>
3055
>
3055
>
3056
>
3056
>
3057
>
3057
>
3058
>
3058
>
3059
>
3059
>
3060
>
3060
>
3061
>
3061
>
3062
>
3062
;>
3063
;>
3063
>
3064
>
3064
>
3065
>
3065
>
3066
>
3066
>
3067
>
3067
>
3068
>
3068
>
3069
>
3069
>
3070
>
3070
>
3071
>
3071
>
3072
>
3072
>
3073
>
3073
>
3074
>
3074
 
3075
 
3075
align>
3076
align>
3076
>
3077
>
3077
>
3078
>
3078
>
3079
>
3079
>
3080
>
3080
>
3081
>
3081
>
3082
>
3082
>
3083
>