// File: /workspace/github_c_makefile_star2_O1/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, %r15
movq %rsi, %rbx
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 0x3263
movq %rax, -0x38(%rbp)
testq %rax, %rax
je 0x7409
movl -0x40(%rbp), %r12d
testl %r12d, %r12d
jle 0x7409
movl -0x3c(%rbp), %r13d
testl %r13d, %r13d
jle 0x7409
movq %rbx, -0x50(%rbp)
leaq 0x12f32(%rip), %rax     # 0x1a1d8
cmpl $0x0, (%rax)
je 0x72c6
movl -0x2c(%rbp), %r8d
leaq 0xe246(%rip), %rdi      # 0x154fc
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 0x11c0
testq %rax, %rax
je 0x7428
movq %rax, %rbx
movl -0x2c(%rbp), %edx
leal -0x3(%rdx), %eax
cmpl $0x2, %eax
jae 0x7380
testl %r13d, %r13d
jle 0x73e4
movq %r15, -0x48(%rbp)
movslq %edx, %rax
movq %rbx, %rcx
addq $0x3, %rcx
leaq (,%r12,4), %rsi
movq -0x38(%rbp), %r8
leaq 0x3(%r8), %rdi
addq $0x2, %r8
movq %rax, %r9
imulq %r12, %r9
xorl %r10d, %r10d
testl %r12d, %r12d
jle 0x7369
movq %r8, %r11
xorl %r14d, %r14d
movb -0x2(%r11), %r15b
movb %r15b, -0x3(%rcx,%r14,4)
movb -0x1(%r11), %r15b
movb %r15b, -0x2(%rcx,%r14,4)
movb (%r11), %r15b
movb %r15b, -0x1(%rcx,%r14,4)
movb $-0x1, %r15b
cmpl $0x4, %edx
jne 0x735a
movb (%rdi,%r14,4), %r15b
movb %r15b, (%rcx,%r14,4)
incq %r14
addq %rax, %r11
cmpq %r14, %r12
jne 0x7334
incq %r10
addq %rsi, %rcx
addq %rsi, %rdi
addq %r9, %r8
cmpq %r13, %r10
jne 0x7329
movq -0x48(%rbp), %r15
jmp 0x73e4
cmpl $0x2, %edx
jne 0x7447
testl %r13d, %r13d
jle 0x73e4
movq %rbx, %rax
addq $0x3, %rax
leaq (,%r12,4), %rcx
movq -0x38(%rbp), %rdx
incq %rdx
leaq (%r12,%r12), %rsi
xorl %edi, %edi
testl %r12d, %r12d
jle 0x73d6
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 0x73b2
incq %rdi
addq %rcx, %rax
addq %rsi, %rdx
cmpq %r13, %rdi
jne 0x73aa
movq -0x38(%rbp), %rdi
callq 0x1040
movq -0x50(%rbp), %rax
movl %r12d, (%rax)
movl %r13d, (%r15)
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x12be0(%rip), %rax     # 0x19ff0
movq (%rax), %rdi
leaq 0xe0c5(%rip), %rsi      # 0x154df
xorl %ebx, %ebx
movq %r14, %rdx
xorl %eax, %eax
callq 0x1160
jmp 0x73f7
movq 0x12bc1(%rip), %rax     # 0x19ff0
movq (%rax), %rdi
leaq 0xe068(%rip), %rsi      # 0x154a1
xorl %ebx, %ebx
movl %r14d, %edx
xorl %eax, %eax
callq 0x1160
jmp 0x73f7
movq 0x12ba2(%rip), %rax     # 0x19ff0
movq (%rax), %rdi
leaq 0xe0c2(%rip), %rsi      # 0x1551a
xorl %eax, %eax
callq 0x1160
movq %rbx, %rdi
callq 0x1040
xorl %ebx, %ebx
jmp 0x73e4