// File: /workspace/github_cpp_makefile_star2_O3/jimmiebergmann[P]fbx-file/miniz.c
// Function: mz_zip_validate_file
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
{
    mz_zip_archive_file_stat file_stat;
    mz_zip_internal_state *pState;
    const mz_uint8 *pCentral_dir_header;
    mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
    mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
    mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
    mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
    mz_uint64 local_header_ofs = 0;
    mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
    mz_uint64 local_header_comp_size, local_header_uncomp_size;
    mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
    mz_bool has_data_descriptor;
    mz_uint32 local_header_bit_flags;

    mz_zip_array file_data_array;
    mz_zip_array_init(&file_data_array, 1);

    if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    if (file_index > pZip->m_total_files)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);

    pState = pZip->m_pState;

    pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);

    if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
        return MZ_FALSE;

    /* A directory or zero length file */
    if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
        return MZ_TRUE;

    /* Encryption and patch files are not supported. */
    if (file_stat.m_is_encrypted)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);

    /* This function only supports stored and deflate. */
    if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);

    if (!file_stat.m_is_supported)
        return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);

    /* Read and parse the local directory entry. */
    local_header_ofs = file_stat.m_local_header_ofs;
    if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
        return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);

    if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
    local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
    local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
    local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
    local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
    local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
    has_data_descriptor = (local_header_bit_flags & 8) != 0;

    if (local_header_filename_len != strlen(file_stat.m_filename))
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
        return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

    if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
        return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);

    if (local_header_filename_len)
    {
        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */
        if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
    {
        mz_uint32 extra_size_remaining = local_header_extra_len;
        const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        do
        {
            mz_uint32 field_id, field_data_size, field_total_size;

            if (extra_size_remaining < (sizeof(mz_uint16) * 2))
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            field_id = MZ_READ_LE16(pExtra_data);
            field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
            field_total_size = field_data_size + sizeof(mz_uint16) * 2;

            if (field_total_size > extra_size_remaining)
                return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);

            if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
            {
                const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);

                if (field_data_size < sizeof(mz_uint64) * 2)
                {
                    mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
                    goto handle_failure;
                }

                local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
                local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64));

                found_zip64_ext_data_in_ldir = MZ_TRUE;
                break;
            }

            pExtra_data += field_total_size;
            extra_size_remaining -= field_total_size;
        } while (extra_size_remaining);
    }

    /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
    /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
    if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
    {
        mz_uint8 descriptor_buf[32];
        mz_bool has_id;
        const mz_uint8 *pSrc;
        mz_uint32 file_crc32;
        mz_uint64 comp_size = 0, uncomp_size = 0;

        mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;

        if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s))
        {
            mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
            goto handle_failure;
        }

        has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
        pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf;

        file_crc32 = MZ_READ_LE32(pSrc);

        if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
        {
            comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
        }
        else
        {
            comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
            uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
        }

        if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }
    else
    {
        if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            goto handle_failure;
        }
    }

    mz_zip_array_clear(pZip, &file_data_array);

    if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
    {
        if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
            return MZ_FALSE;

        /* 1 more check to be sure, although the extract checks too. */
        if (uncomp_crc32 != file_stat.m_crc32)
        {
            mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
            return MZ_FALSE;
        }
    }

    return MZ_TRUE;

handle_failure:
    mz_zip_array_clear(pZip, &file_data_array);
    return MZ_FALSE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x508, %rsp            # imm = 0x508
