// File: drummyfish[P]flowchart/src/lodepng.cpp
// Function: doAutoChooseColor(LodePNGColorMode*, unsigned char const*, unsigned int, unsigned int, LodePNGColorMode*, LodePNGAutoConvert)
static unsigned doAutoChooseColor(LodePNGColorMode* mode_out,
                                  const unsigned char* image, unsigned w, unsigned h, LodePNGColorMode* mode_in,
                                  LodePNGAutoConvert auto_convert)
{
  ColorProfile profile;
  unsigned error = 0;

  if(auto_convert == LAC_ALPHA)
  {
    if(mode_out->colortype != LCT_RGBA && mode_out->colortype != LCT_GREY_ALPHA) return 0;
  }

  color_profile_init(&profile, mode_in);
  if(auto_convert == LAC_ALPHA)
  {
    profile.colored_done = 1;
    profile.greybits_done = 1;
    profile.numcolors_done = 1;
    profile.sixteenbit_done = 1;
  }
  error = get_color_profile(&profile, image, w * h, mode_in);

  if(!error && auto_convert == LAC_ALPHA)
  {
    if(!profile.alpha)
    {
      mode_out->colortype = (mode_out->colortype == LCT_RGBA ? LCT_RGB : LCT_GREY);
    }
  }
  else if(!error && auto_convert != LAC_ALPHA)
  {
    mode_out->key_defined = 0;

    if(profile.sixteenbit)
    {
      mode_out->bitdepth = 16;
      if(profile.alpha)
      {
        mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA;
      }
      else
      {
        mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY;
        if(profile.key)
        {
          mode_out->key_defined = 1;
          mode_out->key_r = profile.key_r;
          mode_out->key_g = profile.key_g;
          mode_out->key_b = profile.key_b;
        }
      }
    }
    else /*less than 16 bits per channel*/
    {
      /*don't add palette overhead if image hasn't got a lot of pixels*/
      unsigned n = profile.numcolors;
      int palette_ok = n <= 256 && (n * 2 < w * h);
      unsigned palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
      int grey_ok = !profile.colored && !profile.alpha; /*grey without alpha, with potentially low bits*/
      if(palette_ok || grey_ok)
      {
        if(!palette_ok || (grey_ok && profile.greybits <= palettebits))
        {
          mode_out->colortype = LCT_GREY;
          mode_out->bitdepth = profile.greybits;
          if(profile.key)
          {
            unsigned keyval = profile.key_r;
            keyval &= (profile.greybits - 1); /*same subgroup of bits repeated, so taking right bits is fine*/
            mode_out->key_defined = 1;
            mode_out->key_r = keyval;
            mode_out->key_g = keyval;
            mode_out->key_b = keyval;
          }
        }
        else
        {
          /*fill in the palette*/
          unsigned i;
          unsigned char* p = profile.palette;
          for(i = 0; i < profile.numcolors; i++)
          {
            error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
            if(error) break;
          }

          mode_out->colortype = LCT_PALETTE;
          mode_out->bitdepth = palettebits;
        }
      }
      else /*8-bit per channel*/
      {
        mode_out->bitdepth = 8;
        if(profile.alpha)
        {
          mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA;
        }
        else
        {
          mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY /*LCT_GREY normally won't occur, already done earlier*/;
          if(profile.key)
          {
            mode_out->key_defined = 1;
            mode_out->key_r = profile.key_r % 256;
            mode_out->key_g = profile.key_g % 256;
            mode_out->key_b = profile.key_b % 256;
          }
        }
      }
    }
  }

  color_profile_cleanup(&profile);

  if(mode_out->colortype == LCT_PALETTE && mode_in->palettesize == mode_out->palettesize)
  {
    /*In this case keep the palette order of the input, so that the user can choose an optimal one*/
    size_t i;
    for(i = 0; i < mode_in->palettesize * 4; i++)
    {
      mode_out->palette[i] = mode_in->palette[i];
    }
  }

  if(auto_convert == LAC_AUTO_NO_NIBBLES && mode_out->bitdepth < 8)
  {
    /*palette can keep its small amount of colors, as long as no indices use it*/
    mode_out->bitdepth = 8;
  }

  return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movl $0x0, -0x74(%rbp)
cmpl $0x1, -0x2c(%rbp)
jne 0xa0ae
movq -0x10(%rbp), %rax
cmpl $0x6, (%rax)
je 0xa0ac
movq -0x10(%rbp), %rax
cmpl $0x4, (%rax)
je 0xa0ac
movl $0x0, -0x4(%rbp)
jmp 0xa525
jmp 0xa0ae
movq -0x28(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x11a60
cmpl $0x1, -0x2c(%rbp)
jne 0xa0d1
movb $0x1, -0x6d(%rbp)
movb $0x1, -0x34(%rbp)
movb $0x1, -0x3c(%rbp)
movb $0x1, -0x6f(%rbp)
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %eax
imull -0x20(%rbp), %eax
movl %eax, %eax
movl %eax, %edx
movq -0x28(%rbp), %rcx
leaq -0x70(%rbp), %rdi
callq 0x11bd0
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
jne 0xa120
cmpl $0x1, -0x2c(%rbp)
jne 0xa120
cmpb $0x0, -0x64(%rbp)
jne 0xa11b
movq -0x10(%rbp), %rax
movl (%rax), %edx
xorl %ecx, %ecx
movl $0x2, %eax
cmpl $0x6, %edx
cmovel %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0xa483
cmpl $0x0, -0x74(%rbp)
jne 0xa481
cmpl $0x1, -0x2c(%rbp)
je 0xa481
movq -0x10(%rbp), %rax
movl $0x0, 0x18(%rax)
cmpb $0x0, -0x70(%rbp)
je 0xa1c0
movq -0x10(%rbp), %rax
movl $0x10, 0x4(%rax)
cmpb $0x0, -0x64(%rbp)
je 0xa171
movb -0x6e(%rbp), %dl
movl $0x4, %ecx
movl $0x6, %eax
cmpb $0x0, %dl
cmovnel %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0xa1bb
movb -0x6e(%rbp), %dl
xorl %ecx, %ecx
movl $0x2, %eax
cmpb $0x0, %dl
cmovnel %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
cmpb $0x0, -0x6c(%rbp)
je 0xa1b9
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movzwl -0x6a(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x1c(%rax)
movzwl -0x68(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x20(%rax)
movzwl -0x66(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x24(%rax)
jmp 0xa1bb
jmp 0xa47f
movl -0x60(%rbp), %eax
movl %eax, -0x78(%rbp)
xorl %eax, %eax
cmpl $0x100, -0x78(%rbp)     # imm = 0x100
movb %al, -0xa1(%rbp)
ja 0xa1ee
movl -0x78(%rbp), %eax
shll %eax
movl -0x1c(%rbp), %ecx
imull -0x20(%rbp), %ecx
cmpl %ecx, %eax
setb %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x7c(%rbp)
cmpl $0x2, -0x78(%rbp)
ja 0xa20f
movl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0xa247
cmpl $0x4, -0x78(%rbp)
ja 0xa222
movl $0x2, %eax
movl %eax, -0xac(%rbp)
jmp 0xa23b
movl -0x78(%rbp), %edx
movl $0x8, %eax
movl $0x4, %ecx
cmpl $0x10, %edx
cmovbel %ecx, %eax
movl %eax, -0xac(%rbp)
movl -0xac(%rbp), %eax
movl %eax, -0xa8(%rbp)
movl -0xa8(%rbp), %eax
movl %eax, -0x80(%rbp)
xorl %eax, %eax
cmpb $0x0, -0x6e(%rbp)
movb %al, -0xad(%rbp)
jne 0xa26d
cmpb $0x0, -0x64(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0xad(%rbp)
movb -0xad(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x7c(%rbp)
jne 0xa291
cmpl $0x0, -0x84(%rbp)
je 0xa3ed
cmpl $0x0, -0x7c(%rbp)
je 0xa2a8
cmpl $0x0, -0x84(%rbp)
je 0xa315
movl -0x38(%rbp), %eax
cmpl -0x80(%rbp), %eax
ja 0xa315
movq -0x10(%rbp), %rax
movl $0x0, (%rax)
movl -0x38(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
cmpb $0x0, -0x6c(%rbp)
je 0xa310
movzwl -0x6a(%rbp), %eax
movl %eax, -0x88(%rbp)
movl -0x38(%rbp), %eax
subl $0x1, %eax
andl -0x88(%rbp), %eax
movl %eax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movl -0x88(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x1c(%rax)
movl -0x88(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x20(%rax)
movl -0x88(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x24(%rax)
jmp 0xa3e8
movq -0x48(%rbp), %rax
movq %rax, -0x98(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
cmpl -0x60(%rbp), %eax
jae 0xa3d4
movq -0x10(%rbp), %rdi
movq -0x98(%rbp), %rax
movl -0x8c(%rbp), %ecx
shll $0x2, %ecx
addl $0x0, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %sil
movq -0x98(%rbp), %rax
movl -0x8c(%rbp), %ecx
shll $0x2, %ecx
addl $0x1, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %dl
movq -0x98(%rbp), %rax
movl -0x8c(%rbp), %ecx
shll $0x2, %ecx
addl $0x2, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %cl
movq -0x98(%rbp), %rax
movl -0x8c(%rbp), %r8d
shll $0x2, %r8d
addl $0x3, %r8d
movl %r8d, %r8d
movzbl %sil, %esi
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl (%rax,%r8), %r8d
callq 0x51f0
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
je 0xa3be
jmp 0xa3d4
jmp 0xa3c0
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0xa32a
movq -0x10(%rbp), %rax
movl $0x3, (%rax)
movl -0x80(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
jmp 0xa47d
movq -0x10(%rbp), %rax
movl $0x8, 0x4(%rax)
cmpb $0x0, -0x64(%rbp)
je 0xa419
movb -0x6e(%rbp), %dl
movl $0x4, %ecx
movl $0x6, %eax
cmpb $0x0, %dl
cmovnel %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0xa47b
movb -0x6e(%rbp), %dl
xorl %ecx, %ecx
movl $0x2, %eax
cmpb $0x0, %dl
cmovnel %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
cmpb $0x0, -0x6c(%rbp)
je 0xa479
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movzwl -0x6a(%rbp), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movq -0x10(%rbp), %rax
movl %edx, 0x1c(%rax)
movzwl -0x68(%rbp), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movq -0x10(%rbp), %rax
movl %edx, 0x20(%rax)
movzwl -0x66(%rbp), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movq -0x10(%rbp), %rax
movl %edx, 0x24(%rax)
jmp 0xa47b
jmp 0xa47d
jmp 0xa47f
jmp 0xa481
jmp 0xa483
leaq -0x70(%rbp), %rdi
callq 0x12280
movq -0x10(%rbp), %rax
cmpl $0x3, (%rax)
jne 0xa504
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0xa504
movq $0x0, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq -0x28(%rbp), %rcx
movq 0x10(%rcx), %rcx
shlq $0x2, %rcx
cmpq %rcx, %rax
jae 0xa502
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rax
movq -0xa0(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0xa0(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0xa4b2
jmp 0xa504
cmpl $0x3, -0x2c(%rbp)
jne 0xa51f
movq -0x10(%rbp), %rax
cmpl $0x8, 0x4(%rax)
jae 0xa51f
movq -0x10(%rbp), %rax
movl $0x8, 0x4(%rax)
movl -0x74(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)