// File: /workspace/github_c_makefile_star2_O3/DavidSM64[P]n64graphics_ci/n64graphics_ci.c
// Function: png2rgba
rgba *png2rgba(const char *png_filename, int *width, int *height)
{
    rgba *img = NULL;
    int w = 0;
    int h = 0;
    int channels = 0;
    int img_size;

    stbi_uc *data = stbi_load(png_filename, &w, &h, &channels, STBI_default);
    if (!data || w <= 0 || h <= 0) {
        ERROR("Error loading png file \"%s\"\n", png_filename);
        return NULL;
    }
    INFO("Read \"%s\" %dx%d channels: %d\n", png_filename, w, h, channels);

    img_size = w * h * sizeof(*img);
    img = malloc(img_size);
    if (!img) {
        ERROR("Error allocating %u bytes\n", img_size);
        return NULL;
    }

    switch (channels) {
    case 3: // red, green, blue
    case 4: // red, green, blue, alpha
        for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i++) {
                int idx = j*w + i;
                img[idx].red = data[channels*idx];
                img[idx].green = data[channels*idx + 1];
                img[idx].blue = data[channels*idx + 2];
                if (channels == 4) {
                    img[idx].alpha = data[channels*idx + 3];
                }
                else {
                    img[idx].alpha = 0xFF;
                }
            }
        }
        break;
    case 2: // grey, alpha
        for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i++) {
                int idx = j*w + i;
                img[idx].red = data[2 * idx];
                img[idx].green = data[2 * idx];
                img[idx].blue = data[2 * idx];
                img[idx].alpha = data[2 * idx + 1];
            }
        }
        break;
    default:
        ERROR("Don't know how to read channels: %d\n", channels);
        free(img);
        img = NULL;
    }

    // cleanup
    stbi_image_free(data);

    *width = w;
    *height = h;
    return img;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, %rbx
movq %rsi, -0x38(%rbp)
movq %rdi, %r14
xorl %eax, %eax
leaq -0x40(%rbp), %rsi
movl %eax, (%rsi)
leaq -0x3c(%rbp), %rdx
movl %eax, (%rdx)
leaq -0x2c(%rbp), %rcx
movl %eax, (%rcx)
xorl %r8d, %r8d
callq 0x31ef
testq %rax, %rax
je 0x745b
movl -0x40(%rbp), %r12d
testl %r12d, %r12d
jle 0x745b
movl -0x3c(%rbp), %r13d
testl %r13d, %r13d
jle 0x745b
movq %rax, %r15
movq %rbx, -0x48(%rbp)
leaq 0x11eae(%rip), %rax     # 0x191c8
cmpl $0x0, (%rax)
je 0x733a
movl -0x2c(%rbp), %r8d
leaq 0xd1ce(%rip), %rdi      # 0x144f8
movq %r14, %rsi
movl %r12d, %edx
movl %r13d, %ecx
xorl %eax, %eax
callq 0x10e0
movl %r12d, %r14d
imull %r13d, %r14d
shll $0x2, %r14d
movslq %r14d, %rdi
callq 0x11d0
testq %rax, %rax
je 0x747a
movq %rax, %rbx
movl -0x2c(%rbp), %edx
leal -0x3(%rdx), %eax
cmpl $0x2, %eax
jae 0x73da
movq %rbx, %rax
addq $0x3, %rax
leaq (,%r12,4), %rcx
leaq 0x3(%r15), %rsi
movq %r15, %rdi
addq $0x2, %rdi
movq %r12, %r8
imulq %rdx, %r8
xorl %r9d, %r9d
movq %rdi, %r10
xorl %r11d, %r11d
movb -0x2(%r10), %r14b
movb %r14b, -0x3(%rax,%r11,4)
movb -0x1(%r10), %r14b
movb %r14b, -0x2(%rax,%r11,4)
movb (%r10), %r14b
movb %r14b, -0x1(%rax,%r11,4)
movb $-0x1, %r14b
cmpl $0x4, %edx
jne 0x73b4
movb (%rsi,%r11,4), %r14b
movb %r14b, (%rax,%r11,4)
incq %r11
addq %rdx, %r10
cmpq %r11, %r12
jne 0x738e
incq %r9
addq %rcx, %rax
addq %rcx, %rsi
addq %r8, %rdi
cmpq %r13, %r9
jne 0x7388
movq -0x38(%rbp), %r14
jmp 0x7437
cmpl $0x2, %edx
jne 0x7499
movq %rbx, %rax
addq $0x3, %rax
leaq (,%r12,4), %rcx
movq %r15, %rdx
incq %rdx
leaq (%r12,%r12), %rsi
xorl %edi, %edi
movq -0x38(%rbp), %r14
xorl %r8d, %r8d
movb -0x1(%rdx,%r8,2), %r9b
movb %r9b, -0x3(%rax,%r8,4)
movb %r9b, -0x2(%rax,%r8,4)
movb %r9b, -0x1(%rax,%r8,4)
movb (%rdx,%r8,2), %r9b
movb %r9b, (%rax,%r8,4)
incq %r8
cmpq %r8, %r12
jne 0x7405
incq %rdi
addq %rcx, %rax
addq %rsi, %rdx
cmpq %r13, %rdi
jne 0x7402
movq %r15, %rdi
callq 0x1040
movl %r12d, (%r14)
movq -0x48(%rbp), %rax
movl %r13d, (%rax)
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x11b8e(%rip), %rax     # 0x18ff0
movq (%rax), %rdi
leaq 0xd06f(%rip), %rsi      # 0x144db
xorl %ebx, %ebx
movq %r14, %rdx
xorl %eax, %eax
callq 0x1170
jmp 0x7449
movq 0x11b6f(%rip), %rax     # 0x18ff0
movq (%rax), %rdi
leaq 0xd012(%rip), %rsi      # 0x1449d
xorl %ebx, %ebx
movl %r14d, %edx
xorl %eax, %eax
callq 0x1170
jmp 0x7449
movq 0x11b50(%rip), %rax     # 0x18ff0
movq (%rax), %rdi
leaq 0xd06c(%rip), %rsi      # 0x14516
xorl %eax, %eax
callq 0x1170
movq %rbx, %rdi
callq 0x1040
xorl %ebx, %ebx
jmp 0x73d4