Subversion Repositories Kolibri OS

Rev

Rev 6863 | Details | Compare with Previous | Last modification | View Log | RSS feed

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