// File: phillip-h[P]fractal-gen/lodepng.cpp
// Function: lodepng_convert(unsigned char*, unsigned char const*, LodePNGColorMode const*, LodePNGColorMode const*, unsigned int, unsigned int)
unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
                         const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
                         unsigned w, unsigned h)
{
  size_t i;
  ColorTree tree;
  size_t numpixels = w * h;

  if(lodepng_color_mode_equal(mode_out, mode_in))
  {
    size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
    for(i = 0; i != numbytes; ++i) out[i] = in[i];
    return 0;
  }

  if(mode_out->colortype == LCT_PALETTE)
  {
    size_t palettesize = mode_out->palettesize;
    const unsigned char* palette = mode_out->palette;
    size_t palsize = 1u << mode_out->bitdepth;
    /*if the user specified output palette but did not give the values, assume
    they want the values of the input color type (assuming that one is palette).
    Note that we never create a new palette ourselves.*/
    if(palettesize == 0)
    {
      palettesize = mode_in->palettesize;
      palette = mode_in->palette;
    }
    if(palettesize < palsize) palsize = palettesize;
    color_tree_init(&tree);
    for(i = 0; i != palsize; ++i)
    {
      const unsigned char* p = &palette[i * 4];
      color_tree_add(&tree, p[0], p[1], p[2], p[3], i);
    }
  }

  if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16)
  {
    for(i = 0; i != numpixels; ++i)
    {
      unsigned short r = 0, g = 0, b = 0, a = 0;
      getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
      rgba16ToPixel(out, i, mode_out, r, g, b, a);
    }
  }
  else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA)
  {
    getPixelColorsRGBA8(out, numpixels, 1, in, mode_in);
  }
  else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB)
  {
    getPixelColorsRGBA8(out, numpixels, 0, in, mode_in);
  }
  else
  {
    unsigned char r = 0, g = 0, b = 0, a = 0;
    for(i = 0; i != numpixels; ++i)
    {
      getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
      CERROR_TRY_RETURN(rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a));
    }
  }

  if(mode_out->colortype == LCT_PALETTE)
  {
    color_tree_cleanup(&tree);
  }

  return 0; /*no error*/
}

