private void find_best_colors(int minc0, int minc1, int minc2, int numcolors, byte[] colorlist, byte[] bestcolor)
{
/* Nominal steps between cell centers ("x" in Thomas article) */
const int STEP_C0 = ((1 << C0_SHIFT) * R_SCALE);
const int STEP_C1 = ((1 << C1_SHIFT) * G_SCALE);
const int STEP_C2 = ((1 << C2_SHIFT) * B_SCALE);
/* This array holds the distance to the nearest-so-far color for each cell */
int[] bestdist = new int[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
/* Initialize best-distance for each cell of the update box */
int bestIndex = 0;
for (int i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--)
{
bestdist[bestIndex] = 0x7FFFFFFF;
bestIndex++;
}
/* For each color selected by find_nearby_colors,
* compute its distance to the center of each cell in the box.
* If that's less than best-so-far, update best distance and color number.
*/
for (int i = 0; i < numcolors; i++)
{
int icolor = colorlist[i];
/* Compute (square of) distance from minc0/c1/c2 to this color */
int inc0 = (minc0 - m_cinfo.m_colormap[0][icolor]) * R_SCALE;
int dist0 = inc0 * inc0;
int inc1 = (minc1 - m_cinfo.m_colormap[1][icolor]) * G_SCALE;
dist0 += inc1 * inc1;
int inc2 = (minc2 - m_cinfo.m_colormap[2][icolor]) * B_SCALE;
dist0 += inc2 * inc2;
/* Form the initial difference increments */
inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
/* Now loop over all cells in box, updating distance per Thomas method */
bestIndex = 0;
int colorIndex = 0;
int xx0 = inc0;
for (int ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--)
{
int dist1 = dist0;
int xx1 = inc1;
for (int ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--)
{
int dist2 = dist1;
int xx2 = inc2;
for (int ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--)
{
if (dist2 < bestdist[bestIndex])
{
bestdist[bestIndex] = dist2;
bestcolor[colorIndex] = (byte) icolor;
}
dist2 += xx2;
xx2 += 2 * STEP_C2 * STEP_C2;
bestIndex++;
colorIndex++;
}
dist1 += xx1;
xx1 += 2 * STEP_C1 * STEP_C1;
}
dist0 += xx0;
xx0 += 2 * STEP_C0 * STEP_C0;
}
}
}