// File: /workspace/github_c_makefile_star2_O0/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
subq $0xa0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x1110
movl $0x8, -0x24(%rbp)
movl $0x20, -0x20(%rbp)
movl $0x20, -0x1c(%rbp)
movl $0x1, -0x18(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0xa710
movl %eax, -0x94(%rbp)
cmpl $0x0, -0x94(%rbp)
je 0xa1f0
cmpq $0x0, -0x38(%rbp)
je 0xa1f0
cmpq $0x0, -0x38(%rbp)
je 0xa1f0
cmpq $0x0, -0x40(%rbp)
jne 0xa1ff
callq 0xa990
movl $0x1, %edi
callq 0x1260
cmpl $0x1, -0x30(%rbp)
jne 0xa4ce
movq -0x38(%rbp), %rsi
leaq 0x19a66(%rip), %rdi     # 0x23c7a
movb $0x0, %al
callq 0x10d0
cmpl $0x0, -0x18(%rbp)
je 0xa237
movq -0x38(%rbp), %rdi
leaq 0x18d89(%rip), %rsi     # 0x22fb5
callq 0x1220
movq %rax, -0x58(%rbp)
jmp 0xa24b
movq -0x38(%rbp), %rdi
leaq 0x18d75(%rip), %rsi     # 0x22fb7
callq 0x1220
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0xa27a
movq 0x1dd97(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movq -0x38(%rbp), %rdx
leaq 0x18d53(%rip), %rsi     # 0x22fba
movb $0x0, %al
callq 0x1170
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa6f7
cmpl $0x0, -0x18(%rbp)
jne 0xa290
movq -0x58(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x11e0
movl -0x28(%rbp), %eax
testl %eax, %eax
jne 0xa379
jmp 0xa29d
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
addq $0x20, %rsi
leaq -0x40(%rbp), %rdx
addq $0x24, %rdx
callq 0x9bf0
movq %rax, -0x48(%rbp)
movl -0x20(%rbp), %eax
imull -0x1c(%rbp), %eax
imull -0x24(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, -0x64(%rbp)
movslq -0x64(%rbp), %rdi
callq 0x11d0
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0xa2ff
movq 0x1dd05(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl -0x64(%rbp), %edx
leaq 0x18bae(%rip), %rsi     # 0x22ea6
movb $0x0, %al
callq 0x1170
cmpl $0x4, -0x24(%rbp)
jne 0xa311
movl $0x20, -0x84(%rbp)
jmp 0xa31b
movl $0x200, -0x84(%rbp)     # imm = 0x200
movslq -0x84(%rbp), %rdi
callq 0x11d0
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0xa350
movq 0x1dcb7(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl -0x84(%rbp), %edx
leaq 0x18c91(%rip), %rsi     # 0x22fda
movb $0x0, %al
callq 0x1170
movq -0x60(%rbp), %rdi
movq -0x80(%rbp), %rsi
movq -0x48(%rbp), %rcx
movl -0x20(%rbp), %r8d
movl -0x1c(%rbp), %r9d
movl -0x24(%rbp), %eax
leaq -0x84(%rbp), %rdx
movl %eax, (%rsp)
callq 0x9980
movl %eax, -0x68(%rbp)
cmpl $0x0, -0x68(%rbp)
jg 0xa3a3
movq 0x1dc6a(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
leaq 0x18c71(%rip), %rsi     # 0x23001
movb $0x0, %al
callq 0x1170
movl $0x1, -0x4(%rbp)
jmp 0xa6f7
leaq 0x1e39e(%rip), %rax     # 0x28748
cmpl $0x0, (%rax)
je 0xa3c7
movl -0x68(%rbp), %esi
movl -0x2c(%rbp), %edx
movq -0x38(%rbp), %rcx
leaq 0x18c61(%rip), %rdi     # 0x23021
movb $0x0, %al
callq 0x10d0
movq -0x60(%rbp), %rdi
movslq -0x68(%rbp), %rdx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x1270
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x68(%rbp), %eax
je 0xa407
movq 0x1dc01(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl -0x68(%rbp), %edx
movq -0x38(%rbp), %rcx
leaq 0x18c4c(%rip), %rsi     # 0x2304c
movb $0x0, %al
callq 0x1170
movq -0x58(%rbp), %rdi
callq 0x10a0
cmpl $0x0, -0x28(%rbp)
jne 0xa4c9
movq -0x38(%rbp), %rdi
callq 0xa0a0
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
leaq 0x18b7d(%rip), %rsi     # 0x22fb5
callq 0x1220
movq %rax, -0x78(%rbp)
leaq 0x1e300(%rip), %rax     # 0x28748
cmpl $0x0, (%rax)
je 0xa468
movl -0x84(%rbp), %esi
movq -0x90(%rbp), %rdx
leaq 0x18c0b(%rip), %rdi     # 0x2306c
movb $0x0, %al
callq 0x10d0
movq -0x80(%rbp), %rdi
movslq -0x84(%rbp), %rdx
movq -0x78(%rbp), %rcx
movl $0x1, %esi
callq 0x1270
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x84(%rbp), %eax
je 0xa4b4
movq 0x1db5a(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl -0x84(%rbp), %edx
movq -0x90(%rbp), %rcx
leaq 0x18b9f(%rip), %rsi     # 0x2304c
movb $0x0, %al
callq 0x1170
movq -0x78(%rbp), %rdi
callq 0x10a0
movq -0x90(%rbp), %rdi
callq 0x1040
jmp 0xa6f0
cmpl $0x0, -0x20(%rbp)
jle 0xa4e0
cmpl $0x0, -0x1c(%rbp)
jle 0xa4e0
cmpl $0x0, -0x24(%rbp)
jg 0xa504
movq 0x1db09(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
leaq 0x18ba4(%rip), %rsi     # 0x23095
movb $0x0, %al
callq 0x1170
movl $0x1, -0x4(%rbp)
jmp 0xa6f7
movq -0x38(%rbp), %rdi
leaq 0x18cf4(%rip), %rsi     # 0x23203
callq 0x1220
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0xa547
movq 0x1daca(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movq -0x38(%rbp), %rdx
leaq 0x18b97(%rip), %rsi     # 0x230cb
movb $0x0, %al
callq 0x1170
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa6f7
movl -0x20(%rbp), %eax
imull -0x1c(%rbp), %eax
imull -0x24(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, -0x64(%rbp)
movslq -0x64(%rbp), %rdi
callq 0x11d0
movq %rax, -0x60(%rbp)
cmpl $0x0, -0x2c(%rbp)
jbe 0xa580
movq -0x58(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x11e0
movq -0x60(%rbp), %rdi
movslq -0x64(%rbp), %rdx
movq -0x58(%rbp), %rcx
movl $0x1, %esi
callq 0x1090
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x64(%rbp), %eax
je 0xa5c0
movq 0x1da48(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movl -0x64(%rbp), %edx
movq -0x38(%rbp), %rcx
leaq 0x18b26(%rip), %rsi     # 0x230df
movb $0x0, %al
callq 0x1170
movl -0x28(%rbp), %eax
testl %eax, %eax
jne 0xa6c3
jmp 0xa5cd
movq -0x38(%rbp), %rdi
callq 0xa0a0
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
leaq 0x18c18(%rip), %rsi     # 0x23203
callq 0x1220
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0xa626
movq 0x1d9ee(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movq -0x90(%rbp), %rdx
leaq 0x18ab8(%rip), %rsi     # 0x230cb
movb $0x0, %al
callq 0x1170
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa6f7
cmpl $0x4, -0x24(%rbp)
jne 0xa638
movl $0x20, -0x84(%rbp)
jmp 0xa642
movl $0x200, -0x84(%rbp)     # imm = 0x200
movslq -0x84(%rbp), %rdi
callq 0x11d0
movq %rax, -0x80(%rbp)
cmpl $0x0, -0x2c(%rbp)
jbe 0xa668
movq -0x58(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x11e0
movq -0x80(%rbp), %rdi
movslq -0x84(%rbp), %rdx
movq -0x78(%rbp), %rcx
movl $0x1, %esi
callq 0x1090
movl %eax, -0x6c(%rbp)
movq -0x60(%rbp), %rdi
movq -0x80(%rbp), %rsi
movl -0x20(%rbp), %edx
movl -0x1c(%rbp), %ecx
movl -0x24(%rbp), %r8d
callq 0x9760
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
movq -0x48(%rbp), %rsi
movl -0x20(%rbp), %edx
movl -0x1c(%rbp), %ecx
callq 0x9f20
movl %eax, -0x70(%rbp)
movq -0x90(%rbp), %rdi
callq 0x1040
jmp 0xa6cc
movl $0x1, -0x4(%rbp)
jmp 0xa6f7
cmpl $0x0, -0x70(%rbp)
jne 0xa6ee
movq 0x1d917(%rip), %rax     # 0x27ff0
movq (%rax), %rdi
movq -0x40(%rbp), %rdx
leaq 0x18a1a(%rip), %rsi     # 0x23101
movb $0x0, %al
callq 0x1170
jmp 0xa6f0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)