// File: tomfunkhouser[P]gaps/pkgs/png/deflate.c
// Function: deflateInit2_
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
                  version, stream_size)
    z_streamp strm;
    int  level;
    int  method;
    int  windowBits;
    int  memLevel;
    int  strategy;
    const char *version;
    int stream_size;
{
    deflate_state *s;
    int wrap = 1;
    static const char my_version[] = ZLIB_VERSION;

    ushf *overlay;
    /* We overlay pending_buf and d_buf+l_buf. This works since the average
     * output size for (length,distance) codes is <= 24 bits.
     */

    if (version == Z_NULL || version[0] != my_version[0] ||
        stream_size != sizeof(z_stream)) {
        return Z_VERSION_ERROR;
    }
    if (strm == Z_NULL) return Z_STREAM_ERROR;

    strm->msg = Z_NULL;
    if (strm->zalloc == (alloc_func)0) {
        strm->zalloc = zcalloc;
        strm->opaque = (voidpf)0;
    }
    if (strm->zfree == (free_func)0) strm->zfree = zcfree;

#ifdef FASTEST
    if (level != 0) level = 1;
#else
    if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif

    if (windowBits < 0) { /* suppress zlib wrapper */
        wrap = 0;
        windowBits = -windowBits;
    }
#ifdef GZIP
    else if (windowBits > 15) {
        wrap = 2;       /* write gzip wrapper instead */
        windowBits -= 16;
    }
#endif
    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
        strategy < 0 || strategy > Z_FIXED) {
        return Z_STREAM_ERROR;
    }
    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
    if (s == Z_NULL) return Z_MEM_ERROR;
    strm->state = (struct internal_state FAR *)s;
    s->strm = strm;

    s->wrap = wrap;
    s->gzhead = Z_NULL;
    s->w_bits = windowBits;
    s->w_size = 1 << s->w_bits;
    s->w_mask = s->w_size - 1;

    s->hash_bits = memLevel + 7;
    s->hash_size = 1 << s->hash_bits;
    s->hash_mask = s->hash_size - 1;
    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);

    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));

    s->high_water = 0;      /* nothing written to s->window yet */

    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */

    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
    s->pending_buf = (uchf *) overlay;
    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);

    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
        s->pending_buf == Z_NULL) {
        s->status = FINISH_STATE;
        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
        deflateEnd (strm);
        return Z_MEM_ERROR;
    }
    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;

    s->level = level;
    s->strategy = strategy;
    s->method = (Byte)method;

    return deflateReset(strm);
}

