Subversion Repositories Kolibri OS

Rev

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

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