// File: tomfunkhouser[P]gaps/pkgs/jpeg/jquant1.c
// Function: select_ncolors
LOCAL(int)
select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
/* Determine allocation of desired colors to components, */
/* and fill in Ncolors[] array to indicate choice. */
/* Return value is total number of colors (product of Ncolors[] values). */
{
  int nc = cinfo->out_color_components; /* number of color components */
  int max_colors = cinfo->desired_number_of_colors;
  int total_colors, iroot, i, j;
  jboolean changed;
  long temp;
  static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };

  /* We can allocate at least the nc'th root of max_colors per component. */
  /* Compute floor(nc'th root of max_colors). */
  iroot = 1;
  do {
    iroot++;
    temp = iroot;		/* set temp = iroot ** nc */
    for (i = 1; i < nc; i++)
      temp *= iroot;
  } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
  iroot--;			/* now iroot = floor(root) */

  /* Must have at least 2 color values per component */
  if (iroot < 2)
    ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);

  /* Initialize to iroot color values for each component */
  total_colors = 1;
  for (i = 0; i < nc; i++) {
    Ncolors[i] = iroot;
    total_colors *= iroot;
  }
  /* We may be able to increment the count for one or more components without
   * exceeding max_colors, though we know not all can be incremented.
   * Sometimes, the first component can be incremented more than once!
   * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
   * In RGB colorspace, try to increment G first, then R, then B.
   */
  do {
    changed = FALSE;
    for (i = 0; i < nc; i++) {
      j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
      /* calculate new total_colors if Ncolors[j] is incremented */
      temp = total_colors / Ncolors[j];
      temp *= Ncolors[j]+1;	/* done in long arith to avoid oflo */
      if (temp > (long) max_colors)
	break;			/* won't fit, done with this pass */
      Ncolors[j]++;		/* OK, apply the increment */
      total_colors = (int) temp;
      changed = TRUE;
    }
  } while (changed);

  return total_colors;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x40(%rsp), %rax
movl 0x90(%rax), %eax
movl %eax, 0x34(%rsp)
movq 0x40(%rsp), %rax
movl 0x78(%rax), %eax
movl %eax, 0x30(%rsp)
movl $0x1, 0x28(%rsp)
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
movslq 0x28(%rsp), %rax
movq %rax, 0x10(%rsp)
movl $0x1, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x34(%rsp), %eax
jge 0xf5765
movslq 0x28(%rsp), %rax
imulq 0x10(%rsp), %rax
movq %rax, 0x10(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0xf573e
jmp 0xf5767
movq 0x10(%rsp), %rax
movslq 0x30(%rsp), %rcx
cmpq %rcx, %rax
jle 0xf5721
movl 0x28(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x28(%rsp)
cmpl $0x2, 0x28(%rsp)
jge 0xf57bb
movq 0x40(%rsp), %rax
movq (%rax), %rax
movl $0x38, 0x28(%rax)
movq 0x10(%rsp), %rax
movl %eax, %ecx
movq 0x40(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x40(%rsp), %rdi
callq *%rax
movl $0x1, 0x2c(%rsp)
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x34(%rsp), %eax
jge 0xf5800
movl 0x28(%rsp), %edx
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x28(%rsp), %eax
imull 0x2c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0xf57cb
jmp 0xf5802
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x34(%rsp), %eax
jge 0xf58cb
movq 0x40(%rsp), %rax
cmpl $0x2, 0x40(%rax)
jne 0xf5840
movslq 0x24(%rsp), %rcx
leaq 0x41d19(%rip), %rax     # 0x137550
movl (%rax,%rcx,4), %eax
movl %eax, 0xc(%rsp)
jmp 0xf5848
movl 0x24(%rsp), %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x2c(%rsp), %eax
movq 0x38(%rsp), %rcx
movslq 0x20(%rsp), %rsi
cltd
idivl (%rcx,%rsi,4)
cltq
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x1, %eax
cltq
imulq 0x10(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movslq 0x30(%rsp), %rcx
cmpq %rcx, %rax
jle 0xf5897
jmp 0xf58cb
movq 0x38(%rsp), %rax
movslq 0x20(%rsp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movq 0x10(%rsp), %rax
movl %eax, 0x2c(%rsp)
movl $0x1, 0x1c(%rsp)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0xf5812
jmp 0xf58cd
cmpl $0x0, 0x1c(%rsp)
jne 0xf5802
movl 0x2c(%rsp), %eax
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)