// Assembly:
subq $0x48, %rsp
movl 0x58(%rsp), %eax
movq 0x50(%rsp), %rax
movq %rdi, 0x38(%rsp)
movl %esi, 0x34(%rsp)
movl %edx, 0x30(%rsp)
movl %ecx, 0x2c(%rsp)
movl %r8d, 0x28(%rsp)
movl %r9d, 0x24(%rsp)
movl $0x1, 0x14(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x114f36
movq 0x50(%rsp), %rax
movsbl (%rax), %eax
movsbl 0x289cd(%rip), %ecx     # 0x13d8f4
cmpl %ecx, %eax
jne 0x114f36
movslq 0x58(%rsp), %rax
cmpq $0x70, %rax
je 0x114f43
movl $0xfffffffa, 0x44(%rsp) # imm = 0xFFFFFFFA
jmp 0x11533e
cmpq $0x0, 0x38(%rsp)
jne 0x114f58
movl $0xfffffffe, 0x44(%rsp) # imm = 0xFFFFFFFE
jmp 0x11533e
movq 0x38(%rsp), %rax
movq $0x0, 0x30(%rax)
movq 0x38(%rsp), %rax
cmpq $0x0, 0x40(%rax)
jne 0x114f8e
movq 0x38(%rsp), %rax
leaq 0xd913(%rip), %rcx      # 0x122890
movq %rcx, 0x40(%rax)
movq 0x38(%rsp), %rax
movq $0x0, 0x50(%rax)
movq 0x38(%rsp), %rax
cmpq $0x0, 0x48(%rax)
jne 0x114faa
movq 0x38(%rsp), %rax
leaq 0xd92a(%rip), %rcx      # 0x1228d0
movq %rcx, 0x48(%rax)
cmpl $-0x1, 0x34(%rsp)
jne 0x114fb9
movl $0x6, 0x34(%rsp)
cmpl $0x0, 0x2c(%rsp)
jge 0x114fd4
movl $0x0, 0x14(%rsp)
xorl %eax, %eax
subl 0x2c(%rsp), %eax
movl %eax, 0x2c(%rsp)
jmp 0x114ff0
cmpl $0xf, 0x2c(%rsp)
jle 0x114fee
movl $0x2, 0x14(%rsp)
movl 0x2c(%rsp), %eax
subl $0x10, %eax
movl %eax, 0x2c(%rsp)
jmp 0x114ff0
cmpl $0x1, 0x28(%rsp)
jl 0x11502f
cmpl $0x9, 0x28(%rsp)
jg 0x11502f
cmpl $0x8, 0x30(%rsp)
jne 0x11502f
cmpl $0x8, 0x2c(%rsp)
jl 0x11502f
cmpl $0xf, 0x2c(%rsp)
jg 0x11502f
cmpl $0x0, 0x34(%rsp)
jl 0x11502f
cmpl $0x9, 0x34(%rsp)
jg 0x11502f
cmpl $0x0, 0x24(%rsp)
jl 0x11502f
cmpl $0x4, 0x24(%rsp)
jle 0x11503c
movl $0xfffffffe, 0x44(%rsp) # imm = 0xFFFFFFFE
jmp 0x11533e
cmpl $0x8, 0x2c(%rsp)
jne 0x11504b
movl $0x9, 0x2c(%rsp)
movq 0x38(%rsp), %rax
movq 0x40(%rax), %rax
movq 0x38(%rsp), %rcx
movq 0x50(%rcx), %rdi
movl $0x1, %esi
movl $0x1730, %edx           # imm = 0x1730
callq *%rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
jne 0x115083
movl $0xfffffffc, 0x44(%rsp) # imm = 0xFFFFFFFC
jmp 0x11533e
movq 0x18(%rsp), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x38(%rax)
movq 0x38(%rsp), %rcx
movq 0x18(%rsp), %rax
movq %rcx, (%rax)
movl 0x14(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x2c(%rax)
movq 0x18(%rsp), %rax
movq $0x0, 0x30(%rax)
movl 0x2c(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x48(%rax)
movq 0x18(%rsp), %rax
movl 0x48(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x44(%rax)
movq 0x18(%rsp), %rax
movl 0x44(%rax), %ecx
subl $0x1, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x4c(%rax)
movl 0x28(%rsp), %ecx
addl $0x7, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x78(%rax)
movq 0x18(%rsp), %rax
movl 0x78(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x74(%rax)
movq 0x18(%rsp), %rax
movl 0x74(%rax), %ecx
subl $0x1, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x7c(%rax)
movq 0x18(%rsp), %rax
movl 0x78(%rax), %eax
addl $0x3, %eax
subl $0x1, %eax
movl $0x3, %ecx
xorl %edx, %edx
divl %ecx
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x80(%rax)
movq 0x38(%rsp), %rax
movq 0x40(%rax), %rax
movq 0x38(%rsp), %rcx
movq 0x50(%rcx), %rdi
movq 0x18(%rsp), %rcx
movl 0x44(%rcx), %esi
movl $0x2, %edx
callq *%rax
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x50(%rax)
movq 0x38(%rsp), %rax
movq 0x40(%rax), %rax
movq 0x38(%rsp), %rcx
movq 0x50(%rcx), %rdi
movq 0x18(%rsp), %rcx
movl 0x44(%rcx), %esi
movl $0x2, %edx
callq *%rax
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x60(%rax)
movq 0x38(%rsp), %rax
movq 0x40(%rax), %rax
movq 0x38(%rsp), %rcx
movq 0x50(%rcx), %rdi
movq 0x18(%rsp), %rcx
movl 0x74(%rcx), %esi
movl $0x2, %edx
callq *%rax
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x68(%rax)
movq 0x18(%rsp), %rax
movq $0x0, 0x1728(%rax)
movl 0x28(%rsp), %ecx
addl $0x6, %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x16f8(%rax)
movq 0x38(%rsp), %rax
movq 0x40(%rax), %rax
movq 0x38(%rsp), %rcx
movq 0x50(%rcx), %rdi
movq 0x18(%rsp), %rcx
movl 0x16f8(%rcx), %esi
movl $0x4, %edx
callq *%rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x18(%rsp), %rax
movl 0x16f8(%rax), %eax
movl %eax, %ecx
shlq $0x2, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x18(%rsp), %rax
cmpq $0x0, 0x50(%rax)
je 0x115281
movq 0x18(%rsp), %rax
cmpq $0x0, 0x60(%rax)
je 0x115281
movq 0x18(%rsp), %rax
cmpq $0x0, 0x68(%rax)
je 0x115281
movq 0x18(%rsp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1152b8
movq 0x18(%rsp), %rax
movl $0x29a, 0x8(%rax)       # imm = 0x29A
leaq 0x59a5c(%rip), %rax     # 0x16ecf0
movq 0x30(%rax), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0x38(%rsp), %rdi
callq 0x115350
movl $0xfffffffc, 0x44(%rsp) # imm = 0xFFFFFFFC
jmp 0x11533e
movq 0x8(%rsp), %rcx
movq 0x18(%rsp), %rax
movl 0x16f8(%rax), %eax
shrq %rax
shlq %rax
addq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x1700(%rax)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x18(%rsp), %rax
movl 0x16f8(%rax), %eax
imulq $0x3, %rax, %rax
addq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x16f0(%rax)
movl 0x34(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0xb4(%rax)
movl 0x24(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0xb8(%rax)
movl 0x30(%rsp), %eax
movb %al, %cl
movq 0x18(%rsp), %rax
movb %cl, 0x3c(%rax)
movq 0x38(%rsp), %rdi
callq 0x1154e0
movl %eax, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nopw (%rax,%rax)