BitMiracle.LibJpeg.Classic.Internal.my_1pass_cquantizer.select_ncolors C# (CSharp) Method

select_ncolors() private method

Determine allocation of desired colors to components, and fill in Ncolors[] array to indicate choice. Return value is total number of colors (product of Ncolors[] values).
private select_ncolors ( int Ncolors ) : int
Ncolors int
return int
        private int select_ncolors(int[] Ncolors)
        {
            int nc = m_cinfo.m_out_color_components; /* number of color components */
            int max_colors = m_cinfo.m_desired_number_of_colors;
            
            /* We can allocate at least the nc'th root of max_colors per component. */
            /* Compute floor(nc'th root of max_colors). */
            int iroot = 1;
            long temp = 0;
            do
            {
                iroot++;
                temp = iroot;       /* set temp = iroot ** nc */
                for (int i = 1; i < nc; i++)
                    temp *= iroot;
            }
            while (temp <= max_colors); /* repeat till iroot exceeds root */

            /* now iroot = floor(root) */
            iroot--;

            /* Must have at least 2 color values per component */
            if (iroot < 2)
                m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_QUANT_FEW_COLORS, (int)temp);

            /* Initialize to iroot color values for each component */
            int total_colors = 1;
            for (int i = 0; i < nc; i++)
            {
                Ncolors[i] = iroot;
                total_colors *= iroot;
            }

            /* We may be able to increment the count for one or more components without
             * exceeding max_colors, though we know not all can be incremented.
             * Sometimes, the first component can be incremented more than once!
             * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
             * In RGB colorspace, try to increment G first, then R, then B.
             */
            bool changed = false;
            do
            {
                changed = false;
                for (int i = 0; i < nc; i++)
                {
                    int j = (m_cinfo.m_out_color_space == J_COLOR_SPACE.JCS_RGB ? RGB_order[i] : i);
                    /* calculate new total_colors if Ncolors[j] is incremented */
                    temp = total_colors / Ncolors[j];
                    temp *= Ncolors[j] + 1; /* done in long arith to avoid oflo */

                    if (temp > max_colors)
                        break;          /* won't fit, done with this pass */
                    
                    Ncolors[j]++;       /* OK, apply the increment */
                    total_colors = (int)temp;
                    changed = true;
                }
            }
            while (changed);

            return total_colors;
        }