// File: /workspace/github_c_makefile_star2_O1/Cyan4973[P]FiniteStateEntropy/programs/fileio.c
// Function: FIO_decompressFilename
unsigned long long FIO_decompressFilename(const char* output_filename, const char* input_filename)
{
    FILE* finput, *foutput;
    U64   filesize = 0;
    BYTE* in_buff;
    BYTE* out_buff;
    BYTE* ip;
    U32   blockSize;
    XXH32_state_t xxhState;
    typedef size_t (*decompressor_t) (void* dst, size_t dstSize, const void* src, size_t srcSize);
    decompressor_t decompressor = FSE_decompress;

    /* Init */
    XXH32_reset(&xxhState, FSE_CHECKSUM_SEED);
    get_fileHandle(input_filename, output_filename, &finput, &foutput);

    /* check header */
    {   BYTE header[FIO_FRAMEHEADERSIZE];

        { size_t const sizeCheck = fread(header, (size_t)1, FIO_FRAMEHEADERSIZE, finput);
          if (sizeCheck != FIO_FRAMEHEADERSIZE) EXM_THROW(30, "Read error : cannot read header\n"); }

        switch(FIO_readLE32(header))   /* magic number */
        {
        case FIO_magicNumber_fse:
            DISPLAYLEVEL(5, "compressed with fse \n");
            decompressor = FSE_decompress;
            break;
        case FIO_magicNumber_huf:
            DISPLAYLEVEL(5, "compressed with huff0 \n");
            decompressor = HUF_decompress;
            break;
        case FIO_magicNumber_zlibh:
            DISPLAYLEVEL(5, "compressed with zlib's huffman \n");
            decompressor = FIO_ZLIBH_decompress;
            break;
        default :
            EXM_THROW(31, "Wrong file type : unknown header\n");
        }

        {   U32 const blockSizeId = header[4];
            if (blockSizeId > FIO_maxBlockSizeID)
                EXM_THROW(32, "Wrong version : unknown header flags\n");
            blockSize = FIO_blockID_to_blockSize(blockSizeId);
    }   }

    /* Allocate Memory */
    in_buff  = (BYTE*)malloc(blockSize + FIO_maxBlockHeaderSize);
    out_buff = (BYTE*)malloc(blockSize);
    if (!in_buff || !out_buff) EXM_THROW(33, "Allocation error : not enough memory");

    /* read first block header */
    { size_t const sizeCheck = fread(in_buff, 1, 1, finput);
      if (sizeCheck != 1) EXM_THROW(34, "Read error : cannot read header\n");
      ip = in_buff;
    }

    /* Main Loop */
    while (1) {
        size_t rSize=blockSize, cSize;

        /* Decode header */
        int const bType = (ip[0] & (BIT7+BIT6)) >> 6;
        DISPLAYLEVEL(6, "next block type == %i \n", bType);
        DISPLAYLEVEL(7, "read block descriptor : %u \n", ip[0]);
        if (bType == bt_crc) break;   /* end - frame content CRC */

        {   int const fullBlock = ip[0] & BIT5;
            DISPLAYLEVEL(6, "next block is full ? ==> %i \n", !!fullBlock);
            if (!fullBlock) {
                size_t const sizeCheck = fread(in_buff, 1, 2, finput);
                if (sizeCheck != 2) EXM_THROW(35, "Read error : cannot read header\n");
                rSize = (in_buff[0]<<8) + in_buff[1];
        }   }

        switch(bType)
        {
          case bt_compressed :
            {   size_t const sizeCheck = fread(in_buff, 1, 2, finput);
                if (sizeCheck != 2) EXM_THROW(36, "Read error : cannot read header\n");
                cSize = (in_buff[0]<<8) + in_buff[1];
                break;
            }
          case bt_raw :
            cSize = rSize;
            break;
          case bt_rle :
            cSize = 1;
            break;
          default :
          case bt_crc :
            cSize = 0;
            assert(0);   /* supposed already eliminated at this stage */
        }

        DISPLAYLEVEL(6, "next block has a compressed size of %zu, and an original size of %zu \n",
                        cSize, rSize);

        /* Fill input buffer */
        {   size_t const toReadSize = cSize + 1;
            size_t const readSize = fread(in_buff, 1, toReadSize, finput);
            if (readSize != toReadSize) EXM_THROW(38, "Read error");
            ip = in_buff + cSize;   /* end - 1 */
        }

        /* Decode block */
        switch(bType)
        {
          case bt_compressed :
            rSize = decompressor(out_buff, rSize, in_buff, cSize);
            if (FSE_isError(rSize))
                EXM_THROW(39, "Decoding error : %s", FSE_getErrorName(rSize));
            break;
          case bt_raw :
            /* will read directly from in_buff, so no need to memcpy */
            break;
          case bt_rle :
            memset(out_buff, in_buff[0], rSize);
            break;
          default :
          case bt_crc :
            assert(0);   /* supposed already eliminated at this stage */
        }

        /* Write block */
        switch(bType)
        {
          case bt_compressed :
          case bt_rle :
            { size_t const writeSizeCheck = fwrite(out_buff, 1, rSize, foutput);
              if (writeSizeCheck != rSize) EXM_THROW(41, "Write error : unable to write data block to destination file"); }
            XXH32_update(&xxhState, out_buff, rSize);
            filesize += rSize;
            break;
          case bt_raw :
            { size_t const writeSizeCheck = fwrite(in_buff, 1, cSize, foutput);
              if (writeSizeCheck != cSize) EXM_THROW(42, "Write error : unable to write data block to destination file"); }
            XXH32_update(&xxhState, in_buff, cSize);
            filesize += cSize;
            break;
          default :
          case bt_crc :
            assert(0);   /* supposed already eliminated at this stage */
        }
    }

    /* CRC verification */
    { size_t const sizeCheck = fread(ip+1, 1, 2, finput);
      if (sizeCheck != 2) EXM_THROW(43, "Read error"); }
    {   U32 const CRCsaved = ip[2] + (ip[1]<<8) + ((ip[0] & _6BITS) << 16);
        U32 const CRCcalculated = (XXH32_digest(&xxhState) >> 5) & ((1U<<22)-1);
        if (CRCsaved != CRCcalculated) EXM_THROW(44, "CRC error : wrong checksum, corrupted data");
    }

    DISPLAYLEVEL(2, "\r%79s\r", "");
    DISPLAYLEVEL(2, "Decoded %llu bytes\n", (long long unsigned)filesize);

    /* clean */
    free(in_buff);
    free(out_buff);
    fclose(finput);
    fclose(foutput);

    return filesize;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x48(%rsp), %rdi
xorl %esi, %esi
callq 0x5525
leaq 0x40(%rsp), %r15
leaq 0x28(%rsp), %rcx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x4826
movq (%r15), %rcx
leaq 0x13(%rsp), %rdi
movl $0x1, %esi
movl $0x5, %edx
movq %rcx, 0x8(%rsp)
callq 0x1060
cmpq $0x5, %rax
jne 0x4fdd
movl 0x13(%rsp), %ecx
movl 0x14643(%rip), %eax     # 0x190f4
cmpl $0x183e4309, %ecx       # imm = 0x183E4309
je 0x4afd
cmpl $0x183e3309, %ecx       # imm = 0x183E3309
je 0x4ae5
cmpl $0x183e2309, %ecx       # imm = 0x183E2309
jne 0x516a
leaq 0x3a03(%rip), %rcx      # 0x84d7
movq %rcx, 0x18(%rsp)
cmpl $0x5, %eax
jl 0x4b12
callq 0x25eb
jmp 0x4b12
leaq 0xa1a2(%rip), %rcx      # 0xec8e
movq %rcx, 0x18(%rsp)
cmpl $0x5, %eax
jl 0x4b12
callq 0x25c9
jmp 0x4b12
leaq -0xc8(%rip), %rcx       # 0x4a3c
movq %rcx, 0x18(%rsp)
cmpl $0x5, %eax
jge 0x4e3e
movzbl 0x17(%rsp), %ecx
cmpq $0x7, %rcx
jae 0x5020
movl $0x400, %ebx            # imm = 0x400
shlq %cl, %rbx
leaq 0x5(%rbx), %rdi
callq 0x1150
movq %rax, %r13
movl %ebx, %edi
movq %rdi, 0x30(%rsp)
callq 0x1150
testq %r13, %r13
je 0x5063
movq %rax, %r15
testq %rax, %rax
je 0x5063
movl $0x1, %esi
movl $0x1, %edx
movq %r13, %rdi
movq 0x8(%rsp), %rcx
callq 0x1060
cmpq $0x1, %rax
jne 0x50a6
movq 0x28(%rsp), %rax
movq %rax, 0x20(%rsp)
movq %r13, %r14
xorl %r12d, %r12d
movzbl (%r14), %ebx
shrl $0x6, %ebx
cmpl $0x6, 0x1455f(%rip)     # 0x190f4
jge 0x4d31
cmpl $0x7, 0x14552(%rip)     # 0x190f4
jge 0x4d3e
cmpb $0x3, %bl
je 0x4d26
movq %r12, 0x38(%rsp)
movb (%r14), %r14b
andb $0x20, %r14b
cmpl $0x6, 0x14530(%rip)     # 0x190f4
jge 0x4d4b
movq 0x30(%rsp), %rbp
testb %r14b, %r14b
jne 0x4c01
movl $0x1, %esi
movl $0x2, %edx
movq %r13, %rdi
movq 0x8(%rsp), %rcx
callq 0x1060
cmpq $0x2, %rax
jne 0x4f11
movzwl (%r13), %eax
rolw $0x8, %ax
movzwl %ax, %ebp
cmpl $0x2, %ebx
je 0x4c3e
movq %rbp, %r14
cmpl $0x1, %ebx
je 0x4c44
movl $0x1, %esi
movl $0x2, %edx
movq %r13, %rdi
movq 0x8(%rsp), %rcx
callq 0x1060
cmpq $0x2, %rax
jne 0x4f54
movzwl (%r13), %eax
rolw $0x8, %ax
movzwl %ax, %r14d
jmp 0x4c44
movl $0x1, %r14d
movq %r15, %r12
cmpl $0x6, 0x144a6(%rip)     # 0x190f4
jge 0x4d59
leaq 0x1(%r14), %r15
movl $0x1, %esi
movq %r13, %rdi
movq %r15, %rdx
movq 0x8(%rsp), %rcx
callq 0x1060
cmpq %r15, %rax
jne 0x4e48
cmpb $0x2, %bl
movq %r12, %r15
je 0x4caa
movzbl %bl, %eax
cmpl $0x1, %eax
je 0x4cba
movq %r15, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %r14, %rcx
callq *0x18(%rsp)
movq %rax, %rbp
movq %rax, %rdi
callq 0x70ca
testl %eax, %eax
je 0x4cba
jmp 0x4f97
movzbl (%r13), %esi
movq %r15, %rdi
movq %rbp, %rdx
callq 0x10c0
movl $0x1, %esi
cmpb $0x1, %bl
jne 0x4cf2
movq %r13, %rdi
movq %r14, %rdx
movq 0x20(%rsp), %rcx
callq 0x1190
cmpq %r14, %rax
jne 0x4ece
leaq 0x48(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x55b1
movq %r14, %rbp
jmp 0x4d1b
movq %r15, %rdi
movq %rbp, %rdx
movq 0x20(%rsp), %rcx
callq 0x1190
cmpq %rbp, %rax
jne 0x4e8b
leaq 0x48(%rsp), %rdi
movq %r15, %rsi
movq %rbp, %rdx
callq 0x55b1
addq %r13, %r14
movq 0x38(%rsp), %r12
addq %rbp, %r12
cmpb $0x3, %bl
jne 0x4b87
jmp 0x4d7c
movzbl %bl, %edi
callq 0x2693
jmp 0x4b9b
movq %r14, %rdi
callq 0x26b5
jmp 0x4ba8
movzbl %r14b, %edi
callq 0x26d9
jmp 0x4bca
movq 0x14298(%rip), %rax     # 0x18ff8
movq (%rax), %rdi
leaq 0xdefb(%rip), %rsi      # 0x12c65
movq %r14, %rdx
movq %rbp, %rcx
xorl %eax, %eax
callq 0x1110
jmp 0x4c54
leaq 0x1(%r14), %rdi
movl $0x1, %esi
movl $0x2, %edx
movq 0x8(%rsp), %rcx
callq 0x1060
cmpq $0x2, %rax
jne 0x50e9
movzwl 0x1(%r14), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movzbl (%r14), %ebx
andl $0x3f, %ebx
shll $0x10, %ebx
orl %eax, %ebx
leaq 0x48(%rsp), %rdi
callq 0x5740
shrl $0x5, %eax
andl $0x3fffff, %eax         # imm = 0x3FFFFF
movl 0x14326(%rip), %ecx     # 0x190f4
cmpl %eax, %ebx
jne 0x512c
cmpl $0x2, %ecx
jge 0x4e1a
cmpl $0x2, 0x14312(%rip)     # 0x190f4
jge 0x4e21
movq %r13, %rdi
callq 0x1030
movq %r15, %rdi
callq 0x1030
movq 0x40(%rsp), %rdi
callq 0x1080
movq 0x28(%rsp), %rdi
callq 0x1080
movq %r12, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x291e
jmp 0x4ddb
movq 0x141d0(%rip), %rax     # 0x18ff8
movq (%rax), %rdi
leaq 0xdf01(%rip), %rsi      # 0x12d33
movq %r12, %rdx
xorl %eax, %eax
callq 0x1110
jmp 0x4de4
callq 0x25a7
jmp 0x4b12
cmpl $0x0, 0x142a5(%rip)     # 0x190f4
jle 0x4e56
callq 0x2788
cmpl $0x0, 0x14297(%rip)     # 0x190f4
jle 0x4e64
callq 0x27a9
cmpl $0x0, 0x14289(%rip)     # 0x190f4
jle 0x4e81
movq 0x14184(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x26, %edi
callq 0x1180
cmpl $0x0, 0x14262(%rip)     # 0x190f4
jle 0x4e99
callq 0x2812
cmpl $0x0, 0x14254(%rip)     # 0x190f4
jle 0x4ea7
callq 0x2833
cmpl $0x0, 0x14246(%rip)     # 0x190f4
jle 0x4ec4
movq 0x14141(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x29, %edi
callq 0x1180
cmpl $0x0, 0x1421f(%rip)     # 0x190f4
jle 0x4edc
callq 0x2855
cmpl $0x0, 0x14211(%rip)     # 0x190f4
jle 0x4eea
callq 0x2876
cmpl $0x0, 0x14203(%rip)     # 0x190f4
jle 0x4f07
movq 0x140fe(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x2a, %edi
callq 0x1180
cmpl $0x0, 0x141dc(%rip)     # 0x190f4
jle 0x4f1f
callq 0x2702
cmpl $0x0, 0x141ce(%rip)     # 0x190f4
jle 0x4f2d
callq 0x2723
cmpl $0x0, 0x141c0(%rip)     # 0x190f4
jle 0x4f4a
movq 0x140bb(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x23, %edi
callq 0x1180
cmpl $0x0, 0x14199(%rip)     # 0x190f4
jle 0x4f62
callq 0x2745
cmpl $0x0, 0x1418b(%rip)     # 0x190f4
jle 0x4f70
callq 0x2766
cmpl $0x0, 0x1417d(%rip)     # 0x190f4
jle 0x4f8d
movq 0x14078(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x24, %edi
callq 0x1180
cmpl $0x0, 0x14156(%rip)     # 0x190f4
jle 0x4fa5
callq 0x27cb
cmpl $0x0, 0x14148(%rip)     # 0x190f4
jle 0x4fb6
movq %rbp, %rdi
callq 0x27ec
cmpl $0x0, 0x14137(%rip)     # 0x190f4
jle 0x4fd3
movq 0x14032(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x27, %edi
callq 0x1180
cmpl $0x0, 0x14110(%rip)     # 0x190f4
jle 0x4feb
callq 0x2564
cmpl $0x0, 0x14102(%rip)     # 0x190f4
jle 0x4ff9
callq 0x2585
cmpl $0x0, 0x140f4(%rip)     # 0x190f4
jle 0x5016
movq 0x13fef(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x1e, %edi
callq 0x1180
cmpl $0x0, 0x140cd(%rip)     # 0x190f4
jle 0x502e
callq 0x2943
cmpl $0x0, 0x140bf(%rip)     # 0x190f4
jle 0x503c
callq 0x2964
cmpl $0x0, 0x140b1(%rip)     # 0x190f4
jle 0x5059
movq 0x13fac(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x20, %edi
callq 0x1180
cmpl $0x0, 0x1408a(%rip)     # 0x190f4
jle 0x5071
callq 0x260d
cmpl $0x0, 0x1407c(%rip)     # 0x190f4
jle 0x507f
callq 0x262e
cmpl $0x0, 0x1406e(%rip)     # 0x190f4
jle 0x509c
movq 0x13f69(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x21, %edi
callq 0x1180
cmpl $0x0, 0x14047(%rip)     # 0x190f4
jle 0x50b4
callq 0x2650
cmpl $0x0, 0x14039(%rip)     # 0x190f4
jle 0x50c2
callq 0x2671
cmpl $0x0, 0x1402b(%rip)     # 0x190f4
jle 0x50df
movq 0x13f26(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x22, %edi
callq 0x1180
cmpl $0x0, 0x14004(%rip)     # 0x190f4
jle 0x50f7
callq 0x2898
cmpl $0x0, 0x13ff6(%rip)     # 0x190f4
jle 0x5105
callq 0x28b9
cmpl $0x0, 0x13fe8(%rip)     # 0x190f4
jle 0x5122
movq 0x13ee3(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x2b, %edi
callq 0x1180
testl %ecx, %ecx
jle 0x5135
callq 0x28db
cmpl $0x0, 0x13fb8(%rip)     # 0x190f4
jle 0x5143
callq 0x28fc
cmpl $0x0, 0x13faa(%rip)     # 0x190f4
jle 0x5160
movq 0x13ea5(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x2c, %edi
callq 0x1180
testl %eax, %eax
jle 0x5173
callq 0x2986
cmpl $0x0, 0x13f7a(%rip)     # 0x190f4
jle 0x5181
callq 0x29a7
cmpl $0x0, 0x13f6c(%rip)     # 0x190f4
jle 0x519e
movq 0x13e67(%rip), %rax     # 0x18ff8
movq (%rax), %rsi
movl $0xa, %edi
callq 0x10d0
movl $0x1f, %edi
callq 0x1180