BitMiracle.LibJpeg.Classic.Internal.my_2pass_cquantizer.find_nearby_colors C# (CSharp) Method

find_nearby_colors() private method

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.
private find_nearby_colors ( int minc0, int minc1, int minc2, byte colorlist ) : int
minc0 int
minc1 int
minc2 int
colorlist byte
return int
        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;
        }