// File: /workspace/github_cpp_makefile_star2_O2/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
andl $0x0, -0x60(%rbp)
andl $0x0, -0x48(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movl $0x1, -0x88(%rbp)
xorl %ebx, %ebx
testq %rdi, %rdi
je 0xa234
movq %rdi, %r14
movq 0x68(%rdi), %r13
testq %r13, %r13
je 0xa22c
cmpq $0x0, 0x28(%r14)
je 0xa22c
cmpq $0x0, 0x30(%r14)
je 0xa22c
cmpq $0x0, 0x48(%r14)
je 0xa22c
movl %esi, %r15d
movl 0x10(%r14), %eax
cmpl %esi, %eax
jae 0xa248
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 0xa262
movq 0x20(%r13), %rax
movl %r15d, %ecx
movl (%rax,%rcx,4), %edx
addq (%r13), %rdx
jmp 0xa264
xorl %edx, %edx
leaq -0x528(%rbp), %rcx
leaq -0x60(%rbp), %r8
movq %r14, %rdi
movl %r15d, %esi
callq 0xa693
testl %eax, %eax
je 0xa234
cmpl $0x0, -0x4dc(%rbp)
pushq $0x1
popq %rax
jne 0xa651
cmpq $0x0, -0x4f8(%rbp)
je 0xa651
cmpl $0x0, -0x4d8(%rbp)
je 0xa2af
movl $0x5, 0x1c(%r14)
jmp 0xa234
movzwl -0x512(%rbp), %eax
testw $0xfff7, %ax            # imm = 0xFFF7
je 0xa2c9
movl $0x4, 0x1c(%r14)
jmp 0xa234
cmpl $0x0, -0x4d4(%rbp)
je 0xa38b
movq -0x4e8(%rbp), %rsi
movq 0x60(%r14), %rdi
leaq -0xc0(%rbp), %rdx
pushq $0x1e
popq %rcx
movq %rsi, -0x30(%rbp)
callq *0x48(%r14)
cmpq $0x1e, %rax
jne 0xa398
cmpl $0x4034b50, -0xc0(%rbp) # imm = 0x4034B50
jne 0xa37e
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 0x3100
movq -0x40(%rbp), %rsi
cmpq %rsi, %rax
jne 0xa37e
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 0xa3a5
movl $0x9, 0x1c(%r14)
jmp 0xa234
movl $0x6, 0x1c(%r14)
jmp 0xa234
movl $0x14, 0x1c(%r14)
jmp 0xa234
movq %rdi, %rax
movq %rdx, -0xc8(%rbp)
movq %rcx, -0xd0(%rbp)
cmpw %ax, %si
cmoval %esi, %eax
testl %eax, %eax
je 0xa3dc
movzwl %ax, %edx
leaq -0xa0(%rbp), %rsi
movq %r14, %rdi
xorl %ecx, %ecx
callq 0xf595
testl %eax, %eax
je 0xa517
cmpq $0x0, -0x40(%rbp)
je 0xa431
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 0xa50a
leaq -0x4d0(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x3280
testl %eax, %eax
je 0xa431
movl $0x1e, 0x1c(%r14)
jmp 0xa63a
cmpl $0x0, -0x38(%rbp)
je 0xa4b1
cmpl $-0x1, -0x50(%rbp)
sete %al
cmpl $-0x1, -0x58(%rbp)
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0xa4b1
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 0xa50a
cmpl $0x3, -0x38(%rbp)
jbe 0xa658
movq -0x30(%rbp), %rax
movzwl 0x2(%rax), %ecx
leaq 0x4(%rcx), %rax
cmpl %eax, -0x38(%rbp)
jb 0xa658
movq -0x30(%rbp), %rdx
cmpw $0x1, (%rdx)
je 0xa665
addq %rax, -0x30(%rbp)
movq -0x38(%rbp), %rcx
subl %eax, %ecx
movq %rcx, -0x38(%rbp)
jne 0xa474
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 0xa526
movl -0x44(%rbp), %eax
cmpl -0x508(%rbp), %eax
jne 0xa424
movq -0x50(%rbp), %rax
cmpq -0x500(%rbp), %rax
jne 0xa424
movq -0x58(%rbp), %rax
cmpq -0x4f8(%rbp), %rax
je 0xa5d9
jmp 0xa424
movl $0x14, 0x1c(%r14)
jmp 0xa63a
movl $0x10, 0x1c(%r14)
xorl %ebx, %ebx
jmp 0xa234
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)
pushq $0x18
popq %rcx
cmoveq %rax, %rcx
movq %rcx, -0x40(%rbp)
leaq -0x80(%rbp), %rdx
callq *0x48(%r14)
cmpq -0x40(%rbp), %rax
jne 0xa633
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 0xa5bc
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
pushq $0x1e
popq %rsi
cmpl -0x508(%rbp), %ecx
jne 0xa636
cmpq -0x500(%rbp), %rax
jne 0xa636
cmpq -0x4f8(%rbp), %rdx
jne 0xa636
movq 0x40(%r14), %rdi
movq -0xa0(%rbp), %rsi
callq *0x30(%r14)
btl $0xd, %r12d
jb 0xa64e
leaq 0x36c(%rip), %rdx       # 0xa962
leaq -0x48(%rbp), %rcx
xorl %ebx, %ebx
movq %r14, %rdi
movl %r15d, %esi
xorl %r8d, %r8d
callq 0x948d
testl %eax, %eax
je 0xa234
movl -0x48(%rbp), %eax
pushq $0x1
popq %rcx
movl %ecx, %ebx
cmpl -0x508(%rbp), %eax
je 0xa234
movl $0x1e, 0x1c(%r14)
jmp 0xa51f
pushq $0x14
popq %rsi
movl %esi, 0x1c(%r14)
movq 0x40(%r14), %rdi
movq -0xa0(%rbp), %rsi
callq *0x30(%r14)
jmp 0xa234
pushq $0x1
popq %rax
movl %eax, %ebx
jmp 0xa234
movl $0x9, 0x1c(%r14)
jmp 0xa51f
cmpw $0x10, %cx
jae 0xa675
movl $0x9, 0x1c(%r14)
jmp 0xa63a
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 0xa4b8