25#ifdef QUANT_2PASS_SUPPORTED
86#define C0_SCALE R_SCALE
89#define C0_SCALE B_SCALE
92#define C1_SCALE G_SCALE
95#define C2_SCALE R_SCALE
98#define C2_SCALE B_SCALE
128#define MAXNUMCOLORS (MAXJSAMPLE+1)
133#define HIST_C0_BITS 5
134#define HIST_C1_BITS 6
135#define HIST_C2_BITS 5
138#define HIST_C0_ELEMS (1<<HIST_C0_BITS)
139#define HIST_C1_ELEMS (1<<HIST_C1_BITS)
140#define HIST_C2_ELEMS (1<<HIST_C2_BITS)
143#define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS)
144#define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS)
145#define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS)
150typedef histcell
FAR * histptr;
152typedef histcell hist1d[HIST_C2_ELEMS];
153typedef hist1d
FAR * hist2d;
154typedef hist2d * hist3d;
181#if BITS_IN_JSAMPLE == 8
182typedef INT16 FSERROR;
183typedef int LOCFSERROR;
185typedef INT32 FSERROR;
186typedef INT32 LOCFSERROR;
189typedef FSERROR
FAR *FSERRPTR;
204 boolean needs_zeroed;
212typedef my_cquantizer * my_cquantize_ptr;
228 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
230 register histptr histp;
231 register hist3d
histogram = cquantize->histogram;
238 for (col =
width; col > 0; col--) {
274find_biggest_color_pop (boxptr boxlist,
int numboxes)
278 register boxptr boxp;
280 register long maxc = 0;
283 for (
i = 0, boxp = boxlist;
i < numboxes;
i++, boxp++) {
284 if (boxp->colorcount > maxc && boxp->volume > 0) {
286 maxc = boxp->colorcount;
294find_biggest_volume (boxptr boxlist,
int numboxes)
298 register boxptr boxp;
300 register INT32 maxv = 0;
303 for (
i = 0, boxp = boxlist;
i < numboxes;
i++, boxp++) {
304 if (boxp->volume > maxv) {
318 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
322 int c0min,c0max,c1min,c1max,c2min,c2max;
323 INT32 dist0,dist1,dist2;
326 c0min = boxp->c0min; c0max = boxp->c0max;
327 c1min = boxp->c1min; c1max = boxp->c1max;
328 c2min = boxp->c2min; c2max = boxp->c2max;
331 for (c0 = c0min; c0 <= c0max; c0++)
332 for (c1 = c1min; c1 <= c1max; c1++) {
334 for (c2 = c2min; c2 <= c2max; c2++)
336 boxp->c0min = c0min = c0;
342 for (c0 = c0max; c0 >= c0min; c0--)
343 for (c1 = c1min; c1 <= c1max; c1++) {
345 for (c2 = c2min; c2 <= c2max; c2++)
347 boxp->c0max = c0max = c0;
353 for (c1 = c1min; c1 <= c1max; c1++)
354 for (c0 = c0min; c0 <= c0max; c0++) {
356 for (c2 = c2min; c2 <= c2max; c2++)
358 boxp->c1min = c1min = c1;
364 for (c1 = c1max; c1 >= c1min; c1--)
365 for (c0 = c0min; c0 <= c0max; c0++) {
367 for (c2 = c2min; c2 <= c2max; c2++)
369 boxp->c1max = c1max = c1;
375 for (c2 = c2min; c2 <= c2max; c2++)
376 for (c0 = c0min; c0 <= c0max; c0++) {
378 for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
380 boxp->c2min = c2min = c2;
386 for (c2 = c2max; c2 >= c2min; c2--)
387 for (c0 = c0min; c0 <= c0max; c0++) {
389 for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
391 boxp->c2max = c2max = c2;
405 dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
406 dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
407 dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
408 boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
412 for (c0 = c0min; c0 <= c0max; c0++)
413 for (c1 = c1min; c1 <= c1max; c1++) {
415 for (c2 = c2min; c2 <= c2max; c2++, histp++)
420 boxp->colorcount = ccount;
431 register boxptr
b1,
b2;
433 while (numboxes < desired_colors) {
437 if (numboxes*2 <= desired_colors) {
438 b1 = find_biggest_color_pop(boxlist, numboxes);
440 b1 = find_biggest_volume(boxlist, numboxes);
444 b2 = &boxlist[numboxes];
446 b2->c0max =
b1->c0max;
b2->c1max =
b1->c1max;
b2->c2max =
b1->c2max;
447 b2->c0min =
b1->c0min;
b2->c1min =
b1->c1min;
b2->c2min =
b1->c2min;
452 c0 = ((
b1->c0max -
b1->c0min) << C0_SHIFT) * C0_SCALE;
453 c1 = ((
b1->c1max -
b1->c1min) << C1_SHIFT) * C1_SCALE;
454 c2 = ((
b1->c2max -
b1->c2min) << C2_SHIFT) * C2_SCALE;
460 if (c0 > cmax) { cmax = c0;
n = 0; }
461 if (c2 > cmax) {
n = 2; }
464 if (c2 > cmax) { cmax = c2;
n = 2; }
465 if (c0 > cmax) {
n = 0; }
475 lb = (
b1->c0max +
b1->c0min) / 2;
480 lb = (
b1->c1max +
b1->c1min) / 2;
485 lb = (
b1->c2max +
b1->c2min) / 2;
491 update_box(cinfo,
b1);
492 update_box(cinfo,
b2);
505 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
509 int c0min,c0max,c1min,c1max,c2min,c2max;
516 c0min = boxp->c0min; c0max = boxp->c0max;
517 c1min = boxp->c1min; c1max = boxp->c1max;
518 c2min = boxp->c2min; c2max = boxp->c2max;
520 for (c0 = c0min; c0 <= c0max; c0++)
521 for (c1 = c1min; c1 <= c1max; c1++) {
523 for (c2 = c2min; c2 <= c2max; c2++) {
524 if ((
count = *histp++) != 0) {
526 c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) *
count;
527 c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) *
count;
528 c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) *
count;
548 boxlist = (boxptr) (*cinfo->mem->alloc_small)
552 boxlist[0].c0min = 0;
554 boxlist[0].c1min = 0;
556 boxlist[0].c2min = 0;
559 update_box(cinfo, & boxlist[0]);
561 numboxes =
median_cut(cinfo, boxlist, numboxes, desired_colors);
563 for (
i = 0;
i < numboxes;
i++)
564 compute_color(cinfo, & boxlist[
i],
i);
566 TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
625#define BOX_C0_LOG (HIST_C0_BITS-3)
626#define BOX_C1_LOG (HIST_C1_BITS-3)
627#define BOX_C2_LOG (HIST_C2_BITS-3)
629#define BOX_C0_ELEMS (1<<BOX_C0_LOG)
630#define BOX_C1_ELEMS (1<<BOX_C1_LOG)
631#define BOX_C2_ELEMS (1<<BOX_C2_LOG)
633#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
634#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
635#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
659 int maxc0, maxc1, maxc2;
660 int centerc0, centerc1, centerc2;
662 INT32 minmaxdist, min_dist, max_dist, tdist;
663 INT32 mindist[MAXNUMCOLORS];
671 maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
672 centerc0 = (minc0 + maxc0) >> 1;
673 maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
674 centerc1 = (minc1 + maxc1) >> 1;
675 maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
676 centerc2 = (minc2 + maxc2) >> 1;
686 minmaxdist = 0x7FFFFFFFL;
688 for (
i = 0;
i < numcolors;
i++) {
692 tdist = (
x - minc0) * C0_SCALE;
693 min_dist = tdist*tdist;
694 tdist = (
x - maxc0) * C0_SCALE;
695 max_dist = tdist*tdist;
696 }
else if (
x > maxc0) {
697 tdist = (
x - maxc0) * C0_SCALE;
698 min_dist = tdist*tdist;
699 tdist = (
x - minc0) * C0_SCALE;
700 max_dist = tdist*tdist;
705 tdist = (
x - maxc0) * C0_SCALE;
706 max_dist = tdist*tdist;
708 tdist = (
x - minc0) * C0_SCALE;
709 max_dist = tdist*tdist;
715 tdist = (
x - minc1) * C1_SCALE;
716 min_dist += tdist*tdist;
717 tdist = (
x - maxc1) * C1_SCALE;
718 max_dist += tdist*tdist;
719 }
else if (
x > maxc1) {
720 tdist = (
x - maxc1) * C1_SCALE;
721 min_dist += tdist*tdist;
722 tdist = (
x - minc1) * C1_SCALE;
723 max_dist += tdist*tdist;
727 tdist = (
x - maxc1) * C1_SCALE;
728 max_dist += tdist*tdist;
730 tdist = (
x - minc1) * C1_SCALE;
731 max_dist += tdist*tdist;
737 tdist = (
x - minc2) * C2_SCALE;
738 min_dist += tdist*tdist;
739 tdist = (
x - maxc2) * C2_SCALE;
740 max_dist += tdist*tdist;
741 }
else if (
x > maxc2) {
742 tdist = (
x - maxc2) * C2_SCALE;
743 min_dist += tdist*tdist;
744 tdist = (
x - minc2) * C2_SCALE;
745 max_dist += tdist*tdist;
749 tdist = (
x - maxc2) * C2_SCALE;
750 max_dist += tdist*tdist;
752 tdist = (
x - minc2) * C2_SCALE;
753 max_dist += tdist*tdist;
757 mindist[
i] = min_dist;
758 if (max_dist < minmaxdist)
759 minmaxdist = max_dist;
767 for (
i = 0;
i < numcolors;
i++) {
768 if (mindist[
i] <= minmaxdist)
787 register INT32 * bptr;
790 register INT32 dist2;
793 INT32 inc0, inc1, inc2;
795 INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
799 for (
i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1;
i >= 0;
i--)
800 *bptr++ = 0x7FFFFFFFL;
808#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
809#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
810#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
812 for (
i = 0;
i < numcolors;
i++) {
822 inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
823 inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
824 inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
829 for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
832 for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
835 for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
841 xx2 += 2 * STEP_C2 * STEP_C2;
846 xx1 += 2 * STEP_C1 * STEP_C1;
849 xx0 += 2 * STEP_C0 * STEP_C0;
861 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
863 int minc0, minc1, minc2;
866 register histptr cachep;
868 JSAMPLE colorlist[MAXNUMCOLORS];
871 JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
882 minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
883 minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
884 minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
889 numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
892 find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
900 for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
901 for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
902 cachep = &
histogram[c0+ic0][c1+ic1][c2];
903 for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
904 *cachep++ = (histcell) (
GETJSAMPLE(*cptr++) + 1);
920 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
923 register histptr cachep;
924 register int c0, c1, c2;
930 inptr = input_buf[
row];
932 for (col =
width; col > 0; col--) {
941 fill_inverse_cmap(cinfo, c0,c1,c2);
943 *outptr++ = (
JSAMPLE) (*cachep - 1);
954 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
956 register LOCFSERROR cur0, cur1, cur2;
957 LOCFSERROR belowerr0, belowerr1, belowerr2;
958 LOCFSERROR bpreverr0, bpreverr1, bpreverr2;
959 register FSERRPTR errorptr;
969 int *error_limit = cquantize->error_limiter;
976 inptr = input_buf[
row];
978 if (cquantize->on_odd_row) {
980 inptr += (
width-1) * 3;
984 errorptr = cquantize->fserrors + (
width+1)*3;
985 cquantize->on_odd_row =
FALSE;
990 errorptr = cquantize->fserrors;
991 cquantize->on_odd_row =
TRUE;
994 cur0 = cur1 = cur2 = 0;
996 belowerr0 = belowerr1 = belowerr2 = 0;
997 bpreverr0 = bpreverr1 = bpreverr2 = 0;
999 for (col =
width; col > 0; col--) {
1008 cur0 =
RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
1009 cur1 =
RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
1010 cur2 =
RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
1014 cur0 = error_limit[cur0];
1015 cur1 = error_limit[cur1];
1016 cur2 = error_limit[cur2];
1028 cachep = &
histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
1032 fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
1034 {
register int pixcode = *cachep - 1;
1045 {
register LOCFSERROR bnexterr, delta;
1050 errorptr[0] = (FSERROR) (bpreverr0 + cur0);
1052 bpreverr0 = belowerr0 + cur0;
1053 belowerr0 = bnexterr;
1058 errorptr[1] = (FSERROR) (bpreverr1 + cur1);
1060 bpreverr1 = belowerr1 + cur1;
1061 belowerr1 = bnexterr;
1066 errorptr[2] = (FSERROR) (bpreverr2 + cur2);
1068 bpreverr2 = belowerr2 + cur2;
1069 belowerr2 = bnexterr;
1084 errorptr[0] = (FSERROR) bpreverr0;
1085 errorptr[1] = (FSERROR) bpreverr1;
1086 errorptr[2] = (FSERROR) bpreverr2;
1112 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
1116 table = (
int *) (*cinfo->mem->alloc_small)
1119 cquantize->error_limiter =
table;
1121#define STEPSIZE ((MAXJSAMPLE+1)/16)
1124 for (
in = 0;
in < STEPSIZE;
in++,
out++) {
1128 for (;
in < STEPSIZE*3;
in++,
out += (
in&1) ? 0 : 1) {
1146 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
1149 cinfo->
colormap = cquantize->sv_colormap;
1150 select_colors(cinfo, cquantize->desired);
1152 cquantize->needs_zeroed =
TRUE;
1170 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
1171 hist3d
histogram = cquantize->histogram;
1181 cquantize->pub.color_quantize = prescan_quantize;
1182 cquantize->pub.finish_pass = finish_pass1;
1183 cquantize->needs_zeroed =
TRUE;
1187 cquantize->pub.color_quantize = pass2_fs_dither;
1189 cquantize->pub.color_quantize = pass2_no_dither;
1190 cquantize->pub.finish_pass = finish_pass2;
1195 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
1196 if (
i > MAXNUMCOLORS)
1197 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
1203 if (cquantize->fserrors ==
NULL)
1204 cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
1207 FMEMZERO((
void FAR *) cquantize->fserrors, arraysize);
1209 if (cquantize->error_limiter ==
NULL)
1210 init_error_limit(cinfo);
1211 cquantize->on_odd_row =
FALSE;
1216 if (cquantize->needs_zeroed) {
1217 for (
i = 0;
i < HIST_C0_ELEMS;
i++) {
1219 HIST_C1_ELEMS*HIST_C2_ELEMS *
SIZEOF(histcell));
1221 cquantize->needs_zeroed =
FALSE;
1233 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->
cquantize;
1236 cquantize->needs_zeroed =
TRUE;
1247 my_cquantize_ptr cquantize;
1250 cquantize = (my_cquantize_ptr)
1254 cquantize->pub.start_pass = start_pass_2_quant;
1255 cquantize->pub.new_color_map = new_color_map_2_quant;
1256 cquantize->fserrors =
NULL;
1257 cquantize->error_limiter =
NULL;
1264 cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
1266 for (
i = 0;
i < HIST_C0_ELEMS;
i++) {
1267 cquantize->histogram[
i] = (hist2d) (*cinfo->mem->alloc_large)
1269 HIST_C1_ELEMS*HIST_C2_ELEMS *
SIZEOF(histcell));
1271 cquantize->needs_zeroed =
TRUE;
1282 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
1285 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
1286 cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
1290 cquantize->sv_colormap =
NULL;
1303 cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
1307 init_error_limit(cinfo);
static int median_cut(unsigned char *image, unsigned int width, unsigned int height, unsigned int stride, int desired, unsigned int *colors)
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
GLint GLint GLsizei width
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
jpeg_component_info JCOEFPTR JSAMPARRAY output_buf
#define TRACEMS1(cinfo, lvl, code, p1)
#define ERREXIT1(cinfo, code, p1)
#define GETJSAMPLE(value)
#define FMEMZERO(target, size)
int JSAMPARRAY int int num_rows
#define RIGHT_SHIFT(x, shft)
struct jpeg_common_struct * j_common_ptr
static CRYPT_DATA_BLOB b2[]
static CRYPT_DATA_BLOB b1[]
JSAMPLE * sample_range_limit
int actual_number_of_colors
boolean enable_2pass_quant
int desired_number_of_colors
J_DITHER_MODE dither_mode
struct jpeg_color_quantizer * cquantize