Subversion Repositories Kolibri OS

Rev

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