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

find_best_colors() private method

Find the closest colormap entry for each cell in the update box, given the list of candidate colors prepared by find_nearby_colors. Return the indexes of the closest entries in the bestcolor[] array. This routine uses Thomas' incremental distance calculation method to find the distance from a colormap entry to successive cells in the box.
private find_best_colors ( int minc0, int minc1, int minc2, int numcolors, byte colorlist, byte bestcolor ) : void
minc0 int
minc1 int
minc2 int
numcolors int
colorlist byte
bestcolor byte
return void
        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;
                }
            }
        }