// File: tomfunkhouser[P]gaps/pkgs/png/deflate.c
// Function: deflate_stored
local block_state deflate_stored(s, flush)
    deflate_state *s;
    int flush;
{
    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
     * to pending_buf_size, and each stored block has a 5 byte header:
     */
    ulg max_block_size = 0xffff;
    ulg max_start;

    if (max_block_size > s->pending_buf_size - 5) {
        max_block_size = s->pending_buf_size - 5;
    }

    /* Copy as much as possible from input to output: */
    for (;;) {
        /* Fill the window as much as possible: */
        if (s->lookahead <= 1) {

            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
                   s->block_start >= (long)s->w_size, "slide too late");

            fill_window(s);
            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;

            if (s->lookahead == 0) break; /* flush the current block */
        }
        Assert(s->block_start >= 0L, "block gone");

        s->strstart += s->lookahead;
        s->lookahead = 0;

        /* Emit a stored block if pending_buf will be full: */
        max_start = s->block_start + max_block_size;
        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
            /* strstart == 0 is possible when wraparound on 16-bit machine */
            s->lookahead = (uInt)(s->strstart - max_start);
            s->strstart = (uInt)max_start;
            FLUSH_BLOCK(s, 0);
        }
        /* Flush if we may have to slide, otherwise block_start may become
         * negative and the data will be gone:
         */
        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
            FLUSH_BLOCK(s, 0);
        }
    }
    FLUSH_BLOCK(s, flush == Z_FINISH);
    return flush == Z_FINISH ? finish_done : block_done;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movl %esi, 0x44(%rsp)
movq $0xffff, 0x38(%rsp)     # imm = 0xFFFF
movq 0x38(%rsp), %rax
movq 0x48(%rsp), %rcx
movq 0x18(%rcx), %rcx
subq $0x5, %rcx
cmpq %rcx, %rax
jbe 0x117fcf
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rax
subq $0x5, %rax
movq %rax, 0x38(%rsp)
jmp 0x117fd1
movq 0x48(%rsp), %rax
cmpl $0x1, 0xa4(%rax)
ja 0x118020
movq 0x48(%rsp), %rdi
callq 0x1193a0
movq 0x48(%rsp), %rax
cmpl $0x0, 0xa4(%rax)
jne 0x11800b
cmpl $0x0, 0x44(%rsp)
jne 0x11800b
movl $0x0, 0x54(%rsp)
jmp 0x118320
movq 0x48(%rsp), %rax
cmpl $0x0, 0xa4(%rax)
jne 0x11801e
jmp 0x118248
jmp 0x118020
movq 0x48(%rsp), %rax
movl 0xa4(%rax), %ecx
movq 0x48(%rsp), %rax
addl 0x9c(%rax), %ecx
movl %ecx, 0x9c(%rax)
movq 0x48(%rsp), %rax
movl $0x0, 0xa4(%rax)
movq 0x48(%rsp), %rax
movq 0x88(%rax), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x48(%rsp), %rax
cmpl $0x0, 0x9c(%rax)
je 0x118085
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
cmpq 0x30(%rsp), %rax
jb 0x118164
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
subq 0x30(%rsp), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0xa4(%rax)
movq 0x30(%rsp), %rax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x9c(%rax)
movq 0x48(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x48(%rsp), %rax
cmpq $0x0, 0x88(%rax)
jl 0x1180ee
movq 0x48(%rsp), %rax
movq 0x50(%rax), %rax
movq 0x48(%rsp), %rcx
movq 0x88(%rcx), %rcx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
jmp 0x1180f7
xorl %eax, %eax
movq %rax, 0x20(%rsp)
jmp 0x1180f7
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rsi
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %edx
movq 0x48(%rsp), %rax
subq 0x88(%rax), %rdx
xorl %ecx, %ecx
callq 0x11f710
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movq %rcx, 0x88(%rax)
movq 0x48(%rsp), %rax
movq (%rax), %rdi
callq 0x117190
movq 0x48(%rsp), %rax
movq (%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x118162
movl $0x0, 0x54(%rsp)
jmp 0x118320
jmp 0x118164
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movq 0x48(%rsp), %rcx
movq 0x88(%rcx), %rcx
subl %ecx, %eax
movq 0x48(%rsp), %rcx
movl 0x44(%rcx), %ecx
subl $0x106, %ecx            # imm = 0x106
cmpl %ecx, %eax
jb 0x118243
movq 0x48(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x48(%rsp), %rax
cmpq $0x0, 0x88(%rax)
jl 0x1181cd
movq 0x48(%rsp), %rax
movq 0x50(%rax), %rax
movq 0x48(%rsp), %rcx
movq 0x88(%rcx), %rcx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
jmp 0x1181d6
xorl %eax, %eax
movq %rax, 0x10(%rsp)
jmp 0x1181d6
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rsi
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %edx
movq 0x48(%rsp), %rax
subq 0x88(%rax), %rdx
xorl %ecx, %ecx
callq 0x11f710
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movq %rcx, 0x88(%rax)
movq 0x48(%rsp), %rax
movq (%rax), %rdi
callq 0x117190
movq 0x48(%rsp), %rax
movq (%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x118241
movl $0x0, 0x54(%rsp)
jmp 0x118320
jmp 0x118243
jmp 0x117fd1
movq 0x48(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x48(%rsp), %rax
cmpq $0x0, 0x88(%rax)
jl 0x118281
movq 0x48(%rsp), %rax
movq 0x50(%rax), %rax
movq 0x48(%rsp), %rcx
movq 0x88(%rcx), %rcx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, (%rsp)
jmp 0x118289
xorl %eax, %eax
movq %rax, (%rsp)
jmp 0x118289
movq 0x8(%rsp), %rdi
movq (%rsp), %rsi
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %edx
movq 0x48(%rsp), %rax
subq 0x88(%rax), %rdx
cmpl $0x4, 0x44(%rsp)
sete %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x11f710
movq 0x48(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, %ecx
movq 0x48(%rsp), %rax
movq %rcx, 0x88(%rax)
movq 0x48(%rsp), %rax
movq (%rax), %rdi
callq 0x117190
movq 0x48(%rsp), %rax
movq (%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x118308
movl 0x44(%rsp), %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x4, %edx
cmovel %ecx, %eax
movl %eax, 0x54(%rsp)
jmp 0x118320
movl 0x44(%rsp), %edx
movl $0x1, %eax
movl $0x3, %ecx
cmpl $0x4, %edx
cmovel %ecx, %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
addq $0x58, %rsp
retq
nopl (%rax)