// File: drummyfish[P]flowchart/src/lodepng.cpp
// Function: get_color_profile(ColorProfile*, unsigned char const*, unsigned long, LodePNGColorMode*)
static unsigned get_color_profile(ColorProfile* profile,
                                  const unsigned char* in, size_t numpixels,
                                  LodePNGColorMode* mode)
{
  unsigned error = 0;
  size_t i;

  if(mode->bitdepth == 16)
  {
    for(i = 0; i < numpixels; i++)
    {
      unsigned short r, g, b, a;
      error = getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode);
      if(error) break;

      /*a color is considered good for 8-bit if the first byte and the second byte are equal,
        (so if it's divisible through 257), NOT necessarily if the second byte is 0*/
      if(!profile->sixteenbit_done
          && (((r & 255) != ((r >> 8) & 255))
           || ((g & 255) != ((g >> 8) & 255))
           || ((b & 255) != ((b >> 8) & 255))))
      {
        profile->sixteenbit = 1;
        profile->sixteenbit_done = 1;
        profile->greybits_done = 1; /*greybits is not applicable anymore at 16-bit*/
        profile->numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/
      }

      if(!profile->colored_done && (r != g || r != b))
      {
        profile->colored = 1;
        profile->colored_done = 1;
        profile->greybits_done = 1; /*greybits is not applicable anymore*/
      }

      if(!profile->alpha_done && a != 255)
      {
        if(a == 0 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
        {
          if(!profile->key)
          {
            profile->key = 1;
            profile->key_r = r;
            profile->key_g = g;
            profile->key_b = b;
          }
        }
        else
        {
          profile->alpha = 1;
          profile->alpha_done = 1;
          profile->greybits_done = 1; /*greybits is not applicable anymore*/
        }
      }

      if(!profile->greybits_done)
      {
        /*assuming 8-bit r, this test does not care about 16-bit*/
        unsigned bits = getValueRequiredBits(r);
        if(bits > profile->greybits) profile->greybits = bits;
        if(profile->greybits >= 8) profile->greybits_done = 1;
      }

      if(!profile->numcolors_done)
      {
        /*assuming 8-bit rgba, this test does not care about 16-bit*/
        if(!color_tree_has(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a))
        {
          color_tree_add(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a,
            profile->numcolors);
          if(profile->numcolors < 256)
          {
            unsigned char* p = profile->palette;
            unsigned i = profile->numcolors;
            p[i * 4 + 0] = (unsigned char)r;
            p[i * 4 + 1] = (unsigned char)g;
            p[i * 4 + 2] = (unsigned char)b;
            p[i * 4 + 3] = (unsigned char)a;
          }
          profile->numcolors++;
          if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1;
        }
      }

      if(profile->alpha_done && profile->numcolors_done
      && profile->colored_done && profile->sixteenbit_done && profile->greybits_done)
      {
        break;
      }
    };
  }
  else
  {
    for(i = 0; i < numpixels; i++)
    {
      unsigned char r, g, b, a;
      error = getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode);
      if(error) break;

      if(!profile->colored_done && (r != g || r != b))
      {
        profile->colored = 1;
        profile->colored_done = 1;
        profile->greybits_done = 1; /*greybits is not applicable anymore*/
      }

      if(!profile->alpha_done && a != 255)
      {
        if(a == 0 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
        {
          if(!profile->key)
          {
            profile->key = 1;
            profile->key_r = r;
            profile->key_g = g;
            profile->key_b = b;
          }
        }
        else
        {
          profile->alpha = 1;
          profile->alpha_done = 1;
          profile->greybits_done = 1; /*greybits is not applicable anymore*/
        }
      }

      if(!profile->greybits_done)
      {
        unsigned bits = getValueRequiredBits(r);
        if(bits > profile->greybits) profile->greybits = bits;
        if(profile->greybits >= 8) profile->greybits_done = 1;
      }

      if(!profile->numcolors_done)
      {
        if(!color_tree_has(&profile->tree, r, g, b, a))
        {

          color_tree_add(&profile->tree, r, g, b, a, profile->numcolors);
          if(profile->numcolors < 256)
          {
            unsigned char* p = profile->palette;
            unsigned i = profile->numcolors;
            p[i * 4 + 0] = r;
            p[i * 4 + 1] = g;
            p[i * 4 + 2] = b;
            p[i * 4 + 3] = a;
          }
          profile->numcolors++;
          if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1;
        }
      }

      if(profile->alpha_done && profile->numcolors_done && profile->colored_done && profile->greybits_done)
      {
        break;
      }
    };
  }

  /*make the profile's key always 16-bit for consistency*/
  if(mode->bitdepth < 16)
  {
    /*repeat each byte twice*/
    profile->key_r *= 257;
    profile->key_g *= 257;
    profile->key_b *= 257;
  }

  return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x10, 0x4(%rax)
jne 0x11f64
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x11f5f
movq -0x10(%rbp), %r8
movq -0x30(%rbp), %r9
movq -0x20(%rbp), %rax
leaq -0x32(%rbp), %rdi
leaq -0x34(%rbp), %rsi
leaq -0x36(%rbp), %rdx
leaq -0x38(%rbp), %rcx
movq %rax, (%rsp)
callq 0x6740
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x11c46
jmp 0x11f5f
movq -0x8(%rbp), %rax
cmpb $0x0, 0x1(%rax)
jne 0x11cbd
movzwl -0x32(%rbp), %eax
andl $0xff, %eax
movzwl -0x32(%rbp), %ecx
sarl $0x8, %ecx
andl $0xff, %ecx
cmpl %ecx, %eax
jne 0x11c9e
movzwl -0x34(%rbp), %eax
andl $0xff, %eax
movzwl -0x34(%rbp), %ecx
sarl $0x8, %ecx
andl $0xff, %ecx
cmpl %ecx, %eax
jne 0x11c9e
movzwl -0x36(%rbp), %eax
andl $0xff, %eax
movzwl -0x36(%rbp), %ecx
sarl $0x8, %ecx
andl $0xff, %ecx
cmpl %ecx, %eax
je 0x11cbd
movq -0x8(%rbp), %rax
movb $0x1, (%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x1(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x34(%rax)
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3(%rax)
jne 0x11cf7
movzwl -0x32(%rbp), %eax
movzwl -0x34(%rbp), %ecx
cmpl %ecx, %eax
jne 0x11cdf
movzwl -0x32(%rbp), %eax
movzwl -0x36(%rbp), %ecx
cmpl %ecx, %eax
je 0x11cf7
movq -0x8(%rbp), %rax
movb $0x1, 0x2(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
movq -0x8(%rbp), %rax
cmpb $0x0, 0xd(%rax)
jne 0x11da9
movzwl -0x38(%rbp), %eax
cmpl $0xff, %eax
je 0x11da9
movzwl -0x38(%rbp), %eax
cmpl $0x0, %eax
jne 0x11d8f
movq -0x8(%rbp), %rax
cmpb $0x0, 0x4(%rax)
je 0x11d57
movzwl -0x32(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0x6(%rcx), %ecx
cmpl %ecx, %eax
jne 0x11d8f
movzwl -0x34(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0x8(%rcx), %ecx
cmpl %ecx, %eax
jne 0x11d8f
movzwl -0x36(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
jne 0x11d8f
movq -0x8(%rbp), %rax
cmpb $0x0, 0x4(%rax)
jne 0x11d8d
movq -0x8(%rbp), %rax
movb $0x1, 0x4(%rax)
movw -0x32(%rbp), %cx
movq -0x8(%rbp), %rax
movw %cx, 0x6(%rax)
movw -0x34(%rbp), %cx
movq -0x8(%rbp), %rax
movw %cx, 0x8(%rax)
movw -0x36(%rbp), %cx
movq -0x8(%rbp), %rax
movw %cx, 0xa(%rax)
jmp 0x11da7
movq -0x8(%rbp), %rax
movb $0x1, 0xc(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0xd(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
jmp 0x11da9
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3c(%rax)
jne 0x11de9
movzwl -0x32(%rbp), %edi
callq 0x7720
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x38(%rcx), %eax
jbe 0x11dd5
movl -0x3c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x38(%rax)
movq -0x8(%rbp), %rax
cmpl $0x8, 0x38(%rax)
jb 0x11de7
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
jmp 0x11de9
movq -0x8(%rbp), %rax
cmpb $0x0, 0x34(%rax)
jne 0x11f18
movq -0x8(%rbp), %rdi
addq $0x18, %rdi
movw -0x32(%rbp), %ax
movb %al, %sil
movw -0x34(%rbp), %ax
movb %al, %dl
movw -0x36(%rbp), %ax
movb %al, %cl
movw -0x38(%rbp), %ax
movzbl %sil, %esi
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl %al, %r8d
callq 0x122b0
cmpl $0x0, %eax
jne 0x11f16
movq -0x8(%rbp), %rdi
addq $0x18, %rdi
movw -0x32(%rbp), %ax
movb %al, %sil
movw -0x34(%rbp), %ax
movb %al, %dl
movw -0x36(%rbp), %ax
movb %al, %cl
movw -0x38(%rbp), %ax
movq -0x8(%rbp), %r8
movl 0x10(%r8), %r9d
movzbl %sil, %esi
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl %al, %r8d
callq 0x6670
movq -0x8(%rbp), %rax
cmpl $0x100, 0x10(%rax)      # imm = 0x100
jae 0x11eef
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x4c(%rbp)
movw -0x32(%rbp), %ax
movb %al, %dl
movq -0x48(%rbp), %rax
movl -0x4c(%rbp), %ecx
shll $0x2, %ecx
addl $0x0, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movw -0x34(%rbp), %ax
movb %al, %dl
movq -0x48(%rbp), %rax
movl -0x4c(%rbp), %ecx
shll $0x2, %ecx
addl $0x1, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movw -0x36(%rbp), %ax
movb %al, %dl
movq -0x48(%rbp), %rax
movl -0x4c(%rbp), %ecx
shll $0x2, %ecx
addl $0x2, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movw -0x38(%rbp), %ax
movb %al, %dl
movq -0x48(%rbp), %rax
movl -0x4c(%rbp), %ecx
shll $0x2, %ecx
addl $0x3, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x30(%rcx), %eax
jb 0x11f14
movq -0x8(%rbp), %rax
movb $0x1, 0x34(%rax)
jmp 0x11f16
jmp 0x11f18
movq -0x8(%rbp), %rax
cmpb $0x0, 0xd(%rax)
je 0x11f4c
movq -0x8(%rbp), %rax
cmpb $0x0, 0x34(%rax)
je 0x11f4c
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3(%rax)
je 0x11f4c
movq -0x8(%rbp), %rax
cmpb $0x0, 0x1(%rax)
je 0x11f4c
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3c(%rax)
je 0x11f4c
jmp 0x11f5f
jmp 0x11f4e
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x11c05
jmp 0x1222f
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x1222d
movq -0x10(%rbp), %r8
movq -0x30(%rbp), %r9
movq -0x20(%rbp), %rax
leaq -0x4d(%rbp), %rdi
leaq -0x4e(%rbp), %rsi
leaq -0x4f(%rbp), %rdx
leaq -0x50(%rbp), %rcx
movq %rax, (%rsp)
callq 0x6da0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x11fad
jmp 0x1222d
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3(%rax)
jne 0x11fe7
movzbl -0x4d(%rbp), %eax
movzbl -0x4e(%rbp), %ecx
cmpl %ecx, %eax
jne 0x11fcf
movzbl -0x4d(%rbp), %eax
movzbl -0x4f(%rbp), %ecx
cmpl %ecx, %eax
je 0x11fe7
movq -0x8(%rbp), %rax
movb $0x1, 0x2(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
movq -0x8(%rbp), %rax
cmpb $0x0, 0xd(%rax)
jne 0x120a2
movzbl -0x50(%rbp), %eax
cmpl $0xff, %eax
je 0x120a2
movzbl -0x50(%rbp), %eax
cmpl $0x0, %eax
jne 0x12088
movq -0x8(%rbp), %rax
cmpb $0x0, 0x4(%rax)
je 0x12047
movzbl -0x4d(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0x6(%rcx), %ecx
cmpl %ecx, %eax
jne 0x12088
movzbl -0x4e(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0x8(%rcx), %ecx
cmpl %ecx, %eax
jne 0x12088
movzbl -0x4f(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
jne 0x12088
movq -0x8(%rbp), %rax
cmpb $0x0, 0x4(%rax)
jne 0x12086
movq -0x8(%rbp), %rax
movb $0x1, 0x4(%rax)
movzbl -0x4d(%rbp), %eax
movw %ax, %cx
movq -0x8(%rbp), %rax
movw %cx, 0x6(%rax)
movzbl -0x4e(%rbp), %eax
movw %ax, %cx
movq -0x8(%rbp), %rax
movw %cx, 0x8(%rax)
movzbl -0x4f(%rbp), %eax
movw %ax, %cx
movq -0x8(%rbp), %rax
movw %cx, 0xa(%rax)
jmp 0x120a0
movq -0x8(%rbp), %rax
movb $0x1, 0xc(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0xd(%rax)
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
jmp 0x120a2
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3c(%rax)
jne 0x120e5
movzbl -0x4d(%rbp), %eax
movzwl %ax, %edi
callq 0x7720
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x38(%rcx), %eax
jbe 0x120d1
movl -0x54(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x38(%rax)
movq -0x8(%rbp), %rax
cmpl $0x8, 0x38(%rax)
jb 0x120e3
movq -0x8(%rbp), %rax
movb $0x1, 0x3c(%rax)
jmp 0x120e5
movq -0x8(%rbp), %rax
cmpb $0x0, 0x34(%rax)
jne 0x121f0
movq -0x8(%rbp), %rdi
addq $0x18, %rdi
movb -0x4d(%rbp), %dl
movb -0x4e(%rbp), %cl
movb -0x4f(%rbp), %al
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
movzbl -0x50(%rbp), %r8d
callq 0x122b0
cmpl $0x0, %eax
jne 0x121ee
movq -0x8(%rbp), %rdi
addq $0x18, %rdi
movb -0x4d(%rbp), %sil
movb -0x4e(%rbp), %dl
movb -0x4f(%rbp), %cl
movb -0x50(%rbp), %al
movq -0x8(%rbp), %r8
movl 0x10(%r8), %r9d
movzbl %sil, %esi
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl %al, %r8d
callq 0x6670
movq -0x8(%rbp), %rax
cmpl $0x100, 0x10(%rax)      # imm = 0x100
jae 0x121c7
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x64(%rbp)
movb -0x4d(%rbp), %dl
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
shll $0x2, %ecx
addl $0x0, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movb -0x4e(%rbp), %dl
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
shll $0x2, %ecx
addl $0x1, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movb -0x4f(%rbp), %dl
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
shll $0x2, %ecx
addl $0x2, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movb -0x50(%rbp), %dl
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
shll $0x2, %ecx
addl $0x3, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x30(%rcx), %eax
jb 0x121ec
movq -0x8(%rbp), %rax
movb $0x1, 0x34(%rax)
jmp 0x121ee
jmp 0x121f0
movq -0x8(%rbp), %rax
cmpb $0x0, 0xd(%rax)
je 0x1221a
movq -0x8(%rbp), %rax
cmpb $0x0, 0x34(%rax)
je 0x1221a
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3(%rax)
je 0x1221a
movq -0x8(%rbp), %rax
cmpb $0x0, 0x3c(%rax)
je 0x1221a
jmp 0x1222d
jmp 0x1221c
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x11f6c
jmp 0x1222f
movq -0x20(%rbp), %rax
cmpl $0x10, 0x4(%rax)
jae 0x1226f
movq -0x8(%rbp), %rax
movzwl 0x6(%rax), %ecx
imull $0x101, %ecx, %ecx      # imm = 0x101
movw %cx, 0x6(%rax)
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %ecx
imull $0x101, %ecx, %ecx      # imm = 0x101
movw %cx, 0x8(%rax)
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %ecx
imull $0x101, %ecx, %ecx      # imm = 0x101
movw %cx, 0xa(%rax)
movl -0x24(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)