xorl %ebx, %ebx
movl %ebx, -0x60(%rbp)
movl %ebx, -0x48(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movl $0x1, -0x88(%rbp)
testq %rdi, %rdi
je 0xa344
movq %rdi, %r14
movq 0x68(%rdi), %r13
testq %r13, %r13
je 0xa33c
cmpq $0x0, 0x28(%r14)
je 0xa33c
cmpq $0x0, 0x30(%r14)
je 0xa33c
cmpq $0x0, 0x48(%r14)
je 0xa33c
movl %esi, %r15d
movl 0x10(%r14), %eax
cmpl %esi, %eax
jae 0xa358
movl $0x18, 0x1c(%r14)
movl %ebx, %eax
addq $0x508, %rsp            # imm = 0x508
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %edx, %r12d
xorl %ebx, %ebx
cmpl %r15d, %eax
jbe 0xa372
movq 0x20(%r13), %rax
movl %r15d, %ecx
movl (%rax,%rcx,4), %edx
addq (%r13), %rdx
jmp 0xa374
xorl %edx, %edx
leaq -0x528(%rbp), %rcx
leaq -0x60(%rbp), %r8
movq %r14, %rdi
movl %r15d, %esi
callq 0xa7a9
testl %eax, %eax
je 0xa344
cmpl $0x0, -0x4dc(%rbp)
jne 0xa74c
cmpq $0x0, -0x4f8(%rbp)
je 0xa74c
cmpl $0x0, -0x4d8(%rbp)
je 0xa3bc
movl $0x5, 0x1c(%r14)
jmp 0xa344
movzwl -0x512(%rbp), %eax
testl $0xfff7, %eax           # imm = 0xFFF7
je 0xa3d7
movl $0x4, 0x1c(%r14)
jmp 0xa344
cmpl $0x0, -0x4d4(%rbp)
je 0xa49b
movq -0x4e8(%rbp), %rsi
movq 0x60(%r14), %rdi
leaq -0xc0(%rbp), %rdx
movl $0x1e, %ecx
movq %rsi, -0x30(%rbp)
callq *0x48(%r14)
cmpq $0x1e, %rax
jne 0xa4a8
cmpl $0x4034b50, -0xc0(%rbp) # imm = 0x4034B50
jne 0xa48e
movzwl -0xa6(%rbp), %eax
movq %rax, -0x40(%rbp)
movzwl -0xa4(%rbp), %eax
movq %rax, -0x38(%rbp)
movl -0xae(%rbp), %eax
movq %rax, -0x50(%rbp)
movl -0xaa(%rbp), %eax
movq %rax, -0x58(%rbp)
movl -0xb2(%rbp), %eax
movl %eax, -0x44(%rbp)
movzwl -0xba(%rbp), %eax
movl %eax, -0x5c(%rbp)
leaq -0x4d0(%rbp), %rdi
callq 0x3110
movq -0x40(%rbp), %rsi
cmpq %rsi, %rax
jne 0xa48e
movq -0x30(%rbp), %rax
leaq (%rax,%rsi), %rdx
addq $0x1e, %rdx
movq -0x38(%rbp), %rdi
leaq (%rdx,%rdi), %rcx
movq -0x500(%rbp), %rax
addq %rcx, %rax
cmpq (%r14), %rax
jbe 0xa4b5
movl $0x9, 0x1c(%r14)
jmp 0xa344
movl $0x6, 0x1c(%r14)
jmp 0xa344
movl $0x14, 0x1c(%r14)
jmp 0xa344
movq %rdi, %rax
movq %rdx, -0xc8(%rbp)
movq %rcx, -0xd0(%rbp)
cmpw %ax, %si
cmoval %esi, %eax
testl %eax, %eax
je 0xa4ec
movzwl %ax, %edx
leaq -0xa0(%rbp), %rsi
movq %r14, %rdi
xorl %ecx, %ecx
callq 0xfd63
testl %eax, %eax
je 0xa627
cmpq $0x0, -0x40(%rbp)
je 0xa541
movq -0x30(%rbp), %rsi
addq $0x1e, %rsi
movq 0x60(%r14), %rdi
movq -0xa0(%rbp), %rdx
movq %rdx, -0x30(%rbp)
movq -0x40(%rbp), %rcx
callq *0x48(%r14)
cmpq -0x40(%rbp), %rax
jne 0xa61a
leaq -0x4d0(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x3270
testl %eax, %eax
je 0xa541
movl $0x1e, 0x1c(%r14)
jmp 0xa75a
cmpl $0x0, -0x38(%rbp)
je 0xa5c1
cmpl $-0x1, -0x50(%rbp)
sete %al
cmpl $-0x1, -0x58(%rbp)
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0xa5c1
movq -0xa0(%rbp), %rdx
movq 0x60(%r14), %rdi
movq -0xc8(%rbp), %rsi
movq %rdx, -0x30(%rbp)
movq -0x38(%rbp), %rcx
callq *0x48(%r14)
cmpq -0x38(%rbp), %rax
jne 0xa61a
cmpl $0x3, -0x38(%rbp)
jbe 0xa76e
movq -0x30(%rbp), %rax
movzwl 0x2(%rax), %ecx
leaq 0x4(%rcx), %rax
cmpl %eax, -0x38(%rbp)
jb 0xa76e
movq -0x30(%rbp), %rdx
cmpw $0x1, (%rdx)
je 0xa77b
addq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rcx
subl %eax, %ecx
movq %rcx, -0x38(%rbp)
jne 0xa584
movl $0x0, -0x30(%rbp)
testb $0x8, -0x5c(%rbp)
sete %al
cmpq $0x0, -0x50(%rbp)
setne %cl
cmpl $0x0, -0x44(%rbp)
setne %dl
orb %cl, %dl
orb %al, %dl
je 0xa636
movl -0x44(%rbp), %eax
cmpl -0x508(%rbp), %eax
jne 0xa534
movq -0x50(%rbp), %rax
cmpq -0x500(%rbp), %rax
jne 0xa534
movq -0x58(%rbp), %rax
cmpq -0x4f8(%rbp), %rax
je 0xa6f2
jmp 0xa534
movl $0x14, 0x1c(%r14)
jmp 0xa75a
movl $0x10, 0x1c(%r14)
xorl %ebx, %ebx
jmp 0xa344
xorl %eax, %eax
cmpl $0x0, 0x64(%r13)
setne %al
movq 0x60(%r14), %rdi
movq -0xd0(%rbp), %rsi
addq -0x500(%rbp), %rsi
leaq 0x10(,%rax,8), %rax
cmpb $0x0, -0x30(%rbp)
movl $0x18, %ecx
cmoveq %rax, %rcx
movq %rcx, -0x40(%rbp)
leaq -0x80(%rbp), %rdx
callq *0x48(%r14)
movl $0x14, %esi
cmpq -0x40(%rbp), %rax
jne 0xa756
movl -0x80(%rbp), %esi
movl -0x7c(%rbp), %eax
cmpl $0x0, 0x64(%r13)
sete %dil
cmpl $0x8074b50, %esi        # imm = 0x8074B50
movl %esi, %ecx
cmovel %eax, %ecx
movl -0x30(%rbp), %r8d
notb %r8b
movl -0x78(%rbp), %edx
cmovel %edx, %eax
cmovel -0x74(%rbp), %edx
testb %dil, %r8b
jne 0xa6d3
shlq $0x20, %rdx
orq %rdx, %rax
cmpl $0x8074b50, %esi        # imm = 0x8074B50
movl -0x70(%rbp), %edx
movl -0x74(%rbp), %esi
cmovel %edx, %esi
cmovel -0x6c(%rbp), %edx
shlq $0x20, %rdx
orq %rsi, %rdx
movl $0x1e, %esi
cmpl -0x508(%rbp), %ecx
jne 0xa756
cmpq -0x500(%rbp), %rax
jne 0xa756
cmpq -0x4f8(%rbp), %rdx
jne 0xa756
movq 0x40(%r14), %rdi
movq -0xa0(%rbp), %rsi
callq *0x30(%r14)
btl $0xd, %r12d
jb 0xa74c
leaq 0x358(%rip), %rdx       # 0xaa67
leaq -0x48(%rbp), %rcx
xorl %ebx, %ebx
movq %r14, %rdi
movl %r15d, %esi
xorl %r8d, %r8d
callq 0x9551
testl %eax, %eax
je 0xa344
movl -0x48(%rbp), %eax
movl $0x1, %ebx
cmpl -0x508(%rbp), %eax
je 0xa344
movl $0x1e, 0x1c(%r14)
jmp 0xa62f
movl $0x1, %ebx
jmp 0xa344
movl %esi, 0x1c(%r14)
movq 0x40(%r14), %rdi
movq -0xa0(%rbp), %rsi
callq *0x30(%r14)
jmp 0xa344
movl $0x9, 0x1c(%r14)
jmp 0xa62f
cmpw $0x10, %cx
jae 0xa78b
movl $0x9, 0x1c(%r14)
jmp 0xa75a
movq -0x30(%rbp), %rcx
movq 0x4(%rcx), %rax
movq %rax, -0x58(%rbp)
movq 0xc(%rcx), %rax
movq %rax, -0x50(%rbp)
movb $0x1, %al
movl %eax, -0x30(%rbp)
jmp 0xa5c8