// Assembly:
subq $0x118, %rsp            # imm = 0x118
movq %rdi, 0x108(%rsp)
movq %rsi, 0x100(%rsp)
movq %rdx, 0xf8(%rsp)
movq %rcx, 0xf0(%rsp)
movl %r8d, 0xec(%rsp)
movl %r9d, 0xe8(%rsp)
movl 0xec(%rsp), %eax
imull 0xe8(%rsp), %eax
movl %eax, %eax
movq %rax, 0x50(%rsp)
movq 0xf8(%rsp), %rdi
movq 0xf0(%rsp), %rsi
callq 0xa0e0
cmpl $0x0, %eax
je 0x9d22
movl 0xec(%rsp), %edi
movl 0xe8(%rsp), %esi
movq 0xf0(%rsp), %rdx
callq 0x8ee0
movq %rax, 0x48(%rsp)
movq $0x0, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
cmpq 0x48(%rsp), %rax
je 0x9d12
movq 0x100(%rsp), %rax
movq 0xe0(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x108(%rsp), %rax
movq 0xe0(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0xe0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xe0(%rsp)
jmp 0x9cc7
movl $0x0, 0x114(%rsp)
jmp 0xa0d1
movq 0xf8(%rsp), %rax
cmpl $0x3, (%rax)
jne 0x9e4a
movq 0xf8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0xf8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0xf8(%rsp), %rax
movl 0x4(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %eax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x40(%rsp)
jne 0x9d98
movq 0xf0(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0xf0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x40(%rsp), %rax
cmpq 0x30(%rsp), %rax
jae 0x9dae
movq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x58(%rsp), %rdi
callq 0xa240
movq $0x0, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x9e48
movq 0x38(%rsp), %rax
movq 0xe0(%rsp), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movb (%rax), %sil
movq 0x28(%rsp), %rax
movb 0x1(%rax), %dl
movq 0x28(%rsp), %rax
movb 0x2(%rax), %cl
movq 0x28(%rsp), %rax
movb 0x3(%rax), %al
movq 0xe0(%rsp), %rdi
movl %edi, %r9d
leaq 0x58(%rsp), %rdi
movzbl %sil, %esi
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl %al, %r8d
callq 0xa290
movq 0xe0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xe0(%rsp)
jmp 0x9dc4
jmp 0x9e4a
movq 0xf0(%rsp), %rax
cmpl $0x10, 0x4(%rax)
jne 0x9f3c
movq 0xf8(%rsp), %rax
cmpl $0x10, 0x4(%rax)
jne 0x9f3c
movq $0x0, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
cmpq 0x50(%rsp), %rax
je 0x9f37
movw $0x0, 0x26(%rsp)
movw $0x0, 0x24(%rsp)
movw $0x0, 0x22(%rsp)
movw $0x0, 0x20(%rsp)
movq 0x100(%rsp), %r8
movq 0xe0(%rsp), %r9
movq 0xf0(%rsp), %rax
leaq 0x26(%rsp), %rdi
leaq 0x24(%rsp), %rsi
leaq 0x22(%rsp), %rdx
leaq 0x20(%rsp), %rcx
movq %rax, (%rsp)
callq 0xa390
movq 0x108(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xf8(%rsp), %rdx
movw 0x26(%rsp), %cx
movw 0x24(%rsp), %r8w
movw 0x22(%rsp), %ax
movzwl %cx, %ecx
movzwl %r8w, %r8d
movzwl %ax, %r9d
movzwl 0x20(%rsp), %eax
movl %eax, (%rsp)
callq 0xa730
movq 0xe0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xe0(%rsp)
jmp 0x9e7a
jmp 0xa0af
movq 0xf8(%rsp), %rax
cmpl $0x8, 0x4(%rax)
jne 0x9f83
movq 0xf8(%rsp), %rax
cmpl $0x6, (%rax)
jne 0x9f83
movq 0x108(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x100(%rsp), %rcx
movq 0xf0(%rsp), %r8
movl $0x1, %edx
callq 0xaa50
jmp 0xa0ad
movq 0xf8(%rsp), %rax
cmpl $0x8, 0x4(%rax)
jne 0x9fc7
movq 0xf8(%rsp), %rax
cmpl $0x2, (%rax)
jne 0x9fc7
movq 0x108(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x100(%rsp), %rcx
movq 0xf0(%rsp), %r8
xorl %edx, %edx
callq 0xaa50
jmp 0xa0ab
movb $0x0, 0x1f(%rsp)
movb $0x0, 0x1e(%rsp)
movb $0x0, 0x1d(%rsp)
movb $0x0, 0x1c(%rsp)
movq $0x0, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
cmpq 0x50(%rsp), %rax
je 0xa0a9
movq 0x100(%rsp), %r8
movq 0xe0(%rsp), %r9
movq 0xf0(%rsp), %rax
leaq 0x1f(%rsp), %rdi
leaq 0x1e(%rsp), %rsi
leaq 0x1d(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
movq %rax, (%rsp)
callq 0xb3e0
movq 0x108(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xf8(%rsp), %rdx
movb 0x1f(%rsp), %r8b
movb 0x1e(%rsp), %r9b
movb 0x1d(%rsp), %al
leaq 0x58(%rsp), %rcx
movzbl %r8b, %r8d
movzbl %r9b, %r9d
movzbl %al, %eax
movl %eax, (%rsp)
movzbl 0x1c(%rsp), %eax
movl %eax, 0x8(%rsp)
callq 0xb9f0
movl %eax, 0x18(%rsp)
cmpl $0x0, 0x18(%rsp)
je 0xa08e
movl 0x18(%rsp), %eax
movl %eax, 0x114(%rsp)
jmp 0xa0d1
jmp 0xa090
movq 0xe0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xe0(%rsp)
jmp 0x9fe7
jmp 0xa0ab
jmp 0xa0ad
jmp 0xa0af
movq 0xf8(%rsp), %rax
cmpl $0x3, (%rax)
jne 0xa0c6
leaq 0x58(%rsp), %rdi
callq 0xbe30
movl $0x0, 0x114(%rsp)
movl 0x114(%rsp), %eax
addq $0x118, %rsp            # imm = 0x118
retq