Subversion Repositories Kolibri OS

Rev

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

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