// File: jimmiebergmann[P]fbx-file/miniz.c
// Function: mz_zip_reader_extract_iter_read
size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size)
{
    size_t copied_to_caller = 0;

    /* Argument sanity check */
    if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
        return 0;

    if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
    {
        /* The file is stored or the caller has requested the compressed data, calc amount to return. */
        copied_to_caller = (size_t)MZ_MIN((mz_uint64)buf_size, pState->comp_remaining );

        /* Zip is in memory....or requires reading from a file? */
        if (pState->pZip->m_pState->m_pMem)
        {
            /* Copy data to caller's buffer */
            memcpy( pvBuf, pState->pRead_buf, copied_to_caller );
            pState->pRead_buf = ((mz_uint8*)pState->pRead_buf) + copied_to_caller;
        }
        else
        {
            /* Read directly into caller's buffer */
            if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
            {
                /* Failed to read all that was asked for, flag failure and alert user */
                mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
                pState->status = TINFL_STATUS_FAILED;
                copied_to_caller = 0;
            }
        }

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
        /* Compute CRC if not returning compressed data only */
        if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
            pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller);
#endif

        /* Advance offsets, dec counters */
        pState->cur_file_ofs += copied_to_caller;
        pState->out_buf_ofs += copied_to_caller;
        pState->comp_remaining -= copied_to_caller;
    }
    else
    {
        do
        {
            /* Calc ptr to write buffer - given current output pos and block size */
            mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));

            /* Calc max output size - given current output pos and block size */
            size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));

            if (!pState->out_blk_remain)
            {
                /* Read more data from file if none available (and reading from file) */
                if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
                {
                    /* Calc read size */
                    pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
                    if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (size_t)pState->read_buf_avail) != pState->read_buf_avail)
                    {
                        mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
                        pState->status = TINFL_STATUS_FAILED;
                        break;
                    }

                    /* Advance offsets, dec counters */
                    pState->cur_file_ofs += pState->read_buf_avail;
                    pState->comp_remaining -= pState->read_buf_avail;
                    pState->read_buf_ofs = 0;
                }

                /* Perform decompression */
                in_buf_size = (size_t)pState->read_buf_avail;
                pState->status = tinfl_decompress(&pState->inflator, (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
                pState->read_buf_avail -= in_buf_size;
                pState->read_buf_ofs += in_buf_size;

                /* Update current output block size remaining */
                pState->out_blk_remain = out_buf_size;
            }

            if (pState->out_blk_remain)
            {
                /* Calc amount to return. */
                size_t to_copy = MZ_MIN( (buf_size - copied_to_caller), pState->out_blk_remain );

                /* Copy data to caller's buffer */
                memcpy( (uint8_t*)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy );

#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
                /* Perform CRC */
                pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
#endif

                /* Decrement data consumed from block */
                pState->out_blk_remain -= to_copy;

                /* Inc output offset, while performing sanity check */
                if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
                {
                    mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
                    pState->status = TINFL_STATUS_FAILED;
                    break;
                }

                /* Increment counter of data copied to caller */
                copied_to_caller += to_copy;
            }
        } while ( (copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)) );
    }

    /* Return how many bytes were copied into user buffer */
    return copied_to_caller;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x40(%rbp)
