private int find_nearby_colors(int minc0, int minc1, int minc2, byte[] colorlist)
{
/* 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 "<".
*/
int maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
int centerc0 = (minc0 + maxc0) >> 1;
int maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
int centerc1 = (minc1 + maxc1) >> 1;
int maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
int 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.
*/
int minmaxdist = 0x7FFFFFFF;
int[] mindist = new int[MAXNUMCOLORS]; /* min distance to colormap entry i */
for (int i = 0; i < m_cinfo.m_actual_number_of_colors; i++)
{
/* We compute the squared-c0-distance term, then add in the other two. */
int x = m_cinfo.m_colormap[0][i];
int min_dist;
int max_dist;
if (x < minc0)
{
int tdist = (x - minc0) * R_SCALE;
min_dist = tdist * tdist;
tdist = (x - maxc0) * R_SCALE;
max_dist = tdist * tdist;
}
else if (x > maxc0)
{
int tdist = (x - maxc0) * R_SCALE;
min_dist = tdist * tdist;
tdist = (x - minc0) * R_SCALE;
max_dist = tdist * tdist;
}
else
{
/* within cell range so no contribution to min_dist */
min_dist = 0;
if (x <= centerc0)
{
int tdist = (x - maxc0) * R_SCALE;
max_dist = tdist * tdist;
}
else
{
int tdist = (x - minc0) * R_SCALE;
max_dist = tdist * tdist;
}
}
x = m_cinfo.m_colormap[1][i];
if (x < minc1)
{
int tdist = (x - minc1) * G_SCALE;
min_dist += tdist * tdist;
tdist = (x - maxc1) * G_SCALE;
max_dist += tdist * tdist;
}
else if (x > maxc1)
{
int tdist = (x - maxc1) * G_SCALE;
min_dist += tdist * tdist;
tdist = (x - minc1) * G_SCALE;
max_dist += tdist * tdist;
}
else
{
/* within cell range so no contribution to min_dist */
if (x <= centerc1)
{
int tdist = (x - maxc1) * G_SCALE;
max_dist += tdist * tdist;
}
else
{
int tdist = (x - minc1) * G_SCALE;
max_dist += tdist * tdist;
}
}
x = m_cinfo.m_colormap[2][i];
if (x < minc2)
{
int tdist = (x - minc2) * B_SCALE;
min_dist += tdist * tdist;
tdist = (x - maxc2) * B_SCALE;
max_dist += tdist * tdist;
}
else if (x > maxc2)
{
int tdist = (x - maxc2) * B_SCALE;
min_dist += tdist * tdist;
tdist = (x - minc2) * B_SCALE;
max_dist += tdist * tdist;
}
else
{
/* within cell range so no contribution to min_dist */
if (x <= centerc2)
{
int tdist = (x - maxc2) * B_SCALE;
max_dist += tdist * tdist;
}
else
{
int tdist = (x - minc2) * B_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.
*/
int ncolors = 0;
for (int i = 0; i < m_cinfo.m_actual_number_of_colors; i++)
{
if (mindist[i] <= minmaxdist)
colorlist[ncolors++] = (byte) i;
}
return ncolors;
}