// File: /workspace/github_c_makefile_star2_O2/DavidSM64[P]n64graphics_ci/n64graphics_ci.c
// Function: main
int main(int argc, char* argv[])
{
    graphics_config config = default_config;
    rgba *imgr;
    ia   *imgi;
    FILE *fp;
    uint8_t *raw;
    int raw_size;
    int length = 0;
    int flength;
    int res;
    FILE *fp_pal; // for ci palette
    uint8_t *pal;
    int pal_len;
    char* pal_bin_filename;

    int valid = parse_arguments(argc, argv, &config);
    if (!valid || !config.bin_filename || !config.bin_filename || !config.img_filename) {
        print_usage();
        exit(EXIT_FAILURE);
    }

    if (config.mode == MODE_IMPORT) {
        printf("%s\n", config.bin_filename);
        if (config.truncate) {
            fp = fopen(config.bin_filename, "w");
        }
        else {
            fp = fopen(config.bin_filename, "r+");
        }
        if (!fp) {
            ERROR("Error opening binary file \"%s\"\n", config.bin_filename);
            return -1;
        }
        if (!config.truncate) {
            fseek(fp, config.offset, SEEK_SET);
        }
        switch (config.format) {
        case IMG_FORMAT_CI:
            imgr = png2rgba(config.img_filename, &config.width, &config.height);
            raw_size = config.width * config.height * config.depth / 8;
            raw = malloc(raw_size);
            if (!raw) {
                ERROR("Error allocating %u bytes\n", raw_size);
            }
            if (config.depth == 4) {
                pal_len = 16 * 2; // CI4
            }
            else {
                pal_len = 256 * 2; // CI8
            }
            pal = malloc(pal_len);
            if (!pal) {
                ERROR("Error allocating %u bytes for palette\n", pal_len);
            }
            length = rgba2rawci(raw, pal, &pal_len, imgr, config.width, config.height, config.depth);
            //length = rgba2raw(raw, imgr, config.width, config.height, config.depth);
            break;
        }
        if (length <= 0) {
            ERROR("Error converting to raw format\n");
            return EXIT_FAILURE;
        }
        INFO("Writing 0x%X bytes to offset 0x%X of \"%s\"\n", length, config.offset, config.bin_filename);
        flength = fwrite(raw, 1, length, fp);
        if (flength != length) {
            ERROR("Error writing %d bytes to \"%s\"\n", length, config.bin_filename);
        }
        fclose(fp);

        if (config.format == IMG_FORMAT_CI) {
            pal_bin_filename = getPaletteFilename(config.bin_filename);

            fp_pal = fopen(pal_bin_filename, "w");
            INFO("Writing 0x%X bytes to palette file \"%s\"\n", pal_len, pal_bin_filename);
            flength = fwrite(pal, 1, pal_len, fp_pal);
            if (flength != pal_len) {
                ERROR("Error writing %d bytes to \"%s\"\n", pal_len, pal_bin_filename);
            }
            fclose(fp_pal);
            free(pal_bin_filename);
        }
    } else { // Export
        if (config.width <= 0 || config.height <= 0 || config.depth <= 0) {
            ERROR("Error: must set position width and height for export\n");
            return EXIT_FAILURE;
        }
        fp = fopen(config.bin_filename, "r");
        if (!fp) {
            ERROR("Error opening \"%s\"\n", config.bin_filename);
            return -1;
        }
        raw_size = config.width * config.height * config.depth / 8;
        raw = malloc(raw_size);
        if (config.offset > 0) {
            fseek(fp, config.offset, SEEK_SET);
        }
        flength = fread(raw, 1, raw_size, fp);
        if (flength != raw_size) {
            ERROR("Error reading %d bytes from \"%s\"\n", raw_size, config.bin_filename);
        }
        switch (config.format) {
        case IMG_FORMAT_CI:
            // Read Palette file
            pal_bin_filename = getPaletteFilename(config.bin_filename);
            fp_pal = fopen(pal_bin_filename, "r");
            if (!fp_pal) {
                ERROR("Error opening \"%s\"\n", pal_bin_filename);
                return -1;
            }
            if (config.depth == 4) {
                pal_len = 16 * 2; // CI4
            }
            else {
                pal_len = 256 * 2; // CI8
            }

            pal = malloc(pal_len);
            if (config.offset > 0) {
                fseek(fp, config.offset, SEEK_SET);
            }
            flength = fread(pal, 1, pal_len, fp_pal);

            imgr = rawci2rgba(raw, pal, config.width, config.height, config.depth);
            res = rgba2png(config.img_filename, imgr, config.width, config.height);

            free(pal_bin_filename);
            break;
        default:
            return EXIT_FAILURE;
        }
        if (!res) {
            ERROR("Error writing to \"%s\"\n", config.img_filename);
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
leaq -0x88(%rbp), %rax
andq $0x0, 0x8(%rax)
movq %rsi, -0x30(%rbp)
movl %edi, %r15d
pushq $0x1
popq %rdx
pushq $0x20
popq %rax
movq $0x0, -0x70(%rbp)
pushq $0x8
popq %rcx
movl %ecx, -0x34(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x60(%rbp)
movl %edx, %ecx
movq %rcx, -0x68(%rbp)
movq $0x0, -0x40(%rbp)
movq %rax, -0x58(%rbp)
movq %rax, -0x48(%rbp)
movl %edx, %r13d
cmpl %r15d, %r13d
jge 0x7315
movslq %r13d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rax
cmpb $0x2d, (%rax)
jne 0x7315
movzbl 0x1(%rax), %eax
leal -0x65(%rax), %ecx
cmpl $0x12, %ecx
ja 0x730c
leaq 0xa0df(%rip), %rdx      # 0x11288
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0x70(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1250
movq %rax, -0x48(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, -0x50(%rbp)
pushq $0x1
popq %rax
movq %rax, -0x70(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rdi
movq $0x0, -0x68(%rbp)
xorl %esi, %esi
xorl %edx, %edx
callq 0x1250
movq %rax, -0x40(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rax
movq %rax, -0x60(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1250
movq %rax, -0x58(%rbp)
jmp 0x7301
leal 0x1(%r13), %r12d
cmpl %r15d, %r12d
jge 0x7315
movslq %r12d, %rax
movq -0x30(%rbp), %rcx
movq (%rcx,%rax,8), %r14
xorl %ecx, %ecx
leaq 0x10(%rcx), %rbx
cmpq $0x30, %rbx
je 0x7315
leaq 0x10ae2(%rip), %rax     # 0x17db0
movq (%rcx,%rax), %rsi
movq %r14, %rdi
callq 0x1050
movq %rbx, %rcx
testl %eax, %eax
jne 0x72bd
leaq 0x10ac8(%rip), %rax     # 0x17db0
movl -0x4(%rbx,%rax), %eax
movl %eax, -0x34(%rbp)
jmp 0x7301
leaq 0x10ef0(%rip), %rax     # 0x181e8
movl $0x1, (%rax)
movl %r13d, %r12d
incl %r12d
movl %r12d, %r13d
jmp 0x7175
cmpl $0x56, %eax
je 0x77f4
andl $0x0, -0x90(%rbp)
movq -0x48(%rbp), %rax
movl %eax, -0x88(%rbp)
movq -0x40(%rbp), %rax
movl %eax, -0x94(%rbp)
movq -0x68(%rbp), %rax
movl %eax, -0x80(%rbp)
movq -0x58(%rbp), %r14
movl %r14d, -0x84(%rbp)
movq -0x60(%rbp), %rbx
movq %rbx, -0xa8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x70(%rbp), %rcx
movl %ecx, -0x98(%rbp)
movl -0x34(%rbp), %r12d
movl %r12d, -0x8c(%rbp)
cmpl %r15d, %r13d
jl 0x77e7
movq %rax, %r15
testq %rax, %rax
je 0x77e7
testq %rbx, %rbx
je 0x77e7
cmpl $0x1, %ecx
jne 0x73c2
movq %r15, %rdi
callq 0x1090
cmpl $0x0, -0x68(%rbp)
je 0x751b
leaq 0xc1f3(%rip), %rsi      # 0x1359c
movq %r15, %rdi
callq 0x1230
movq %rax, %r14
testq %rax, %rax
jne 0x7543
jmp 0x76cf
cmpl $0x0, -0x48(%rbp)
jle 0x76ee
testl %r14d, %r14d
jle 0x76ee
testl %r12d, %r12d
jle 0x76ee
leaq 0xc405(%rip), %rsi      # 0x137ea
movq %r15, %rdi
callq 0x1230
testq %rax, %rax
je 0x76bc
movq %rax, %rbx
imull -0x48(%rbp), %r14d
imull %r12d, %r14d
shrl $0x3, %r14d
movq %r14, %rdi
callq 0x11d0
movq %rax, %r13
movq -0x40(%rbp), %rax
movl %eax, %r12d
testl %eax, %eax
je 0x7429
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x11f0
pushq $0x1
popq %rsi
movq %r13, %rdi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x10a0
cmpl %eax, %r14d
jne 0x777a
movq %r15, %rdi
callq 0x708e
movq %rax, %r15
leaq 0xc395(%rip), %rsi      # 0x137ea
movq %rax, %rdi
callq 0x1230
testq %rax, %rax
je 0x76bc
movq %rax, %r14
movq %r15, -0x50(%rbp)
movq %r13, -0x30(%rbp)
cmpl $0x4, -0x34(%rbp)
pushq $0x20
popq %rax
movl $0x200, %r15d           # imm = 0x200
cmoveq %rax, %r15
movq %r15, %rdi
callq 0x11d0
movq %rax, %r13
cmpl $0x0, -0x40(%rbp)
je 0x74a0
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x11f0
pushq $0x1
popq %rsi
movq %r13, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x10a0
movq -0x30(%rbp), %rdi
movq %r13, %rsi
movq -0x48(%rbp), %r14
movl %r14d, %edx
movq -0x58(%rbp), %rbx
movl %ebx, %ecx
movl -0x34(%rbp), %r8d
callq 0x6ab6
movq -0x60(%rbp), %r15
movq %r15, %rdi
movq %rax, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x6f7a
movl %eax, %r14d
movq -0x50(%rbp), %rdi
callq 0x1040
xorl %ebx, %ebx
testl %r14d, %r14d
jne 0x7766
movq 0x10af0(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xc1de(%rip), %rsi      # 0x136e8
xorl %ebx, %ebx
movq %r15, %rdx
xorl %eax, %eax
callq 0x1170
jmp 0x7766
leaq 0xc07c(%rip), %rsi      # 0x1359e
movq %r15, %rdi
callq 0x1230
testq %rax, %rax
je 0x76cf
movq %rax, %r14
movl -0x40(%rbp), %esi
movq %rax, %rdi
xorl %edx, %edx
callq 0x11f0
movq %r14, -0x48(%rbp)
movq %rbx, %rdi
leaq -0x88(%rbp), %rsi
leaq -0x84(%rbp), %rdx
callq 0x6d66
movq %rax, -0x30(%rbp)
movl -0x8c(%rbp), %ebx
movl -0x88(%rbp), %r13d
movl -0x84(%rbp), %r15d
movl %r15d, %eax
imull %r13d, %eax
imull %ebx, %eax
pushq $0x8
popq %rcx
cltd
idivl %ecx
movl %eax, %r14d
movslq %eax, %rdi
callq 0x11d0
movq %rax, %r12
testq %rax, %rax
je 0x7703
cmpl $0x4, %ebx
pushq $0x20
popq %rax
movl $0x200, %r14d           # imm = 0x200
cmovel %eax, %r14d
movl %r14d, -0x74(%rbp)
movq %r14, %rdi
callq 0x11d0
testq %rax, %rax
movq %rax, -0x40(%rbp)
je 0x7723
movl %ebx, (%rsp)
leaq -0x74(%rbp), %rdx
movq %r12, %rdi
movq %rax, %rsi
movq -0x30(%rbp), %rcx
movl %r13d, %r8d
movl %r15d, %r9d
callq 0x6bc4
testl %eax, %eax
jle 0x7747
movl %eax, %r15d
leaq 0x10bf5(%rip), %rax     # 0x181e8
cmpl $0x0, (%rax)
je 0x7616
movl -0x94(%rbp), %edx
movq -0xa0(%rbp), %rcx
leaq 0xbffc(%rip), %rdi      # 0x13608
movl %r15d, %esi
xorl %eax, %eax
callq 0x10e0
movl %r15d, %edx
pushq $0x1
popq %rsi
movq %r12, %rdi
movq -0x48(%rbp), %rbx
movq %rbx, %rcx
callq 0x1280
cmpl %eax, %r15d
jne 0x779d
movq %rbx, %rdi
callq 0x10b0
xorl %ebx, %ebx
cmpl $0x0, -0x90(%rbp)
jne 0x7766
movq -0xa0(%rbp), %rdi
callq 0x708e
movq %rax, %r15
leaq 0xbf3b(%rip), %rsi      # 0x1359c
movq %rax, %rdi
callq 0x1230
movq %rax, %r12
leaq 0x10b75(%rip), %rax     # 0x181e8
cmpl $0x0, (%rax)
je 0x768c
leaq 0xbfd4(%rip), %rdi      # 0x13653
movl %r14d, %esi
movq %r15, %rdx
xorl %eax, %eax
callq 0x10e0
movl %r14d, %edx
pushq $0x1
popq %rsi
movq -0x40(%rbp), %rdi
movq %r12, %rcx
callq 0x1280
cmpl %eax, %r14d
jne 0x77c4
movq %r12, %rdi
callq 0x10b0
movq %r15, %rdi
callq 0x1040
jmp 0x7766
movq 0x1092d(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbfe5(%rip), %rsi      # 0x136b2
jmp 0x76e0
movq 0x1091a(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbec1(%rip), %rsi      # 0x135a1
movq %r15, %rdx
xorl %eax, %eax
callq 0x1170
pushq $-0x1
jmp 0x7765
movq 0x108fb(%rip), %rax     # 0x17ff0
movq (%rax), %rcx
leaq 0xbf7d(%rip), %rdi      # 0x1367c
pushq $0x35
jmp 0x775a
movq 0x108e6(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbd79(%rip), %rsi      # 0x1348d
movl %r14d, %edx
xorl %eax, %eax
callq 0x1170
jmp 0x759c
movq 0x108c6(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbe8d(%rip), %rsi      # 0x135c1
movl %r14d, %edx
xorl %eax, %eax
callq 0x1170
movq -0x40(%rbp), %rax
jmp 0x75c5
movq 0x108a2(%rip), %rax     # 0x17ff0
movq (%rax), %rcx
leaq 0xbe90(%rip), %rdi      # 0x135e8
pushq $0x1f
popq %rsi
pushq $0x1
popq %rdx
callq 0x1280
pushq $0x1
popq %rbx
movl %ebx, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1086f(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbf3b(%rip), %rsi      # 0x136c6
movl %r14d, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x1170
jmp 0x7443
movq 0x1084c(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movq -0xa0(%rbp), %rcx
leaq 0xbe7e(%rip), %rsi      # 0x13633
movl %r15d, %edx
xorl %eax, %eax
callq 0x1170
jmp 0x7634
movq 0x10825(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xbe5e(%rip), %rsi      # 0x13633
movl %r14d, %edx
movq %r15, %rcx
xorl %eax, %eax
callq 0x1170
jmp 0x76a7
callq 0x7800
pushq $0x1
popq %rdi
callq 0x1270
callq 0x1038e
xorl %edi, %edi
callq 0x1270