Subversion Repositories Kolibri OS

Rev

Rev 6851 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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