// File: tomfunkhouser[P]gaps/pkgs/jpeg/jquant2.c
// Function: find_nearby_colors
LOCAL(int)
find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
		    JSAMPLE colorlist[])
/* Locate the colormap entries close enough to an update box to be candidates
 * for the nearest entry to some cell(s) in the update box.  The update box
 * is specified by the center coordinates of its first cell.  The number of
 * candidate colormap entries is returned, and their colormap indexes are
 * placed in colorlist[].
 * This routine uses Heckbert's "locally sorted search" criterion to select
 * the colors that need further consideration.
 */
{
  int numcolors = cinfo->actual_number_of_colors;
  int maxc0, maxc1, maxc2;
  int centerc0, centerc1, centerc2;
  int i, x, ncolors;
  INT32 minmaxdist, min_dist, max_dist, tdist;
  INT32 mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */

  /* Compute true coordinates of update box's upper corner and center.
   * Actually we compute the coordinates of the center of the upper-corner
   * histogram cell, which are the upper bounds of the volume we care about.
   * Note that since ">>" rounds down, the "center" values may be closer to
   * min than to max; hence comparisons to them must be "<=", not "<".
   */
  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
  centerc0 = (minc0 + maxc0) >> 1;
  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
  centerc1 = (minc1 + maxc1) >> 1;
  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
  centerc2 = (minc2 + maxc2) >> 1;

  /* For each color in colormap, find:
   *  1. its minimum squared-distance to any point in the update box
   *     (zero if color is within update box);
   *  2. its maximum squared-distance to any point in the update box.
   * Both of these can be found by considering only the corners of the box.
   * We save the minimum distance for each color in mindist[];
   * only the smallest maximum distance is of interest.
   */
  minmaxdist = 0x7FFFFFFFL;

  for (i = 0; i < numcolors; i++) {
    /* We compute the squared-c0-distance term, then add in the other two. */
    x = GETJSAMPLE(cinfo->colormap[0][i]);
    if (x < minc0) {
      tdist = (x - minc0) * C0_SCALE;
      min_dist = tdist*tdist;
      tdist = (x - maxc0) * C0_SCALE;
      max_dist = tdist*tdist;
    } else if (x > maxc0) {
      tdist = (x - maxc0) * C0_SCALE;
      min_dist = tdist*tdist;
      tdist = (x - minc0) * C0_SCALE;
      max_dist = tdist*tdist;
    } else {
      /* within cell range so no contribution to min_dist */
      min_dist = 0;
      if (x <= centerc0) {
	tdist = (x - maxc0) * C0_SCALE;
	max_dist = tdist*tdist;
      } else {
	tdist = (x - minc0) * C0_SCALE;
	max_dist = tdist*tdist;
      }
    }

    x = GETJSAMPLE(cinfo->colormap[1][i]);
    if (x < minc1) {
      tdist = (x - minc1) * C1_SCALE;
      min_dist += tdist*tdist;
      tdist = (x - maxc1) * C1_SCALE;
      max_dist += tdist*tdist;
    } else if (x > maxc1) {
      tdist = (x - maxc1) * C1_SCALE;
      min_dist += tdist*tdist;
      tdist = (x - minc1) * C1_SCALE;
      max_dist += tdist*tdist;
    } else {
      /* within cell range so no contribution to min_dist */
      if (x <= centerc1) {
	tdist = (x - maxc1) * C1_SCALE;
	max_dist += tdist*tdist;
      } else {
	tdist = (x - minc1) * C1_SCALE;
	max_dist += tdist*tdist;
      }
    }

    x = GETJSAMPLE(cinfo->colormap[2][i]);
    if (x < minc2) {
      tdist = (x - minc2) * C2_SCALE;
      min_dist += tdist*tdist;
      tdist = (x - maxc2) * C2_SCALE;
      max_dist += tdist*tdist;
    } else if (x > maxc2) {
      tdist = (x - maxc2) * C2_SCALE;
      min_dist += tdist*tdist;
      tdist = (x - minc2) * C2_SCALE;
      max_dist += tdist*tdist;
    } else {
      /* within cell range so no contribution to min_dist */
      if (x <= centerc2) {
	tdist = (x - maxc2) * C2_SCALE;
	max_dist += tdist*tdist;
      } else {
	tdist = (x - minc2) * C2_SCALE;
	max_dist += tdist*tdist;
      }
    }

    mindist[i] = min_dist;	/* save away the results */
    if (max_dist < minmaxdist)
      minmaxdist = max_dist;
  }

  /* Now we know that no cell in the update box is more than minmaxdist
   * away from some colormap entry.  Therefore, only colors that are
   * within minmaxdist of some part of the box need be considered.
   */
  ncolors = 0;
  for (i = 0; i < numcolors; i++) {
    if (mindist[i] <= minmaxdist)
      colorlist[ncolors++] = (JSAMPLE) i;
  }
  return ncolors;
}

