Subversion Repositories Kolibri OS

Rev

Rev 6797 | Rev 6801 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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
  165.         shl ebx,2
  166.         add ebx,[s+deflate_state.prev]
  167.         mov [ebx],eax
  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. {
  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
  188.         mov eax,[s+deflate_state.hash_size]
  189.         ;dec eax
  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)
  202. ;    z_streamp strm
  203. ;    int level
  204. ;    const char *version
  205. ;    int stream_size
  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)
  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
  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)
  437. ;    z_streamp strm
  438. ;    const Bytef *dictionary
  439. ;    uInt  dictLength
  440. align 4
  441. proc deflateSetDictionary uses ebx edi, strm:dword, dictionary:dword, dictLength:dword
  442. locals
  443. ;    uInt str, n;
  444.         wrap  dd ? ;int
  445.         avail dd ? ;unsigned
  446.         next  dd ? ;unsigned char*
  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
  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.         @@:
  476.  
  477.         ; when using zlib wrappers, compute Adler-32 for provided dictionary
  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
  484.  
  485.         ; if dictionary would fill window, just replace the history
  486.         mov eax,[edi+deflate_state.w_size]
  487.         cmp [dictLength],eax
  488.         jl .end2 ;if (..>=..)
  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 */
  496.                 mov eax,[edi+deflate_state.w_size]
  497.                 mov [dictLength],eax
  498.         .end2:
  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;
  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
  536.         mov eax,Z_OK
  537. .end_f:
  538.         ret
  539. endp
  540.  
  541. ; =========================================================================
  542. ;int (strm)
  543. ;    z_streamp strm
  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
  565.         mov dword[ebx+z_stream.data_type],Z_UNKNOWN
  566.  
  567.         mov dword[edi+deflate_state.pending],0
  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
  586.                 xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
  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)
  600. ;    z_streamp strm
  601. align 4
  602. proc deflateReset uses ebx, strm:dword
  603.         mov ebx,[strm]
  604.         zlib_debug 'deflateReset'
  605.         stdcall deflateResetKeep, ebx
  606.         cmp eax,Z_OK
  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)
  615. ;    z_streamp strm
  616. ;    gz_headerp head
  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)
  643. ;    unsigned *pending
  644. ;    int *bits
  645. ;    z_streamp strm
  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]
  661.                 mov ebx,[edi+deflate_state.pending]
  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)
  677. ;    z_streamp strm
  678. ;    int bits
  679. ;    int value
  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)
  713. ;    z_streamp strm
  714. ;    int level
  715. ;    int strategy
  716. align 4
  717. proc deflateParams uses ebx edi, strm:dword, level:dword, strategy:dword
  718. locals
  719.         co_func dd ?
  720.         err dd Z_OK
  721. endl
  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
  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
  761.  
  762. ;    if ((strategy != s->strategy || co_func != configuration_table[level].func) &&
  763. ;        strm->total_in != 0) {
  764.                 ; Flush the last buffer:
  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. ;    }
  776.         mov eax,[strategy]
  777.         mov [edi+deflate_state.strategy],ax
  778.         mov eax,[err]
  779. .end_f:
  780.         ret
  781. endp
  782.  
  783. ; =========================================================================
  784. ;int (strm, good_length, max_lazy, nice_length, max_chain)
  785. ;    z_streamp strm
  786. ;    int good_length
  787. ;    int max_lazy
  788. ;    int nice_length
  789. ;    int max_chain
  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)
  834. ;    z_streamp strm
  835. ;    uLong sourceLen
  836. align 4
  837. proc deflateBound, strm:dword, sourceLen:dword
  838. ;    deflate_state *s;
  839. ;    uLong complen, wraplen;
  840. ;    Bytef *str;
  841.         zlib_debug 'deflateBound'
  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)
  900. ;    deflate_state *s
  901. ;    uInt b
  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)
  918. ;    z_streamp strm
  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
  924.         zlib_debug 'flush_pending'
  925.         mov ebx,[strm]
  926.         mov edx,[ebx+z_stream.state]
  927.  
  928.         stdcall _tr_flush_bits, edx
  929.         mov ecx,[edx+deflate_state.pending]
  930.         mov eax,[ebx+z_stream.avail_out]
  931.         cmp ecx,eax
  932.         jle @f ;if (..>..)
  933.                 mov ecx,eax
  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
  942.         sub [ebx+z_stream.avail_out],ecx
  943.         sub [edx+deflate_state.pending],ecx
  944.         cmp dword[edx+deflate_state.pending],0
  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)
  954. ;    z_streamp strm
  955. ;    int flush
  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
  972.         jge .end10 ;if (..==0 || ..==0 || ..>.. || ..<0)
  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
  981.         cmp dword[ebx+z_stream.avail_in],0
  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
  988.         .beg0: ;if (..==0 || (..==0 && ..!=0) || (..==.. && ..!=..))
  989.                 ERR_RETURN ebx, Z_STREAM_ERROR
  990.                 jmp .end_f
  991.         .end0:
  992.         cmp dword[ebx+z_stream.avail_out],0
  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 (..==..)
  1010.                         xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
  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],\
  1087.                                                 [edi+deflate_state.pending_buf], [edi+deflate_state.pending]
  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
  1104.                         jge @f
  1105.                         cmp word[edi+deflate_state.level],2
  1106.                         jge .end30 ;if (..>=.. || ..<..)
  1107.                         @@:
  1108.                                 xor esi,esi
  1109.                                 jmp .end4
  1110.                         .end30:
  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.                         @@:
  1144.                         xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
  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 (..!=..)
  1153.                         mov esi,[edi+deflate_state.pending]
  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
  1160.                                 mov eax,[edi+deflate_state.pending]
  1161.                                 cmp eax,[edi+deflate_state.pending_buf_size]
  1162.                                 jne .end24 ;if (..==..)
  1163.                                         mov dword[edx+gz_header.hcrc],0
  1164.                                         je @f
  1165.                                         cmp [edi+deflate_state.pending],esi
  1166.                                         jle @f ;if (.. && ..>..)
  1167.                                                 mov ecx,[edi+deflate_state.pending]
  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
  1175.                                         mov esi,[edi+deflate_state.pending]
  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
  1190.                         cmp [edi+deflate_state.pending],esi
  1191.                         jle @f ;if (.. && ..>..)
  1192.                                 mov ecx,[edi+deflate_state.pending]
  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 (..!=..)
  1212.                         mov esi,[edi+deflate_state.pending]
  1213.                         ;esi = beg ;start of bytes to update crc
  1214.  
  1215.                         .cycle1: ;do
  1216.                                 mov eax,[edi+deflate_state.pending]
  1217.                                 cmp eax,[edi+deflate_state.pending_buf_size]
  1218.                                 jne .end25 ;if (..==..)
  1219.                                         mov dword[edx+gz_header.hcrc],0
  1220.                                         je @f
  1221.                                         cmp [edi+deflate_state.pending],esi
  1222.                                         jle @f ;if (.. && ..>..)
  1223.                                                 mov ecx,[edi+deflate_state.pending]
  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
  1231.                                         mov esi,[edi+deflate_state.pending]
  1232.                                         cmp esi,[edi+deflate_state.pending_buf_size]
  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
  1250.                         cmp [edi+deflate_state.pending],esi
  1251.                         jle @f ;if (.. && ..>..)
  1252.                                 mov ecx,[edi+deflate_state.pending]
  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 (..!=..)
  1271.                         mov esi,[edi+deflate_state.pending]
  1272.                         ;esi = beg ;start of bytes to update crc
  1273.  
  1274.                         .cycle2: ;do
  1275.                                 mov eax,[edi+deflate_state.pending]
  1276.                                 cmp eax,[edi+deflate_state.pending_buf_size]
  1277.                                 jne .end26 ;if (..==..)
  1278.                                         mov dword[edx+gz_header.hcrc],0
  1279.                                         je @f
  1280.                                         cmp [edi+deflate_state.pending],esi
  1281.                                         jle @f ;if (.. && ..>..)
  1282.                                                 mov ecx,[edi+deflate_state.pending]
  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
  1290.                                         mov esi,[edi+deflate_state.pending]
  1291.                                         cmp esi,[edi+deflate_state.pending_buf_size]
  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
  1309.                         cmp [edi+deflate_state.pending],esi
  1310.                         jle @f ;if (.. && ..>..)
  1311.                                 mov ecx,[edi+deflate_state.pending]
  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 (..)
  1329.                         mov ecx,[edi+deflate_state.pending]
  1330.                         add ecx,2
  1331.                         cmp ecx,[edi+deflate_state.pending_buf_size]
  1332.                         jle @f ;if (..>..)
  1333.                                 stdcall flush_pending, ebx
  1334.                         @@:
  1335.                         mov ecx,[edi+deflate_state.pending]
  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
  1342.                                 xor eax,eax ;stdcall calc_crc32, 0, Z_NULL, 0
  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
  1353.         cmp dword[edi+deflate_state.pending],0
  1354.         je .end13 ;if (..!=0)
  1355.                 stdcall flush_pending, ebx
  1356.                 cmp dword[ebx+z_stream.avail_out],0
  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:
  1373.         cmp dword[ebx+z_stream.avail_in],0
  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
  1388.         cmp dword[ebx+z_stream.avail_in],0
  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.  
  1396.         cmp dword[ebx+z_stream.avail_in],0
  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
  1426.                 jne .end18
  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
  1433.                 jne .end19
  1434.                 @@: ;if (..==.. || ..==..)
  1435.                         cmp dword[ebx+z_stream.avail_out],0
  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
  1472.                 cmp dword[ebx+z_stream.avail_out],0
  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:
  1478.         cmp dword[ebx+z_stream.avail_out],0
  1479.         jg @f
  1480.                 zlib_assert 'bug2' ;Assert(..>0)
  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.  
  1513.         cmp dword[edi+deflate_state.pending],0
  1514.         jle @f ;if (..>0) ;write the trailer only once!
  1515.                 neg dword[edi+deflate_state.pending]
  1516.                 inc dword[edi+deflate_state.pending]
  1517.         @@:
  1518.         mov eax,Z_OK
  1519.         cmp dword[edi+deflate_state.pending],0
  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)
  1529. ;    z_streamp strm
  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)
  1586. ;    z_streamp dest
  1587. ;    z_streamp source
  1588. align 4
  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*
  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
  1628.         mov ebx,eax
  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
  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]
  1656.  
  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
  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)
  1691. ;    z_streamp strm
  1692. ;    Bytef *buf
  1693. ;    unsigned size
  1694. align 4
  1695. proc read_buf uses ebx ecx, strm:dword, buf:dword, size:dword
  1696.         mov ebx,[strm]
  1697.         mov eax,[ebx+z_stream.avail_in]
  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.  
  1709.         sub [ebx+z_stream.avail_in],eax
  1710.  
  1711.         stdcall zmemcpy, [buf],[ebx+z_stream.next_in],eax
  1712.         mov ecx,[ebx+z_stream.state]
  1713.         cmp dword[ecx+deflate_state.wrap],1
  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
  1722.         cmp dword[ecx+deflate_state.wrap],2
  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)
  1783. ;    deflate_state *s
  1784. ;    IPos cur_match ;current match
  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.
  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
  1821.  
  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.         @@:
  1829.         ; Stop when cur_match becomes <= limit. To simplify the code,
  1830.         ; we prevent matches with the string of window index 0.
  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
  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.  
  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
  1853.  
  1854.         ; Do not waste too much time if we already have a good match:
  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.         @@:
  1860.         ; Do not look for matches beyond the end of the input. This is necessary
  1861.         ; to make deflate deterministic.
  1862.  
  1863.         mov eax,[edx+deflate_state.lookahead]
  1864.         cmp dword[nice_match],eax
  1865.         jle @f ;if (..>..)
  1866.                 mov [nice_match],eax
  1867.         @@:
  1868.  
  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(..<=..)
  1874.  
  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]
  1884.  
  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.
  1892.  
  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
  1904.  
  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.
  1910.  
  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.                 @@:
  1918.  
  1919.                 ; We check for insufficient lookahead only every 8th comparison;
  1920.                 ; the 256th check will be made at strstart+258.
  1921.  
  1922.                 inc edi
  1923.                 inc esi
  1924.                 mov ecx,[strend]
  1925.                 sub ecx,edi
  1926.                 jz @f
  1927.                         repe cmpsb
  1928.                         dec edi
  1929.                         dec esi
  1930.                 @@:
  1931.  
  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.                 @@:
  1939.  
  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
  1946.  
  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]
  1960.  
  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
  1973. align 4
  1974.         .cycle0end: ;while (..>.. && ..!=0)
  1975.  
  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.  
  1983. else ;FASTEST
  1984.  
  1985. ; ---------------------------------------------------------------------------
  1986. ; Optimized version for FASTEST only
  1987.         mov edx,[s]
  1988.         zlib_debug 'longest_match'
  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
  1996.                 zlib_assert 'Code too clever' ;Assert(..>=.. && ..==..)
  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
  2003.                 zlib_assert 'need lookahead' ;Assert(..<=..)
  2004.         @@:
  2005.         mov eax,[edx+deflate_state.strstart]
  2006.         cmp [cur_match],eax
  2007.         jl @f
  2008.                 zlib_assert 'no future' ;Assert(..<..)
  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
  2037.                 zlib_assert 'match[2]?' ;Assert(..==..)
  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
  2056.                 zlib_assert 'wild scan' ;Assert(..<=..)
  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)
  2084. ;    deflate_state *s
  2085. ;    IPos start, match
  2086. ;    int length
  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
  2129.         zlib_debug 'fill_window'
  2130.         mov edi,[s]
  2131.         cmp dword[edi+deflate_state.lookahead],MIN_LOOKAHEAD
  2132.         jl @f
  2133.                 zlib_assert 'already enough lookahead' ;Assert(..<..)
  2134.         @@:
  2135.  
  2136.         mov ecx,[edi+deflate_state.w_size]
  2137.         mov edx,[edi+deflate_state.strm]
  2138.         .cycle0: ;do
  2139.         zlib_debug 'do'
  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.  
  2184. if FASTEST eq 0
  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:
  2206.                 cmp dword[edx+z_stream.avail_in],0
  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
  2222.                         zlib_assert 'more < 2' ;Assert(..>=..)
  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
  2285.                 cmp dword[edx+z_stream.avail_in],0
  2286.                 jne .cycle0
  2287. align 4
  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
  2348.                 zlib_assert 'not enough room for search' ;Assert(..<=..)
  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]
  2384.         cmp dword[eax+z_stream.avail_out],0
  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)
  2405. ;    deflate_state *s
  2406. ;    int flush
  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]
  2412.         zlib_debug 'deflate_stored'
  2413.  
  2414.         mov ecx,0xffff
  2415.         mov eax,[edi+deflate_state.pending_buf_size]
  2416.         sub eax,5
  2417.         cmp ecx,eax
  2418.         jle .cycle0 ;if (..>..)
  2419.                 mov ecx,eax
  2420.         ;ecx = max_block_size
  2421.  
  2422.         ; Copy as much as possible from input to output:
  2423. align 4
  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:
  2442.                 cmp dword[edi+deflate_state.block_start],0
  2443.                 jge @f
  2444.                         zlib_assert 'block gone' ;Assert(..>=0)
  2445.                 @@:
  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]
  2512.         zlib_debug 'deflate_fast'
  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]
  2667.         zlib_debug 'deflate_slow'
  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
  2710.                 je .end1
  2711.                 mov eax,[edi+deflate_state.prev_length]
  2712.                 cmp eax,[edi+deflate_state.max_lazy_match]
  2713.                 jge .end1
  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
  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
  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
  2753.                 jl .end2
  2754.                 cmp [edi+deflate_state.match_length],eax
  2755.                 jg .end2 ;if (..>=.. && ..<=..)
  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]
  2819.                         cmp dword[eax+z_stream.avail_out],0
  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
  2833. align 4
  2834.         .cycle0end:
  2835.         cmp dword[flush],Z_NO_FLUSH
  2836.         jne @f
  2837.                 zlib_assert 'no flush?' ;Assert (..!=..)
  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)
  2876. ;    deflate_state *s
  2877. ;    int flush
  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]
  2884.         zlib_debug 'deflate_rle'
  2885. align 4
  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
  2915.                         lodsb
  2916.                         mov edi,esi
  2917.                         scasb
  2918.                         jnz .end2
  2919.                         scasb
  2920.                         jnz .end2
  2921.                         scasb
  2922.                         jnz .end2 ;if (..==.. && ..==.. && ..==..)
  2923.                                 ;edi = scan ;scan goes up to strend for length of run
  2924.                                 ; al = prev ;byte at distance one to match
  2925.                                 ;ecx = strend-scan
  2926.                                 mov ecx,MAX_MATCH-2
  2927.                                 repz scasb
  2928.                                 sub edi,[edx+deflate_state.window]
  2929.                                 sub edi,[edx+deflate_state.strstart]
  2930.                                 mov [edx+deflate_state.match_length],edi
  2931.                                 mov eax,[edx+deflate_state.lookahead]
  2932.                                 cmp [edx+deflate_state.match_length],eax
  2933.                                 jle .end2
  2934.                                         mov [edx+deflate_state.match_length],eax
  2935.                         .end2:
  2936.                         mov eax,[edx+deflate_state.window_size]
  2937.                         dec eax
  2938.                         add eax,[edx+deflate_state.window]
  2939.                         cmp edi,eax
  2940.                         jle .end1
  2941.                                 zlib_assert 'wild scan' ;Assert(..<=..)
  2942.                 .end1:
  2943.  
  2944.                 ; Emit match if have run of MIN_MATCH or longer, else emit literal
  2945.                 cmp dword[edx+deflate_state.match_length],MIN_MATCH
  2946.                 jl @f ;if (..>=..)
  2947.                         push dword[edx+deflate_state.match_length]
  2948.                         mov eax,[edx+deflate_state.strstart]
  2949.                         dec eax
  2950.                         stdcall check_match, edx, [edx+deflate_state.strstart], eax
  2951.  
  2952.                         mov eax,[edx+deflate_state.match_length]
  2953.                         sub eax,MIN_MATCH
  2954.                         _tr_tally_dist edx, 1, eax, [bflush]
  2955.  
  2956.                         mov eax,[edx+deflate_state.match_length]
  2957.                         sub [edx+deflate_state.lookahead],eax
  2958.                         add [edx+deflate_state.strstart],eax
  2959.                         mov dword[edx+deflate_state.match_length],0
  2960.                         jmp .end3
  2961.                 @@: ;else
  2962.                         ; No match, output a literal byte
  2963.                         mov eax,[edx+deflate_state.strstart]
  2964.                         add eax,[edx+deflate_state.window]
  2965.                         movzx eax,byte[eax]
  2966.                         Tracevv eax,
  2967.                         _tr_tally_lit edx, eax, [bflush]
  2968.                         dec dword[edx+deflate_state.lookahead]
  2969.                         inc dword[edx+deflate_state.strstart]
  2970.                 .end3:
  2971.                 cmp dword[bflush],0
  2972.                 je .cycle0 ;if (..)
  2973.                         FLUSH_BLOCK edx, 0
  2974.                 jmp .cycle0
  2975. align 4
  2976.         .cycle0end:
  2977.         mov dword[edx+deflate_state.insert],0
  2978.         cmp dword[flush],Z_FINISH
  2979.         jne @f ;if (..==..)
  2980.                 FLUSH_BLOCK edx, 1
  2981.                 mov eax,finish_done
  2982.                 jmp .end_f
  2983.         @@:
  2984.         cmp dword[edx+deflate_state.last_lit],0
  2985.         je @f ;if (..)
  2986.                 FLUSH_BLOCK edx, 0
  2987.         @@:
  2988.         mov eax,block_done
  2989. .end_f:
  2990.         ret
  2991. endp
  2992.  
  2993. ; ===========================================================================
  2994. ; For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
  2995. ; (It will be regenerated if this run of deflate switches away from Huffman.)
  2996.  
  2997. ;block_state (s, flush)
  2998. ;    deflate_state *s
  2999. ;    int flush
  3000. align 4
  3001. proc deflate_huff uses ebx edi, s:dword, flush:dword
  3002. locals
  3003.         bflush dd ? ;int ;set if current block must be flushed
  3004. endl
  3005.         mov edi,[s]
  3006.         zlib_debug 'deflate_huff'
  3007. align 4
  3008.         .cycle0: ;for (;;)
  3009.                 ; Make sure that we have a literal to write.
  3010.                 cmp dword[edi+deflate_state.lookahead],0
  3011.                 jne .end0 ;if (..==0)
  3012.                         stdcall fill_window, edi
  3013.                         cmp dword[edi+deflate_state.lookahead],0
  3014.                         jne .end0 ;if (..==0)
  3015.                                 cmp dword[flush],Z_NO_FLUSH
  3016.                                 jne .cycle0end ;if (..==..)
  3017.                                         mov eax,need_more
  3018.                                         jmp .end_f
  3019.                                 ;flush the current block
  3020. align 4
  3021.                 .end0:
  3022.  
  3023.                 ; Output a literal byte
  3024.                 mov dword[edi+deflate_state.match_length],0
  3025.                 mov eax,[edi+deflate_state.strstart]
  3026.                 add eax,[edi+deflate_state.window]
  3027.                 movzx eax,byte[eax]
  3028.                 Tracevv eax,
  3029.                 _tr_tally_lit edi, eax, [bflush]
  3030.                 dec dword[edi+deflate_state.lookahead]
  3031.                 inc dword[edi+deflate_state.strstart]
  3032.                 cmp dword[bflush],0
  3033.                 je @f ;if (..)
  3034.                         FLUSH_BLOCK edi, 0
  3035.                 @@:
  3036.                 jmp .cycle0
  3037. align 4
  3038.         .cycle0end:
  3039.         mov dword[edi+deflate_state.insert],0
  3040.         cmp dword[flush],Z_FINISH
  3041.         jne @f ;if (..==..)
  3042.                 FLUSH_BLOCK edi, 1
  3043.                 mov eax,finish_done
  3044.                 jmp .end_f
  3045.         @@:
  3046.         cmp dword[edi+deflate_state.last_lit],0
  3047.         je @f ;if (..)
  3048.                 FLUSH_BLOCK edi, 0
  3049.         @@:
  3050.         mov eax,block_done
  3051. .end_f:
  3052.         ret
  3053. endp
  3054.