// File: /workspace/github_c_makefile_star2_O2/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, -0x48(%rbp)
movq %rdi, %r14
leaq -0x34(%rbp), %rsi
andl $0x0, (%rsi)
leaq -0x30(%rbp), %rdx
andl $0x0, (%rdx)
leaq -0x2c(%rbp), %rcx
andl $0x0, (%rcx)
xorl %r8d, %r8d
callq 0x300f
testq %rax, %rax
je 0x6ef2
movl -0x34(%rbp), %r12d
testl %r12d, %r12d
jle 0x6ef2
movl -0x30(%rbp), %r13d
testl %r13d, %r13d
jle 0x6ef2
movq %rax, %r15
movq %rbx, -0x40(%rbp)
leaq 0x11419(%rip), %rax     # 0x181e8
cmpl $0x0, (%rax)
je 0x6def
movl -0x2c(%rbp), %r8d
leaq 0xc709(%rip), %rdi      # 0x134e8
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 0x6f11
movq %rax, %rbx
movl -0x2c(%rbp), %edx
leal -0x3(%rdx), %eax
cmpl $0x2, %eax
jae 0x6e91
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
cmpq %r13, %r9
je 0x6f52
movq %rdi, %r10
xorl %r11d, %r11d
cmpq %r11, %r12
je 0x6e83
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 0x6e77
movb (%rsi,%r11,4), %r14b
movb %r14b, (%rax,%r11,4)
incq %r11
addq %rdx, %r10
jmp 0x6e4c
incq %r9
addq %rcx, %rax
addq %rcx, %rsi
addq %r8, %rdi
jmp 0x6e3d
cmpl $0x2, %edx
jne 0x6f30
movq %rbx, %rax
addq $0x3, %rax
leaq (,%r12,4), %rcx
movq %r15, %rdx
incq %rdx
leaq (%r12,%r12), %rsi
xorl %edi, %edi
cmpq %r13, %rdi
je 0x6f52
xorl %r8d, %r8d
cmpq %r8, %r12
je 0x6ee7
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
jmp 0x6ec1
incq %rdi
addq %rcx, %rax
addq %rsi, %rdx
jmp 0x6eb5
movq 0x110f7(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xc5c8(%rip), %rsi      # 0x134cb
xorl %ebx, %ebx
movq %r14, %rdx
xorl %eax, %eax
callq 0x1170
jmp 0x6f68
movq 0x110d8(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xc56b(%rip), %rsi      # 0x1348d
xorl %ebx, %ebx
movl %r14d, %edx
xorl %eax, %eax
callq 0x1170
jmp 0x6f68
movq 0x110b9(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0xc5c5(%rip), %rsi      # 0x13506
xorl %eax, %eax
callq 0x1170
movq %rbx, %rdi
callq 0x1040
xorl %ebx, %ebx
movq %r15, %rdi
callq 0x1040
movq -0x48(%rbp), %rax
movl %r12d, (%rax)
movq -0x40(%rbp), %rax
movl %r13d, (%rax)
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq