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;
}