43#define QUANT_2PASS_SUPPORTED
49#define JSAMPLE unsigned char
50#define MAXJSAMPLE (gdMaxColors-1)
51#define BITS_IN_JSAMPLE 8
56#define METHODDEF(type) static type
57#define LOCAL(type) static type
70#ifdef RIGHT_SHIFT_IS_UNSIGNED
71#define SHIFT_TEMPS INT32 shift_temp;
72#define RIGHT_SHIFT(x,shft) \
73 ((shift_temp = (x)) < 0 ? \
74 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
75 (shift_temp >> (shft)))
78#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
82#define range_limit(x) { if(x<0) x=0; if (x>255) x=255; }
90#define UINT16 unsigned short
116#define input_buf (oim->tpixels)
117#define output_buf (nim->pixels)
119#ifdef QUANT_2PASS_SUPPORTED
180#define C0_SCALE R_SCALE
183#define C0_SCALE B_SCALE
186#define C1_SCALE G_SCALE
189#define C2_SCALE R_SCALE
192#define C2_SCALE B_SCALE
222#define MAXNUMCOLORS (MAXJSAMPLE+1)
227#define HIST_C0_BITS 5
228#define HIST_C1_BITS 6
229#define HIST_C2_BITS 5
232#define HIST_C0_ELEMS (1<<HIST_C0_BITS)
233#define HIST_C1_ELEMS (1<<HIST_C1_BITS)
234#define HIST_C2_ELEMS (1<<HIST_C2_BITS)
237#define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS)
238#define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS)
239#define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS)
275#if BITS_IN_JSAMPLE == 8
320 register hist3d histogram = cquantize->histogram;
324 int num_rows = oim->sy;
326 for (row = 0; row < num_rows; row++)
329 for (col = width; col > 0; col--)
336 if ((oim->transparent >= 0) && (*
ptr == oim->transparent))
342 histp = &histogram[r][g][b];
381 register long maxc = 0;
384 for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
402 register INT32 maxv = 0;
405 for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
420 hist3d histogram = cquantize->histogram;
423 int c0min, c0max, c1min, c1max, c2min, c2max;
424 INT32 dist0, dist1, dist2;
435 for (c0 = c0min; c0 <= c0max; c0++)
436 for (c1 = c1min; c1 <= c1max; c1++)
438 histp = &histogram[c0][c1][c2min];
439 for (c2 = c2min; c2 <= c2max; c2++)
442 boxp->c0min = c0min = c0;
448 for (c0 = c0max; c0 >= c0min; c0--)
449 for (c1 = c1min; c1 <= c1max; c1++)
451 histp = &histogram[c0][c1][c2min];
452 for (c2 = c2min; c2 <= c2max; c2++)
455 boxp->c0max = c0max = c0;
461 for (c1 = c1min; c1 <= c1max; c1++)
462 for (c0 = c0min; c0 <= c0max; c0++)
464 histp = &histogram[c0][c1][c2min];
465 for (c2 = c2min; c2 <= c2max; c2++)
468 boxp->c1min = c1min = c1;
474 for (c1 = c1max; c1 >= c1min; c1--)
475 for (c0 = c0min; c0 <= c0max; c0++)
477 histp = &histogram[c0][c1][c2min];
478 for (c2 = c2min; c2 <= c2max; c2++)
481 boxp->c1max = c1max = c1;
487 for (c2 = c2min; c2 <= c2max; c2++)
488 for (c0 = c0min; c0 <= c0max; c0++)
490 histp = &histogram[c0][c1min][c2];
494 boxp->c2min = c2min = c2;
500 for (c2 = c2max; c2 >= c2min; c2--)
501 for (c0 = c0min; c0 <= c0max; c0++)
503 histp = &histogram[c0][c1min][c2];
507 boxp->c2max = c2max = c2;
524 boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2;
528 for (c0 = c0min; c0 <= c0max; c0++)
529 for (c1 = c1min; c1 <= c1max; c1++)
531 histp = &histogram[c0][c1][c2min];
532 for (c2 = c2min; c2 <= c2max; c2++, histp++)
538 boxp->colorcount = ccount;
544 boxptr boxlist,
int numboxes,
int desired_colors)
548 int c0, c1, c2, cmax;
551 while (numboxes < desired_colors)
556 if (numboxes * 2 <= desired_colors)
558 b1 = find_biggest_color_pop (boxlist, numboxes);
562 b1 = find_biggest_volume (boxlist, numboxes);
566 b2 = &boxlist[numboxes];
649 hist3d histogram = cquantize->histogram;
652 int c0min, c0max, c1min, c1max, c2min, c2max;
666 for (c0 = c0min; c0 <= c0max; c0++)
667 for (c1 = c1min; c1 <= c1max; c1++)
669 histp = &histogram[c0][c1][c2min];
670 for (c2 = c2min; c2 <= c2max; c2++)
672 if ((
count = *histp++) != 0)
688 nim->red[icolor] = (int) ((c0total + (
total >> 1)) /
total);
689 nim->green[icolor] = (int) ((c1total + (
total >> 1)) /
total);
690 nim->blue[icolor] = (int) ((c2total + (
total >> 1)) /
total);
694 nim->red[icolor] = 255;
695 nim->green[icolor] = 255;
696 nim->blue[icolor] = 255;
698 nim->open[icolor] = 0;
714 boxlist[0].
c0min = 0;
716 boxlist[0].
c1min = 0;
718 boxlist[0].
c2min = 0;
721 update_box (oim, nim, cquantize, &boxlist[0]);
723 numboxes =
median_cut (oim, nim, cquantize, boxlist, numboxes, desired_colors);
725 for (i = 0; i < numboxes; i++)
727 nim->colorsTotal = numboxes;
733 if (oim->transparent >= 0)
740 nim->open[nim->colorsTotal] = 0;
802#define BOX_C0_LOG (HIST_C0_BITS-3)
803#define BOX_C1_LOG (HIST_C1_BITS-3)
804#define BOX_C2_LOG (HIST_C2_BITS-3)
806#define BOX_C0_ELEMS (1<<BOX_C0_LOG)
807#define BOX_C1_ELEMS (1<<BOX_C1_LOG)
808#define BOX_C2_ELEMS (1<<BOX_C2_LOG)
810#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
811#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
812#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
826 int minc0,
int minc1,
int minc2,
JSAMPLE colorlist[])
836 int numcolors = nim->colorsTotal;
837 int maxc0, maxc1, maxc2;
838 int centerc0, centerc1, centerc2;
840 INT32 minmaxdist, min_dist, max_dist, tdist;
850 centerc0 = (minc0 + maxc0) >> 1;
852 centerc1 = (minc1 + maxc1) >> 1;
854 centerc2 = (minc2 + maxc2) >> 1;
864 minmaxdist = 0x7FFFFFFFL;
866 for (i = 0; i < numcolors; i++)
873 min_dist = tdist * tdist;
875 max_dist = tdist * tdist;
880 min_dist = tdist * tdist;
882 max_dist = tdist * tdist;
891 max_dist = tdist * tdist;
896 max_dist = tdist * tdist;
904 min_dist += tdist * tdist;
906 max_dist += tdist * tdist;
911 min_dist += tdist * tdist;
913 max_dist += tdist * tdist;
921 max_dist += tdist * tdist;
926 max_dist += tdist * tdist;
934 min_dist += tdist * tdist;
936 max_dist += tdist * tdist;
941 min_dist += tdist * tdist;
943 max_dist += tdist * tdist;
951 max_dist += tdist * tdist;
956 max_dist += tdist * tdist;
960 mindist[i] = min_dist;
961 if (max_dist < minmaxdist)
962 minmaxdist = max_dist;
970 for (i = 0; i < numcolors; i++)
972 if (mindist[i] <= minmaxdist)
973 colorlist[ncolors++] = (
JSAMPLE) i;
981 int minc0,
int minc1,
int minc2,
982 int numcolors,
JSAMPLE colorlist[],
993 register INT32 *bptr;
996 register INT32 dist2;
999 INT32 inc0, inc1, inc2;
1006 *bptr++ = 0x7FFFFFFFL;
1014#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
1015#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
1016#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
1018 for (i = 0; i < numcolors; i++)
1021 icolor = colorlist[i];
1022 r = nim->
red[icolor];
1023 g = nim->
green[icolor];
1024 b = nim->
blue[icolor];
1028 dist0 = inc0 * inc0;
1030 dist0 += inc1 * inc1;
1032 dist0 += inc2 * inc2;
1074 int c0,
int c1,
int c2)
1079 hist3d histogram = cquantize->histogram;
1080 int minc0, minc1, minc2;
1108 find_best_colors (oim, nim, cquantize, minc0, minc1, minc2, numcolors,
1109 colorlist, bestcolor);
1120 cachep = &histogram[c0 + ic0][c1 + ic1][c2];
1123 *cachep++ = (
histcell) ((*cptr++) + 1);
1137 register int *inptr;
1138 register unsigned char *outptr;
1139 int width = oim->sx;
1140 int num_rows = oim->sy;
1141 hist3d histogram = cquantize->histogram;
1142 register int c0, c1, c2;
1148 for (row = 0; row < num_rows; row++)
1152 for (col = width; col > 0; col--)
1167 if ((oim->transparent >= 0) && (oim->transparent == *inptr))
1169 *outptr++ = nim->colorsTotal;
1177 cachep = &histogram[c0][c1][c2];
1183 *outptr++ = (*cachep - 1);
1192 hist3d histogram = cquantize->histogram;
1203 unsigned char *outptr;
1204 int width = oim->sx;
1205 int num_rows = oim->sy;
1206 int *colormap0 = nim->red;
1207 int *colormap1 = nim->green;
1208 int *colormap2 = nim->blue;
1209 int *error_limit = cquantize->error_limiter;
1216 if (cquantize->on_odd_row)
1219 inptr += (width - 1) * 3;
1220 outptr += width - 1;
1223 errorptr = cquantize->fserrors + (width + 1) * 3;
1230 errorptr = cquantize->fserrors;
1233 cur0 = cur1 = cur2 = 0;
1235 belowerr0 = belowerr1 = belowerr2 = 0;
1236 bpreverr0 = bpreverr1 = bpreverr2 = 0;
1238 for (col = width; col > 0; col--)
1244 if ((oim->transparent >= 0) && (*inptr == oim->transparent))
1246 *outptr = nim->colorsTotal;
1264 cur0 =
RIGHT_SHIFT (cur0 + errorptr[dir3 + 0] + 8, 4);
1265 cur1 =
RIGHT_SHIFT (cur1 + errorptr[dir3 + 1] + 8, 4);
1266 cur2 =
RIGHT_SHIFT (cur2 + errorptr[dir3 + 2] + 8, 4);
1270 cur0 = error_limit[cur0];
1271 cur1 = error_limit[cur1];
1272 cur2 = error_limit[cur2];
1294 register int pixcode = *cachep - 1;
1313 errorptr[0] = (
FSERROR) (bpreverr0 + cur0);
1315 bpreverr0 = belowerr0 + cur0;
1316 belowerr0 = bnexterr;
1321 errorptr[1] = (
FSERROR) (bpreverr1 + cur1);
1323 bpreverr1 = belowerr1 + cur1;
1324 belowerr1 = bnexterr;
1329 errorptr[2] = (
FSERROR) (bpreverr2 + cur2);
1331 bpreverr2 = belowerr2 + cur2;
1332 belowerr2 = bnexterr;
1347 errorptr[0] = (
FSERROR) bpreverr0;
1348 errorptr[1] = (
FSERROR) bpreverr1;
1349 errorptr[2] = (
FSERROR) bpreverr2;
1378 cquantize->error_limiter_storage =
1380 if (!cquantize->error_limiter_storage)
1384 table = cquantize->error_limiter_storage;
1387 cquantize->error_limiter = table;
1398 for (; in <
STEPSIZE * 3; in++,
out += (in & 1) ? 0 : 1)
1418zeroHistogram (
hist3d histogram)
1429static int gdImageTrueColorToPaletteBody (
gdImagePtr oim,
int dither,
int colorsWanted,
gdImagePtr *cimP);
1434 if (
TRUE == gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim)) {
1442 return gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0);
1445static void free_truecolor_image_data(
gdImagePtr oim)
1450 for (i = 0; i < oim->
sy; i++)
1462static int gdImageTrueColorToPaletteBody (
gdImagePtr oim,
int dither,
int colorsWanted,
gdImagePtr *cimP)
1465 int i, conversionSucceeded=0;
1496 if (colorsWanted > maxColors)
1498 colorsWanted = maxColors;
1507 for (i = 0; (i < nim->
sy); i++)
1566 if (cquantize->transparentIsPresent)
1570 for (i = 0; (i < im->colorsTotal); i++)
1572 if (im->alpha[i] > mt)
1578 for (i = 0; (i < im->colorsTotal); i++)
1580 if (im->alpha[i] == mt)
1586 if (cquantize->opaqueIsPresent)
1590 for (i = 0; (i < im->colorsTotal); i++)
1592 if (im->alpha[i] < mo)
1598 for (i = 0; (i < im->colorsTotal); i++)
1600 if (im->alpha[i] == mo)
1620 conversionSucceeded =
TRUE;
1623 free_truecolor_image_data(oim);
1626 goto freeQuantizeData;
1629 conversionSucceeded =
FALSE;
1634 for (i = 0; i < nim->
sy; i++)
1675 return conversionSucceeded;
sizeof(Countable|array $value, int $mode=COUNT_NORMAL)
dir(string $directory, $context=null)
count(Countable|array $value, int $mode=COUNT_NORMAL)
memset(ptr, 0, type->size)
#define gdTrueColorGetBlue(c)
#define gdAlphaTransparent
#define gdTrueColorGetGreen(c)
#define gdTrueColorGetRed(c)
my_cquantizer * my_cquantize_ptr
int gdImageTrueColorToPalette(gdImagePtr im, int dither, int colorsWanted)
pass2_no_dither(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
update_box(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp)
prescan_quantize(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
pass2_fs_dither(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
find_nearby_colors(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int minc0, int minc1, int minc2, JSAMPLE colorlist[])
gdImagePtr gdImageCreatePaletteFromTrueColor(gdImagePtr im, int dither, int colorsWanted)
select_colors(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors)
fill_inverse_cmap(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int c0, int c1, int c2)
median_cut(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxlist, int numboxes, int desired_colors)
compute_color(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp, int icolor)
#define RIGHT_SHIFT(x, shft)
histcell hist1d[HIST_C2_ELEMS]
init_error_limit(gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
#define gdRealloc(ptr, size)
#define gdCalloc(nmemb, size)
gdImagePtr gdImageCreate(int sx, int sy)
void gdImageDestroy(gdImagePtr im)
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
int * error_limiter_storage
#define safe_emalloc(nmemb, size, offset)
define(string $constant_name, mixed $value, bool $case_insensitive=false)