movq %rsi, -0x48(%rbp)
movq %rdx, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x10545
movq -0x40(%rbp), %rax
cmpq $0x0, (%rax)
je 0x10545
movq -0x40(%rbp), %rax
movq (%rax), %rax
cmpq $0x0, 0x68(%rax)
je 0x10545
cmpq $0x0, -0x48(%rbp)
jne 0x10552
movq $0x0, -0x38(%rbp)
jmp 0x10a02
movq -0x40(%rbp), %rax
movl 0x8(%rax), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x10572
movq -0x40(%rbp), %rax
cmpw $0x0, 0x5e(%rax)
jne 0x106b5
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x1058a
movq -0x50(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x10596
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq 0x68(%rax), %rax
cmpq $0x0, 0x80(%rax)
je 0x105e7
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x4a0(%rax), %rsi
movq -0x58(%rbp), %rdx
callq 0x3280
movq -0x40(%rbp), %rax
movq 0x4a0(%rax), %rcx
addq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x4a0(%rax)
jmp 0x1064d
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq 0x48(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rcx), %rcx
movq 0x60(%rcx), %rdi
movq -0x40(%rbp), %rcx
movq 0x40(%rcx), %rsi
movq -0x48(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq *%rax
cmpq -0x58(%rbp), %rax
je 0x1064b
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x8(%rbp)
movl $0x14, -0xc(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x10638
movl -0xc(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x40(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
movq $0x0, -0x58(%rbp)
jmp 0x1064d
movq -0x40(%rbp), %rax
movl 0x8(%rax), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x1067d
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, %edi
movq -0x48(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0x3910
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
addq 0x40(%rax), %rcx
movq %rcx, 0x40(%rax)
movq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
addq 0x38(%rax), %rcx
movq %rcx, 0x38(%rax)
movq -0x58(%rbp), %rdx
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x30(%rax)
jmp 0x109fa
jmp 0x106b7
movq -0x40(%rbp), %rax
movq 0x4a8(%rax), %rax
movq -0x40(%rbp), %rcx
movq 0x38(%rcx), %rcx
andq $0x7fff, %rcx           # imm = 0x7FFF
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq 0x38(%rax), %rcx
andq $0x7fff, %rcx           # imm = 0x7FFF
movl $0x8000, %eax           # imm = 0x8000
subq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x4b0(%rax)
jne 0x108af
movq -0x40(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jne 0x10815
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq 0x68(%rax), %rax
cmpq $0x0, 0x80(%rax)
jne 0x10815
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x40(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0x10750
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x88(%rbp)
jmp 0x1075f
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq 0x48(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rcx), %rcx
movq 0x60(%rcx), %rdi
movq -0x40(%rbp), %rcx
movq 0x40(%rcx), %rsi
movq -0x40(%rbp), %rcx
movq 0x4a0(%rcx), %rdx
movq -0x40(%rbp), %rcx
movq 0x28(%rcx), %rcx
callq *%rax
movq -0x40(%rbp), %rcx
cmpq 0x28(%rcx), %rax
je 0x107de
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movl $0x14, -0x1c(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x107ce
movl -0x1c(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x40(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
jmp 0x109f8
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
movq -0x40(%rbp), %rax
addq 0x40(%rax), %rcx
movq %rcx, 0x40(%rax)
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rdx
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x30(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rdi
addq $0x4b8, %rdi            # imm = 0x4B8
movq -0x40(%rbp), %rax
movq 0x4a0(%rax), %rsi
movq -0x40(%rbp), %rax
addq 0x20(%rax), %rsi
movq -0x40(%rbp), %rax
movq 0x4a8(%rax), %rcx
movq -0x60(%rbp), %r8
movq -0x40(%rbp), %rax
movq 0x30(%rax), %r9
xorl %eax, %eax
movl $0x2, %edx
cmpq $0x0, %r9
cmovnel %edx, %eax
leaq -0x68(%rbp), %rdx
leaq -0x70(%rbp), %r9
movl %eax, (%rsp)
callq 0x5060
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x68(%rbp), %rdx
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x28(%rax)
movq -0x68(%rbp), %rcx
movq -0x40(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x70(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x4b0(%rax)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x4b0(%rax)
je 0x109a7
movq -0x50(%rbp), %rax
subq -0x58(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x4b0(%rcx), %rax
jae 0x108e7
movq -0x50(%rbp), %rax
subq -0x58(%rbp), %rax
movq %rax, -0x90(%rbp)
jmp 0x108f9
movq -0x40(%rbp), %rax
movq 0x4b0(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x48(%rbp), %rdi
addq -0x58(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq -0x78(%rbp), %rdx
callq 0x3280
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, %edi
movq -0x60(%rbp), %rsi
movq -0x78(%rbp), %rdx
callq 0x3910
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x78(%rbp), %rdx
movq -0x40(%rbp), %rax
movq 0x4b0(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x4b0(%rax)
movq -0x78(%rbp), %rax
movq -0x40(%rbp), %rcx
addq 0x38(%rcx), %rax
movq %rax, 0x38(%rcx)
movq -0x40(%rbp), %rcx
cmpq 0x78(%rcx), %rax
jbe 0x1099b
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movl $0xb, -0x2c(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x1098e
movl -0x2c(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x40(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
jmp 0x109f8
movq -0x78(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x109a9
movq -0x58(%rbp), %rcx
xorl %eax, %eax
cmpq -0x50(%rbp), %rcx
movb %al, -0x91(%rbp)
jae 0x109ea
movq -0x40(%rbp), %rcx
movb $0x1, %al
cmpl $0x1, 0xc(%rcx)
movb %al, -0x92(%rbp)
je 0x109de
movq -0x40(%rbp), %rax
cmpl $0x2, 0xc(%rax)
sete %al
movb %al, -0x92(%rbp)
movb -0x92(%rbp), %al
movb %al, -0x91(%rbp)
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0x106b7
jmp 0x109fa
movq -0x58(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nop