// File: /workspace/github_c_makefile_star2_O3/minkcv[P]vm/convertsprite.c
// Function: main
int main (int argc, char** argv)
{
    /*
    fprintf(stderr, "   Compiled with libpng %s; using libpng %s.\n",
      PNG_LIBPNG_VER_STRING, png_libpng_ver);
    fprintf(stderr, "   Compiled with zlib %s; using zlib %s.\n",
      ZLIB_VERSION, zlib_version);
    */

    if (argc < 2 || !strlen(argv[1]))
    {
        printf("Usage: convertsprite sprite.png\n");
        return 1;
    }
    char* filename = argv[1];
    FILE* fp = fopen(filename, "rb");
    if (fp == NULL)
    {
        printf("Couldn't open file with name %s\n", filename);
        return 1;
    }
    char* filenameNoExtension = strsep(&filename, ".");
    if (filenameNoExtension == NULL)
    {
        printf("Filename should have \".png\" as an extension\n");
        return 1;
    }

    FILE* spriteFile = fopen(strcat(filenameNoExtension, ".spr"), "wb");
    int x, y;
    int width, height;
    png_byte colorType;
    png_byte bitDepth;
    png_structp pngPtr;
    png_infop infoPtr;
    int numberOfPasses;
    png_bytep* rowPointers;
    pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    infoPtr = png_create_info_struct(pngPtr);
    setjmp(png_jmpbuf(pngPtr));
    png_init_io(pngPtr, fp);
    png_set_sig_bytes(pngPtr, 0);
    png_read_info(pngPtr, infoPtr);
    width = png_get_image_width(pngPtr, infoPtr);
    height = png_get_image_height(pngPtr, infoPtr);
    colorType = png_get_color_type(pngPtr, infoPtr);
    bitDepth = png_get_bit_depth(pngPtr, infoPtr);
    //printf("Image width: %d\n", width);
    //printf("Image height: %d\n", height);
    //printf("Color type: %d\n", colorType);
    //printf("Bit depth: %d\n", bitDepth);
    numberOfPasses = png_set_interlace_handling(pngPtr);
    png_read_update_info(pngPtr, infoPtr);
    setjmp(png_jmpbuf(pngPtr));
    rowPointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
    for (y = 0; y < height; y++)
        rowPointers[y] = (png_byte*)malloc(png_get_rowbytes(pngPtr, infoPtr));
    png_read_image(pngPtr, rowPointers);

    int usedColors = 0;
    int colors[4][3];
    memset(colors, -1, sizeof(int) * 4 * 3);
    int rgba[4] = {};
    uint8_t* sprite = (uint8_t*)malloc((width / 4) * height);
    size_t spriteOffset = 0;
    int currentBits = 3; // 4 pairs of bits in a byte
    int useAlpha = 0;
    for (y = 0; y < height; y++)
    {
        png_byte* row = rowPointers[y];
        for (x = 0; x < width; x++)
        {
            png_byte* pixel = &(row[x * 4]); // RGBA
            rgba[0] = pixel[0];
            rgba[1] = pixel[1];
            rgba[2] = pixel[2];
            rgba[3] = pixel[3];
            int index;
            if (rgba[3] == 0) // Transparent
            {
                index = 3;
                useAlpha = 1;
            }
            else
            {
                index = getColorIndex(rgba, colors); // 2 bit index into colors[4]
                if (index == -1)
                {
                    //printf("%3d %3d %3d (%3d) at %2d %2d is a new color\n", rgba[0], rgba[1], rgba[2], rgba[3], x, y);
                    colors[usedColors][0] = rgba[0];
                    colors[usedColors][1] = rgba[1];
                    colors[usedColors][2] = rgba[2];
                    index = usedColors;
                    usedColors++;
                }
            }
            sprite[spriteOffset] |= index << (2 * currentBits);
            currentBits--;
            if (currentBits < 0)
            {
                currentBits = 3;
                spriteOffset++;
            }
        }
    }

    size_t written = fwrite(sprite, sizeof(uint8_t), (width  / 4) * height, spriteFile);
    printf("Wrote %zd bytes to %s\n", written, filenameNoExtension);
    fclose(spriteFile);
    free(sprite);
    for (y = 0; y < height; y++)
        free(rowPointers[y]);
    free(rowPointers);

    fclose(fp);

    printf("%s's color palette:\n", filenameNoExtension);
    int i;
    for (i = 0; i < 4 - useAlpha; i++)
    {
        // Look in the gimp palette to gain insight into this.
        int fullPaletteIndex = ceil((colors[i][0] / 36) * 32) + ((colors[i][1] / 36) * 4) + (colors[i][2] / 85.0);
        printf("Color %d has palette index %d\n", i, fullPaletteIndex);
    }
    if (useAlpha)
        printf("%s uses color 4 as transparency\n", filenameNoExtension);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
cmpl $0x2, %edi
jl 0x1787
movq 0x8(%rsi), %rdi
cmpb $0x0, (%rdi)
je 0x1787
movq %rdi, -0x58(%rbp)
leaq 0xcfb(%rip), %rsi       # 0x2010
callq 0x1150
testq %rax, %rax
je 0x17aa
movq %rax, %r13
leaq 0xd07(%rip), %rsi       # 0x2034
leaq -0x58(%rbp), %rdi
callq 0x1120
testq %rax, %rax
je 0x17be
movq %rax, %rbx
movq %rax, %rdi
callq 0x1090
movl $0x7270732e, (%rbx,%rax) # imm = 0x7270732E
movb $0x0, 0x4(%rbx,%rax)
leaq 0xcde(%rip), %rsi       # 0x203b
movq %rbx, -0x40(%rbp)
movq %rbx, %rdi
callq 0x1150
movq %rax, -0x60(%rbp)
leaq 0xcca(%rip), %rdi       # 0x203e
xorl %r15d, %r15d
movl %r15d, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x11a0
movq %rax, %r12
movq %rax, %r14
movq %rax, %rdi
callq 0x10f0
movq %rax, %rbx
movq 0x2c4b(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
movq %r12, %rdi
callq 0x10a0
movq %rax, %rdi
callq 0x10d0
movq %r12, %rdi
movq %r13, -0x88(%rbp)
movq %r13, %rsi
callq 0x1130
movq %r12, %rdi
movl %r15d, %esi
callq 0x1160
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1110
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1140
movl %eax, -0x30(%rbp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1190
movl %eax, %r13d
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1060
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1040
movq %r12, %rdi
callq 0x10e0
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1180
movq %r12, %rdi
movq 0x2bbf(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
callq 0x10a0
movq %rax, %rdi
callq 0x10d0
movl %r13d, -0x34(%rbp)
movslq %r13d, %r15
leaq (,%r15,8), %rdi
callq 0x1100
movq %rax, %r13
movl %r15d, -0x2c(%rbp)
testl %r15d, %r15d
jle 0x1489
movl -0x2c(%rbp), %eax
movl %eax, %r15d
xorl %eax, %eax
movq %rax, %r12
movq %r14, %rdi
movq %rbx, %rsi
callq 0x10c0
movq %rax, %rdi
callq 0x1100
movq %rax, (%r13,%r12,8)
incq %r12
movq %r12, %rax
cmpq %r12, %r15
jne 0x1463
movq -0x60(%rbp), %rax
movq %rax, -0x80(%rbp)
movq %r14, %rdi
movq %r13, -0x50(%rbp)
movq %r13, %rsi
callq 0x1050
pcmpeqd %xmm0, %xmm0
movdqa %xmm0, -0xa0(%rbp)
movdqa %xmm0, -0xb0(%rbp)
movdqa %xmm0, -0xc0(%rbp)
movl -0x30(%rbp), %ecx
movl %ecx, %eax
addl $0x3, %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
sarl $0x2, %eax
movl -0x34(%rbp), %ebx
imull %ebx, %eax
movslq %eax, %rdi
movq %rdi, -0x78(%rbp)
callq 0x1100
movq %rax, %r14
xorl %r13d, %r13d
testl %ebx, %ebx
jle 0x1631
movl -0x2c(%rbp), %eax
movq %rax, -0x70(%rbp)
movl -0x30(%rbp), %eax
movl %eax, %edx
movl $0x3, %r15d
xorl %ecx, %ecx
movl %ecx, %eax
movq %rax, %rdi
movl %ecx, %r8d
movl %r8d, %r9d
cmpl $0x0, -0x30(%rbp)
movq %rax, -0x68(%rbp)
jle 0x1611
movq %rax, %rsi
movq -0x50(%rbp), %rax
movq (%rax,%rsi,8), %r10
xorl %eax, %eax
movl %eax, %ebx
movl %r9d, %eax
movq %rdi, %r11
movl %ecx, %r13d
movl %r13d, %ecx
cmpb $0x0, 0x3(%r10,%rbx,4)
je 0x15a5
movl %eax, %r13d
movzbl (%r10,%rbx,4), %eax
movzbl 0x1(%r10,%rbx,4), %r12d
movzbl 0x2(%r10,%rbx,4), %r9d
xorl %esi, %esi
leaq -0xb8(%rbp), %rdi
cmpl %eax, -0x8(%rdi)
jne 0x1569
cmpl %r12d, -0x4(%rdi)
jne 0x1569
cmpl %r9d, (%rdi)
je 0x15b7
movq %rsi, %r8
incq %r8
addq $0xc, %rdi
movq %r8, %rsi
cmpq $0x4, %r8
jne 0x1559
movslq %ecx, %rsi
leaq (%rsi,%rsi,2), %rdi
movl %eax, -0xc0(%rbp,%rdi,4)
movl %r12d, -0xbc(%rbp,%rdi,4)
movl %r9d, -0xb8(%rbp,%rdi,4)
movl %esi, %eax
incl %eax
movl %eax, %edi
movl %r13d, %eax
jmp 0x15be
movl $0x3, %r8d
movl $0x1, %eax
movl %ecx, %edi
movl %r8d, %ecx
jmp 0x15be
movl %ecx, %edi
movl %r13d, %eax
movl %esi, %ecx
movl %ecx, %esi
movl %edi, %r13d
movl %r15d, %ecx
addl %ecx, %ecx
shll %cl, %esi
orb %sil, (%r14,%r11)
movl %r15d, %ecx
decl %ecx
xorl %esi, %esi
testl %r15d, %r15d
setle %dil
movb %dil, %sil
movl %ecx, %r15d
movl $0x3, %edi
cmovlel %edi, %r15d
addq %r11, %rsi
movq %rbx, %r12
incq %r12
movq %r12, %rbx
movl %eax, %r9d
movl %r15d, %r8d
movq %rsi, %rdi
movq %rsi, %r11
movl %r13d, %ecx
cmpq %rdx, %r12
jne 0x1531
jmp 0x1614
movl %r15d, %r8d
movl %r8d, %r15d
movq -0x68(%rbp), %rsi
incq %rsi
movq %rsi, %rax
movl %r9d, %r13d
movl %r9d, %r8d
cmpq -0x70(%rbp), %rsi
jne 0x1508
movl $0x1, %esi
movq %r14, %rdi
movq -0x78(%rbp), %rdx
movq -0x80(%rbp), %rbx
movq %rbx, %rcx
callq 0x1170
leaq 0x9f5(%rip), %rdi       # 0x2045
xorl %ecx, %ecx
movq %rax, %rsi
movq -0x40(%rbp), %rdx
movl %ecx, %eax
callq 0x10b0
movq %rbx, %rdi
callq 0x1080
movq %r14, %rdi
callq 0x1030
cmpl $0x0, -0x34(%rbp)
movq -0x50(%rbp), %r15
jle 0x1698
movl -0x2c(%rbp), %eax
movl %eax, %ebx
xorl %eax, %eax
movq %rax, %r14
movq (%r15,%rax,8), %rdi
callq 0x1030
incq %r14
movq %r14, %rax
cmpq %r14, %rbx
jne 0x1681
movq %r15, %rdi
callq 0x1030
movq -0x88(%rbp), %rdi
callq 0x1080
leaq 0x9a9(%rip), %rdi       # 0x205c
xorl %r14d, %r14d
movl %r14d, %ebx
movq -0x40(%rbp), %rsi
movl %r14d, %eax
callq 0x10b0
movl $0x4, %eax
movl %r13d, -0x44(%rbp)
subl %r13d, %eax
movl %eax, %r15d
leaq -0xb8(%rbp), %r12
movl %r14d, %eax
leaq 0x98c(%rip), %r13       # 0x2071
movslq -0x8(%r12), %rcx
imulq $0x38e38e39, %rcx, %rcx # imm = 0x38E38E39
movq %rcx, %rdx
shrq $0x3f, %rcx
shrq $0x23, %rdx
addl %ecx, %edx
shll $0x5, %edx
xorps %xmm0, %xmm0
cvtsi2sd %edx, %xmm0
movslq -0x4(%r12), %rcx
imulq $0x38e38e39, %rcx, %rcx # imm = 0x38E38E39
movq %rcx, %rdx
shrq $0x3f, %rcx
sarq $0x23, %rdx
addl %ecx, %edx
shll $0x2, %edx
xorps %xmm1, %xmm1
cvtsi2sd %edx, %xmm1
addsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsi2sdl (%r12), %xmm0
movq %rax, %r14
divsd 0x8c5(%rip), %xmm0      # 0x2008
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %edx
movl %r14d, %esi
movq %r13, %rdi
movl %ebx, %eax
callq 0x10b0
incq %r14
addq $0xc, %r12
movq %r14, %rax
cmpq %r14, %r15
jne 0x16e5
cmpl $0x0, -0x44(%rbp)
je 0x1783
leaq 0x918(%rip), %rdi       # 0x2090
xorl %eax, %eax
movq -0x40(%rbp), %rsi
callq 0x10b0
xorl %eax, %eax
jmp 0x1798
leaq 0x94f(%rip), %rdi       # 0x20dd
callq 0x1070
movl $0x1, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x58(%rbp), %rsi
leaq 0x85e(%rip), %rdi       # 0x2013
xorl %eax, %eax
callq 0x10b0
jmp 0x1793
leaq 0x8ec(%rip), %rdi       # 0x20b1
jmp 0x178e