// Assembly:
subq $0x7e8, %rsp            # imm = 0x7E8
movq %rdi, 0x7e0(%rsp)
movl %esi, 0x7dc(%rsp)
movl %edx, 0x7d8(%rsp)
movl %ecx, 0x7d4(%rsp)
movq %r8, 0x7c8(%rsp)
movq 0x7e0(%rsp), %rax
movl 0x9c(%rax), %eax
movl %eax, 0x7c4(%rsp)
movl 0x7dc(%rsp), %eax
addl $0x18, %eax
movl %eax, 0x7c0(%rsp)
movl 0x7dc(%rsp), %eax
addl 0x7c0(%rsp), %eax
sarl %eax
movl %eax, 0x7b4(%rsp)
movl 0x7d8(%rsp), %eax
addl $0x1c, %eax
movl %eax, 0x7bc(%rsp)
movl 0x7d8(%rsp), %eax
addl 0x7bc(%rsp), %eax
sarl %eax
movl %eax, 0x7b0(%rsp)
movl 0x7d4(%rsp), %eax
addl $0x18, %eax
movl %eax, 0x7b8(%rsp)
movl 0x7d4(%rsp), %eax
addl 0x7b8(%rsp), %eax
sarl %eax
movl %eax, 0x7ac(%rsp)
movq $0x7fffffff, 0x798(%rsp) # imm = 0x7FFFFFFF
movl $0x0, 0x7a8(%rsp)
movl 0x7a8(%rsp), %eax
cmpl 0x7c4(%rsp), %eax
jge 0xf8032
movq 0x7e0(%rsp), %rax
movq 0xa0(%rax), %rax
movq (%rax), %rax
movslq 0x7a8(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0x7a4(%rsp)
movl 0x7a4(%rsp), %eax
cmpl 0x7dc(%rsp), %eax
jge 0xf7b44
movl 0x7a4(%rsp), %eax
subl 0x7dc(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7c0(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7c47
movl 0x7a4(%rsp), %eax
cmpl 0x7c0(%rsp), %eax
jle 0xf7bbf
movl 0x7a4(%rsp), %eax
subl 0x7c0(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7dc(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7c45
movq $0x0, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
cmpl 0x7b4(%rsp), %eax
jg 0xf7c10
movl 0x7a4(%rsp), %eax
subl 0x7c0(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7c43
movl 0x7a4(%rsp), %eax
subl 0x7dc(%rsp), %eax
shll %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7c45
jmp 0xf7c47
movq 0x7e0(%rsp), %rax
movq 0xa0(%rax), %rax
movq 0x8(%rax), %rax
movslq 0x7a8(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0x7a4(%rsp)
movl 0x7a4(%rsp), %eax
cmpl 0x7d8(%rsp), %eax
jge 0xf7cfa
movl 0x7a4(%rsp), %eax
subl 0x7d8(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x790(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7bc(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7e15
movl 0x7a4(%rsp), %eax
cmpl 0x7bc(%rsp), %eax
jle 0xf7d87
movl 0x7a4(%rsp), %eax
subl 0x7bc(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x790(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7d8(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7e13
movl 0x7a4(%rsp), %eax
cmpl 0x7b0(%rsp), %eax
jg 0xf7dd5
movl 0x7a4(%rsp), %eax
subl 0x7bc(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7e11
movl 0x7a4(%rsp), %eax
subl 0x7d8(%rsp), %eax
imull $0x3, %eax, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7e13
jmp 0xf7e15
movq 0x7e0(%rsp), %rax
movq 0xa0(%rax), %rax
movq 0x10(%rax), %rax
movslq 0x7a8(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0x7a4(%rsp)
movl 0x7a4(%rsp), %eax
cmpl 0x7d4(%rsp), %eax
jge 0xf7ec8
movl 0x7a4(%rsp), %eax
subl 0x7d4(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x790(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7b8(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7fe3
movl 0x7a4(%rsp), %eax
cmpl 0x7b8(%rsp), %eax
jle 0xf7f55
movl 0x7a4(%rsp), %eax
subl 0x7b8(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x790(%rsp), %rax
movq %rax, 0x790(%rsp)
movl 0x7a4(%rsp), %eax
subl 0x7d4(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7fe1
movl 0x7a4(%rsp), %eax
cmpl 0x7ac(%rsp), %eax
jg 0xf7fa3
movl 0x7a4(%rsp), %eax
subl 0x7b8(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7fdf
movl 0x7a4(%rsp), %eax
subl 0x7d4(%rsp), %eax
shll $0x0, %eax
cltq
movq %rax, 0x780(%rsp)
movq 0x780(%rsp), %rax
imulq 0x780(%rsp), %rax
addq 0x788(%rsp), %rax
movq %rax, 0x788(%rsp)
jmp 0xf7fe1
jmp 0xf7fe3
movq 0x790(%rsp), %rcx
movslq 0x7a8(%rsp), %rax
movq %rcx, -0x80(%rsp,%rax,8)
movq 0x788(%rsp), %rax
cmpq 0x798(%rsp), %rax
jge 0xf801a
movq 0x788(%rsp), %rax
movq %rax, 0x798(%rsp)
jmp 0xf801c
movl 0x7a8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7a8(%rsp)
jmp 0xf7a90
movl $0x0, 0x7a0(%rsp)
movl $0x0, 0x7a8(%rsp)
movl 0x7a8(%rsp), %eax
cmpl 0x7c4(%rsp), %eax
jge 0xf80ae
movslq 0x7a8(%rsp), %rax
movq -0x80(%rsp,%rax,8), %rax
cmpq 0x798(%rsp), %rax
jg 0xf8099
movl 0x7a8(%rsp), %eax
movb %al, %dl
movq 0x7c8(%rsp), %rax
movl 0x7a0(%rsp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x7a0(%rsp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0xf809b
movl 0x7a8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7a8(%rsp)
jmp 0xf8048
movl 0x7a0(%rsp), %eax
addq $0x7e8, %rsp            # imm = 0x7E8
retq
nopl (%rax)