// File: /workspace/github_c_makefile_star2_O0/jani-nykanen[P]mushrooms/./tools/src/png2spr.c
// Function: convert_bitmap
static i32 convert_bitmap(const str in, const str out, bool writeMask,
    i32 frameWidth, i32 frameHeight) {

    const u8 ALPHA_LIMIT = 127;

    i32 pixelCount;
    i32 w, h;
    i32 x, y;
    i32 channels;
    u8* pdata;
    u8* cdata;
    u8* mask;

    u8* rcdata = NULL;
    u8* rmask = NULL;

    u32 i;
    FILE* f;
    u8 bout;
    u16 sout;

    pdata = stbi_load(in, &w, &h, &channels, 4);
    if(pdata == NULL) {
        
        fprintf(stderr, "Failed to load a bitmap in %s!\n", in);
        return 1;
    }
    pixelCount = w * h;

    if (frameWidth <= 0) frameWidth = w;
    if (frameHeight <= 0) frameHeight = h;

    if (w % frameWidth != 0 ||
        h % frameHeight != 0) {

        fprintf(stderr, "The image cannot be split to frames!\n");
        return 1;
    }

    cdata = (u8*)malloc(w * h);
    if (cdata == NULL) {

        fprintf(stderr, "Memory allocation error!\n");
        return 1;
    }

    mask = (u8*)malloc(w * h);
    if (mask == NULL) {

        fprintf(stderr, "Memory allocation error!\n");
        return 1;
    }

    for (i = 0; i < w * h; ++ i) {

        cdata[i] = find_color(pdata, i * 4);
        mask[i] = (u8)(pdata[i*4 + 3] >= ALPHA_LIMIT) * 3;
    }

    if (rearrange(cdata, mask, w, h, frameWidth, frameHeight, &rcdata, &rmask)) {

        fprintf(stderr, "Memory allocation error!\n");
        return 1;
    }

    f = fopen(out, "wb");
    if (f == NULL) {

        fprintf(stderr, "Failed to create a file to %s!\n", out);
        free(pdata);

        return 1;
    }

    // Frame dimensions
    sout = (u16)frameWidth;
    fwrite(&sout, sizeof(u16), 1, f);
    sout = (u16)frameHeight;
    fwrite(&sout, sizeof(u16), 1, f);
    // Frame count
    x = w / frameWidth;
    y = h / frameHeight;
    sout = y * x;
    fwrite(&sout, sizeof(u16), 1, f);

    // Does have a mask
    bout = (u8)writeMask;
    fwrite(&bout, 1, 1, f);

    // Pixel data
    write_array(f, rcdata, w*h);
    // Mask data
    if (writeMask) {

        write_array(f, rmask, w*h);
    }

    fclose(f);

    free(pdata);
    free(cdata);
    free(mask);
    free(rmask);
    free(rcdata);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movb %dl, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movl %ecx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movb $0x7f, -0x25(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq -0x34(%rbp), %rdx
leaq -0x40(%rbp), %rcx
movl $0x4, %r8d
callq 0x12c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x2d73
movq 0x1c2a6(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
movq -0x10(%rbp), %rdx
leaq 0x1853c(%rip), %rsi     # 0x1b29c
movb $0x0, %al
callq 0x10d0
movl $0x1, -0x4(%rbp)
jmp 0x3054
movl -0x30(%rbp), %eax
imull -0x34(%rbp), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x20(%rbp)
jg 0x2d89
movl -0x30(%rbp), %eax
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x24(%rbp)
jg 0x2d95
movl -0x34(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x30(%rbp), %eax
cltd
idivl -0x20(%rbp)
cmpl $0x0, %edx
jne 0x2dad
movl -0x34(%rbp), %eax
cltd
idivl -0x24(%rbp)
cmpl $0x0, %edx
je 0x2dd1
movq 0x1c244(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
leaq 0x184fe(%rip), %rsi     # 0x1b2bc
movb $0x0, %al
callq 0x10d0
movl $0x1, -0x4(%rbp)
jmp 0x3054
movl -0x30(%rbp), %eax
imull -0x34(%rbp), %eax
movslq %eax, %rdi
callq 0x1120
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0x2e0f
movq 0x1c206(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
leaq 0x184e6(%rip), %rsi     # 0x1b2e2
movb $0x0, %al
callq 0x10d0
movl $0x1, -0x4(%rbp)
jmp 0x3054
movl -0x30(%rbp), %eax
imull -0x34(%rbp), %eax
movslq %eax, %rdi
callq 0x1120
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0x2e4d
movq 0x1c1c8(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
leaq 0x184a8(%rip), %rsi     # 0x1b2e2
movb $0x0, %al
callq 0x10d0
movl $0x1, -0x4(%rbp)
jmp 0x3054
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movl -0x30(%rbp), %ecx
imull -0x34(%rbp), %ecx
cmpl %ecx, %eax
jae 0x2eb8
movq -0x48(%rbp), %rdi
movl -0x6c(%rbp), %esi
shll $0x2, %esi
callq 0x19cb0
movb %al, %dl
movq -0x50(%rbp), %rax
movl -0x6c(%rbp), %ecx
movb %dl, (%rax,%rcx)
movq -0x48(%rbp), %rax
movl -0x6c(%rbp), %ecx
shll $0x2, %ecx
addl $0x3, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x7f, %eax
setge %al
andb $0x1, %al
movzbl %al, %eax
movzbl %al, %eax
imull $0x3, %eax, %eax
movb %al, %dl
movq -0x58(%rbp), %rax
movl -0x6c(%rbp), %ecx
movb %dl, (%rax,%rcx)
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x2e54
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
movl -0x30(%rbp), %edx
movl -0x34(%rbp), %ecx
movl -0x20(%rbp), %r8d
movl -0x24(%rbp), %r9d
leaq -0x60(%rbp), %r10
leaq -0x68(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x19d40
testb $0x1, %al
jne 0x2eea
jmp 0x2f0e
movq 0x1c107(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
leaq 0x183e7(%rip), %rsi     # 0x1b2e2
movb $0x0, %al
callq 0x10d0
movl $0x1, -0x4(%rbp)
jmp 0x3054
movq -0x18(%rbp), %rdi
leaq 0x183e3(%rip), %rsi     # 0x1b2fc
callq 0x1150
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0x2f5a
movq 0x1c0c8(%rip), %rax     # 0x1eff8
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
leaq 0x183c1(%rip), %rsi     # 0x1b2ff
movb $0x0, %al
callq 0x10d0
movq -0x48(%rbp), %rdi
callq 0x1030
movl $0x1, -0x4(%rbp)
jmp 0x3054
movl -0x20(%rbp), %eax
movw %ax, -0x7c(%rbp)
movq -0x78(%rbp), %rcx
leaq -0x7c(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x1160
movl -0x24(%rbp), %eax
movw %ax, -0x7c(%rbp)
movq -0x78(%rbp), %rcx
leaq -0x7c(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x1160
movl -0x30(%rbp), %eax
cltd
idivl -0x20(%rbp)
movl %eax, -0x38(%rbp)
movl -0x34(%rbp), %eax
cltd
idivl -0x24(%rbp)
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
imull -0x38(%rbp), %eax
movw %ax, -0x7c(%rbp)
movq -0x78(%rbp), %rcx
leaq -0x7c(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x1160
movb -0x19(%rbp), %al
andb $0x1, %al
movb %al, -0x79(%rbp)
movq -0x78(%rbp), %rcx
leaq -0x79(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x1160
movq -0x78(%rbp), %rdi
movq -0x60(%rbp), %rsi
movl -0x30(%rbp), %edx
imull -0x34(%rbp), %edx
callq 0x19ef0
testb $0x1, -0x19(%rbp)
je 0x3017
movq -0x78(%rbp), %rdi
movq -0x68(%rbp), %rsi
movl -0x30(%rbp), %edx
imull -0x34(%rbp), %edx
callq 0x19ef0
movq -0x78(%rbp), %rdi
callq 0x1080
movq -0x48(%rbp), %rdi
callq 0x1030
movq -0x50(%rbp), %rdi
callq 0x1030
movq -0x58(%rbp), %rdi
callq 0x1030
movq -0x68(%rbp), %rdi
callq 0x1030
movq -0x60(%rbp), %rdi
callq 0x1030
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq