Subversion Repositories Kolibri OS

Rev

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

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