1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * gimpimage-convert-indexed.c
5  * Copyright (C) 1997-2004 Adam D. Moss <adam@gimp.org>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 /*
22  * 2005-09-04 - Switch 'positional' dither matrix to a 32x32 Bayer,
23  *  which generates results that compress somewhat better (and may look
24  *  worse or better depending on what you enjoy...).  [adam@gimp.org]
25  *
26  * 2004-12-12 - Use a slower but much nicer technique for finding the
27  *  two best colors to dither between when using fixed/positional
28  *  dither methods.  Makes positional dither much less lame.  [adam@gimp.org]
29  *
30  * 2002-02-10 - Quantizer version 3.0 (the rest of the commit started
31  *  a year ago -- whoops).  Divide colors within CIE L*a*b* space using
32  *  CPercep module (cpercep.[ch]), color-match and dither likewise,
33  *  change the underlying box selection criteria and division point
34  *  logic, bump luminance precision upwards, etc.etc.  Generally
35  *  chooses a much richer color set, especially for low numbers of
36  *  colors.  n.b.: Less luminance-sloppy in straight remapping which is
37  *  good for color but a bit worse for high-frequency detail (that's
38  *  partly what fs-dithering is for -- use it).  [adam@gimp.org]
39  *
40  * 2001-03-25 - Define accessor function/macro for histogram reads and
41  *  writes.  This slows us down a little because we avoid some of the
42  *  dirty tricks we used when we knew that the histogram was a straight
43  *  3d array, so I've recovered some of the speed loss by implementing
44  *  a 5d accessor function with good locality of reference.  This change
45  *  is the first step towards quantizing in a more interesting colorspace
46  *  than frumpy old RGB.  [Adam]
47  *
48  * 2000/01/30 - Use palette_selector instead of option_menu for custom
49  *  palette. Use libgimp callback functions.  [Sven]
50  *
51  * 99/09/01 - Created a low-bleed FS-dither option.  [Adam]
52  *
53  * 99/08/29 - Deterministic color dithering to arbitrary palettes.
54  *  Ideal for animations that are going to be delta-optimized or simply
55  *  don't want to look 'busy' in static areas.  Also a bunch of bugfixes
56  *  and tweaks.  [Adam]
57  *
58  * 99/08/28 - Deterministic alpha dithering over layers, reduced bleeding
59  *  of transparent values into opaque values, added optional stage to
60  *  remove duplicate or unused color entries from final colormap. [Adam]
61  *
62  * 99/02/24 - Many revisions to the box-cut quantizer used in RGB->INDEXED
63  *  conversion.  Box to be cut is chosen on the basis of possessing an axis
64  *  with the largest sum of weighted perceptible error, rather than based on
65  *  volume or population.  The box is split along this axis rather than its
66  *  longest axis, at the point of error mean rather than simply at its centre.
67  *  Error-limiting in the F-S dither has been disabled - it may become optional
68  *  again later.  If you're convinced that you have an image where the old
69  *  dither looks better, let me know.  [Adam]
70  *
71  * 99/01/10 - Hourglass... [Adam]
72  *
73  * 98/07/25 - Convert-to-indexed now remembers the last invocation's
74  *  settings.  Also, GRAY->INDEXED is more flexible.  [Adam]
75  *
76  * 98/07/05 - Sucked the warning about quantizing to too many colors into
77  *  a text widget embedded in the dialog, improved intelligence of dialog
78  *  to default 'custom palette' selection to 'Web' if available, and
79  *  in this case not bother to present the native WWW-palette radio
80  *  button.  [Adam]
81  *
82  * 98/04/13 - avoid a division by zero when converting an empty gray-scale
83  *  image (who would like to do such a thing anyway??)  [Sven ]
84  *
85  * 98/03/23 - fixed a longstanding fencepost - hopefully the *right*
86  *  way, *again*.  [Adam]
87  *
88  * 97/11/14 - added a proper pdb interface and support for dithering
89  *  to custom palettes (based on a patch by Eric Hernes) [Yosh]
90  *
91  * 97/11/04 - fixed the accidental use of the color-counting case
92  *  when palette_type is WEB or MONO. [Adam]
93  *
94  * 97/10/25 - color-counting implemented (could use some hashing, but
95  *  performance actually seems okay) - now RGB->INDEXED conversion isn't
96  *  destructive if it doesn't have to be. [Adam]
97  *
98  * 97/10/14 - fixed divide-by-zero when converting a completely transparent
99  *  RGB image to indexed. [Adam]
100  *
101  * 97/07/01 - started todo/revision log.  Put code back in to
102  *  eliminate full-alpha pixels from RGB histogram.
103  *  [Adam D. Moss - adam@gimp.org]
104  */
105 
106   /* TODO for Convert:
107    *
108    * . Tweak, tweak, tweak.  Old RGB code was tuned muchly.
109    *
110    * . Re-enable Heckbert locality for matching, benchmark it
111    *
112    * . Try faster fixed-point sRGB<->L*a*b* pixel conversion (see cpercep.c)
113    *
114    * . Use palette of another open INDEXED image?
115    *
116    * . Do error-splitting trick for GREY->INDEXED (hardly worth it)
117    */
118 
119   /* CODE READABILITY BUGS:
120    *
121    * . Most uses of variants of the R,G,B variable naming convention
122    *   are referring to L*a*b* co-ordinates, not RGB co-ordinates!
123    *
124    * . Each said variable is usually one of the following, but it is
125    *   rarely clear which one:
126    *     - (assumed sRGB) raw non-linear 8-bit RGB co-ordinates
127    *     - 'full'-precision (unshifted) 8-bit L*a*b* co-ordinates
128    *     - box-space (reduced-precision shifted L*a*b*) co-ordinates
129    */
130 
131 #include "config.h"
132 
133 #include <stdlib.h>
134 #include <stdio.h>
135 #include <string.h>
136 
137 #include <cairo.h>
138 #include <gdk-pixbuf/gdk-pixbuf.h>
139 #include <gegl.h>
140 
141 #include "libgimpcolor/gimpcolor.h"
142 #include "libgimpmath/gimpmath.h"
143 
144 #include "core-types.h"
145 
146 #include "gegl/gimp-babl.h"
147 #include "gegl/gimp-gegl-utils.h"
148 
149 #include "gimp.h"
150 #include "gimpcontainer.h"
151 #include "gimpdrawable.h"
152 #include "gimperror.h"
153 #include "gimpimage.h"
154 #include "gimpimage-color-profile.h"
155 #include "gimpimage-colormap.h"
156 #include "gimpimage-undo.h"
157 #include "gimpimage-undo-push.h"
158 #include "gimplayer.h"
159 #include "gimpobjectqueue.h"
160 #include "gimppalette.h"
161 #include "gimpprogress.h"
162 
163 #include "text/gimptextlayer.h"
164 
165 #include "gimpimage-convert-fsdither.h"
166 #include "gimpimage-convert-data.h"
167 #include "gimpimage-convert-indexed.h"
168 
169 #include "gimp-intl.h"
170 
171 
172 /* basic memory/quality tradeoff */
173 #define PRECISION_R 8
174 #define PRECISION_G 6
175 #define PRECISION_B 6
176 
177 #define HIST_R_ELEMS (1<<PRECISION_R)
178 #define HIST_G_ELEMS (1<<PRECISION_G)
179 #define HIST_B_ELEMS (1<<PRECISION_B)
180 
181 #define BITS_IN_SAMPLE 8
182 
183 #define R_SHIFT  (BITS_IN_SAMPLE-PRECISION_R)
184 #define G_SHIFT  (BITS_IN_SAMPLE-PRECISION_G)
185 #define B_SHIFT  (BITS_IN_SAMPLE-PRECISION_B)
186 
187 /* we've stretched our non-cubic L*a*b* volume to touch the
188  * faces of the logical cube we've allocated for it, so re-scale
189  * again in inverse proportion to get back to linear proportions.
190  */
191 #define R_SCALE 13              /*  scale R (L*) distances by this much  */
192 #define G_SCALE 24              /*  scale G (a*) distances by this much  */
193 #define B_SCALE 26              /*  and B (b*) by this much              */
194 
195 
196 typedef struct _Color Color;
197 typedef struct _QuantizeObj QuantizeObj;
198 
199 typedef void (* Pass1Func)     (QuantizeObj *quantize_obj);
200 typedef void (* Pass2InitFunc) (QuantizeObj *quantize_obj);
201 typedef void (* Pass2Func)     (QuantizeObj *quantize_obj,
202                                 GimpLayer   *layer,
203                                 GeglBuffer  *new_buffer);
204 typedef void (* CleanupFunc)   (QuantizeObj *quantize_obj);
205 
206 typedef guint64 ColorFreq;
207 typedef ColorFreq * CFHistogram;
208 
209 typedef enum { AXIS_UNDEF, AXIS_RED, AXIS_BLUE, AXIS_GREEN } AxisType;
210 
211 typedef double etype;
212 
213 
214 /*
215   We provide two different histogram access interfaces.  HIST_LIN()
216   accesses the histogram in histogram-native space, taking absolute
217   histogram co-ordinates.  HIST_RGB() accesses the histogram in RGB
218   space.  This latter takes unsigned 8-bit co-ordinates, internally
219   converts those co-ordinates to histogram-native space and returns
220   the access pointer to the corresponding histogram cell.
221 
222   Using these two interfaces we can import RGB data into a more
223   interesting space and efficiently work in the latter space until
224   it is time to output the quantized values in RGB again.  For
225   this final conversion we implement the function lin_to_rgb().
226 
227   We effectively pull our three-dimensional space into five dimensions
228   such that the most-entropic bits lay in the lowest bits of the resulting
229   array index.  This gives significantly better locality of reference
230   and hence a small speedup despite the extra work involved in calculating
231   the index.
232 
233   Why not six dimensions?  The expansion of dimensionality is good for random
234   access such as histogram population and the query pattern typical of
235   dithering but we have some code which iterates in a scanning manner, for
236   which the expansion is suboptimal.  The compromise is to leave the B
237   dimension unmolested in the lower-order bits of the index, since this is
238   the dimension most commonly iterated through in the inner loop of the
239   scans.
240 
241   --adam
242 
243   RhGhRlGlB
244 */
245 #define VOL_GBITS  (PRECISION_G)
246 #define VOL_BBITS  (PRECISION_B)
247 #define VOL_RBITS  (PRECISION_R)
248 #define VOL_GBITSh (VOL_GBITS - 3)
249 #define VOL_GBITSl (VOL_GBITS - VOL_GBITSh)
250 #define VOL_BBITSh (VOL_BBITS - 4)
251 #define VOL_BBITSl (VOL_BBITS - VOL_BBITSh)
252 #define VOL_RBITSh (VOL_RBITS - 3)
253 #define VOL_RBITSl (VOL_RBITS - VOL_RBITSh)
254 #define VOL_GMASKh (((1<<VOL_GBITSh)-1) << VOL_GBITSl)
255 #define VOL_GMASKl ((1<<VOL_GBITSl)-1)
256 #define VOL_BMASKh (((1<<VOL_BBITSh)-1) << VOL_BBITSl)
257 #define VOL_BMASKl ((1<<VOL_BBITSl)-1)
258 #define VOL_RMASKh (((1<<VOL_RBITSh)-1) << VOL_RBITSl)
259 #define VOL_RMASKl ((1<<VOL_RBITSl)-1)
260 /* The 5d compromise thing. */
261 #define REF_FUNC(r,g,b) \
262 ( \
263  (((r) & VOL_RMASKh) << (VOL_BBITS + VOL_GBITS)) | \
264  (((r) & VOL_RMASKl) << (VOL_GBITSl + VOL_BBITS)) | \
265  (((g) & VOL_GMASKh) << (VOL_RBITSl + VOL_BBITS)) | \
266  (((g) & VOL_GMASKl) << (VOL_BBITS)) | \
267  (b) \
268 )
269 /* The full-on 6d thing. */
270 /*
271 #define REF_FUNC(r,g,b) \
272 ( \
273  (((r) & VOL_RMASKh) << (VOL_BBITS + VOL_GBITS)) | \
274  (((r) & VOL_RMASKl) << (VOL_GBITSl + VOL_BBITSl)) | \
275  (((g) & VOL_GMASKh) << (VOL_RBITSl + VOL_BBITS)) | \
276  (((g) & VOL_GMASKl) << (VOL_BBITSl)) | \
277  (((b) & VOL_BMASKh) << (VOL_RBITSl + VOL_GBITSl)) | \
278  ((b) & VOL_BMASKl) \
279 )
280 */
281 /* The boring old 3d thing. */
282 /*
283 #define REF_FUNC(r,g,b) (((r)<<(PRECISION_G+PRECISION_B)) | ((g)<<(PRECISION_B)) | (b))
284 */
285 
286 /* You even get to choose whether you want the accessor function
287    implemented as a macro or an inline function.  Don't say I never
288    give you anything. */
289 /*
290 #define HIST_LIN(hist_ptr,r,g,b) (&(hist_ptr)[REF_FUNC((r),(g),(b))])
291 */
292 static inline ColorFreq *
HIST_LIN(ColorFreq * hist_ptr,const gint r,const gint g,const gint b)293 HIST_LIN (ColorFreq  *hist_ptr,
294           const gint  r,
295           const gint  g,
296           const gint  b)
297 {
298   return (&(hist_ptr) [REF_FUNC (r, g, b)]);
299 }
300 
301 
302 #define LOWA   (-86.181F)
303 #define LOWB  (-107.858F)
304 #define HIGHA   (98.237F)
305 #define HIGHB   (94.480F)
306 
307 #if 1
308 #define LRAT (2.55F)
309 #define ARAT (255.0F / (HIGHA - LOWA))
310 #define BRAT (255.0F / (HIGHB - LOWB))
311 #else
312 #define LRAT (1.0F)
313 #define ARAT (1.0F)
314 #define BRAT (1.0F)
315 #endif
316 
317 static const Babl *rgb_to_lab_fish = NULL;
318 static const Babl *lab_to_rgb_fish = NULL;
319 
320 static inline void
rgb_to_unshifted_lin(const guchar r,const guchar g,const guchar b,gint * hr,gint * hg,gint * hb)321 rgb_to_unshifted_lin (const guchar  r,
322                       const guchar  g,
323                       const guchar  b,
324                       gint         *hr,
325                       gint         *hg,
326                       gint         *hb)
327 {
328   gint   or, og, ob;
329   gfloat rgb[3] = { r / 255.0, g / 255.0, b / 255.0 };
330   gfloat lab[3];
331 
332   babl_process (rgb_to_lab_fish, rgb, lab, 1);
333 
334   /* fprintf(stderr, " %d-%d-%d -> %0.3f,%0.3f,%0.3f ", r, g, b, sL, sa, sb);*/
335 
336   or = RINT(lab[0] * LRAT);
337   og = RINT((lab[1] - LOWA) * ARAT);
338   ob = RINT((lab[2] - LOWB) * BRAT);
339 
340   *hr = CLAMP(or, 0, 255);
341   *hg = CLAMP(og, 0, 255);
342   *hb = CLAMP(ob, 0, 255);
343 
344   /*  fprintf(stderr, " %d:%d:%d ", *hr, *hg, *hb); */
345 }
346 
347 
348 static inline void
rgb_to_lin(const guchar r,const guchar g,const guchar b,gint * hr,gint * hg,gint * hb)349 rgb_to_lin (const guchar  r,
350             const guchar  g,
351             const guchar  b,
352             gint         *hr,
353             gint         *hg,
354             gint         *hb)
355 {
356   gint or, og, ob;
357 
358   /*
359   double sL, sa, sb;
360   {
361     double low_l = 999.0, low_a = 999.9, low_b = 999.0;
362     double high_l = -999.0, high_a = -999.0, high_b = -999.0;
363 
364     int r,g,b;
365 
366     for (r=0; r<256; r++)
367       for (g=0; g<256; g++)
368         for (b=0; b<256; b++)
369           {
370             cpercep_rgb_to_space(r,g,b, &sL, &sa, &sb);
371 
372             if (sL > high_l)
373               high_l = sL;
374             if (sL < low_l)
375               low_l = sL;
376             if (sa > high_a)
377               high_a = sa;
378             if (sa < low_a)
379               low_a = sa;
380             if (sb > high_b)
381               high_b = sb;
382             if (sb < low_b)
383               low_b = sb;
384           }
385 
386     fprintf(stderr, " [L: %0.3f -> %0.3f / a: %0.3f -> %0.3f / b: %0.3f -> %0.3f]\t", low_l, high_l, low_a, high_a, low_b, high_b);
387 
388     exit(-1);
389   }
390   */
391 
392   rgb_to_unshifted_lin (r, g, b, &or, &og, &ob);
393 
394 #if 0
395 #define RSDF(r) ((r) >= ((HIST_R_ELEMS-1) << R_SHIFT) ? HIST_R_ELEMS-1 : \
396                  ((r) + ((1<<R_SHIFT)>>1) ) >> R_SHIFT)
397 #define GSDF(g) ((g) >= ((HIST_G_ELEMS-1) << G_SHIFT) ? HIST_G_ELEMS-1 : \
398                  ((g) + ((1<<G_SHIFT)>>1) ) >> G_SHIFT)
399 #define BSDF(b) ((b) >= ((HIST_B_ELEMS-1) << B_SHIFT) ? HIST_B_ELEMS-1 : \
400                  ((b) + ((1<<B_SHIFT)>>1) ) >> B_SHIFT)
401 #else
402 #define RSDF(r) ((r) >> R_SHIFT)
403 #define GSDF(g) ((g) >> G_SHIFT)
404 #define BSDF(b) ((b) >> B_SHIFT)
405 #endif
406 
407   or = RSDF (or);
408   og = GSDF (og);
409   ob = BSDF (ob);
410 
411   *hr = or;
412   *hg = og;
413   *hb = ob;
414 }
415 
416 
417 static inline ColorFreq *
HIST_RGB(ColorFreq * hist_ptr,const gint r,const gint g,const gint b)418 HIST_RGB (ColorFreq  *hist_ptr,
419           const gint  r,
420           const gint  g,
421           const gint  b)
422 {
423   gint hr, hg, hb;
424 
425   rgb_to_lin (r, g, b, &hr, &hg, &hb);
426 
427   return HIST_LIN (hist_ptr, hr, hg, hb);
428 }
429 
430 
431 static inline void
lin_to_rgb(const gdouble hr,const gdouble hg,const gdouble hb,guchar * r,guchar * g,guchar * b)432 lin_to_rgb (const gdouble  hr,
433             const gdouble  hg,
434             const gdouble  hb,
435             guchar        *r,
436             guchar        *g,
437             guchar        *b)
438 {
439   gfloat  rgb[3];
440   gfloat  lab[3];
441   gdouble ir, ig, ib;
442 
443   ir = ((gdouble) (hr)) * 255.0F / (gdouble) (HIST_R_ELEMS - 1);
444   ig = ((gdouble)( hg)) * 255.0F / (gdouble) (HIST_G_ELEMS - 1);
445   ib = ((gdouble)( hb)) * 255.0F / (gdouble) (HIST_B_ELEMS - 1);
446 
447   ir = ir / LRAT;
448   ig = (ig / ARAT) + LOWA;
449   ib = (ib / BRAT) + LOWB;
450 
451   lab[0] = ir;
452   lab[1] = ig;
453   lab[2] = ib;
454 
455   babl_process (lab_to_rgb_fish, lab, rgb, 1);
456 
457   *r = RINT (CLAMP (rgb[0] * 255, 0.0F, 255.0F));
458   *g = RINT (CLAMP (rgb[1] * 255, 0.0F, 255.0F));
459   *b = RINT (CLAMP (rgb[2] * 255, 0.0F, 255.0F));
460 }
461 
462 
463 
464 struct _Color
465 {
466   gint red;
467   gint green;
468   gint blue;
469 };
470 
471 struct _QuantizeObj
472 {
473   Pass1Func     first_pass;       /* first pass over image data creates colormap  */
474   Pass2InitFunc second_pass_init; /* Initialize data which persists over invocations */
475   Pass2Func     second_pass;      /* second pass maps from image data to colormap */
476   CleanupFunc   delete_func;      /* function to clean up data associated with private */
477 
478   GimpPalette  *custom_palette;           /* The custom palette, if any        */
479 
480   gint          desired_number_of_colors; /* Number of colors we will allow    */
481   gint          actual_number_of_colors;  /* Number of colors actually needed  */
482   Color         cmap[256];                /* colormap created by quantization  */
483   Color         clin[256];                /* .. converted back to linear space */
484   guint64       index_used_count[256];    /* how many times an index was used  */
485   CFHistogram   histogram;                /* holds the histogram               */
486 
487   gboolean      want_dither_alpha;
488   gint          error_freedom;            /* 0=much bleed, 1=controlled bleed */
489 
490   GimpProgress *progress;
491 };
492 
493 typedef struct
494 {
495   /*  The bounds of the box (inclusive); expressed as histogram indexes  */
496   gint    Rmin, Rmax;
497   gint    Rhalferror;
498   gint    Gmin, Gmax;
499   gint    Ghalferror;
500   gint    Bmin, Bmax;
501   gint    Bhalferror;
502 
503   /*  The volume (actually 2-norm) of the box  */
504   gint    volume;
505 
506   /*  The number of nonzero histogram cells within this box  */
507   gint64  colorcount;
508 
509   /* The sum of the weighted error within this box */
510   guint64 error;
511   /* The sum of the unweighted error within this box */
512   guint64 rerror;
513   guint64 gerror;
514   guint64 berror;
515 
516 } box, *boxptr;
517 
518 
519 static void          zero_histogram_gray     (CFHistogram   histogram);
520 static void          zero_histogram_rgb      (CFHistogram   histogram);
521 static void          generate_histogram_gray (CFHistogram   hostogram,
522                                               GimpLayer    *layer,
523                                               gboolean      dither_alpha);
524 static void          generate_histogram_rgb  (CFHistogram   histogram,
525                                               GimpLayer    *layer,
526                                               gint          col_limit,
527                                               gboolean      dither_alpha,
528                                               GimpProgress *progress);
529 
530 static QuantizeObj * initialize_median_cut   (GimpImageBaseType      old_type,
531                                               gint                   max_colors,
532                                               GimpConvertDitherType  dither_type,
533                                               GimpConvertPaletteType palette_type,
534                                               GimpPalette           *custom_palette,
535                                               gboolean               dither_alpha,
536                                               GimpProgress          *progress);
537 
538 static void          compute_color_lin8      (QuantizeObj           *quantobj,
539                                               CFHistogram            histogram,
540                                               boxptr                 boxp,
541                                               const int              icolor);
542 
543 
544 static guchar    found_cols[MAXNUMCOLORS][3];
545 static gint      num_found_cols;
546 static gboolean  needs_quantize;
547 static gboolean  had_white;
548 static gboolean  had_black;
549 
550 
551 /**********************************************************/
552 typedef struct
553 {
554   gint64 used_count;
555   guchar initial_index;
556 } PalEntry;
557 
558 static int
mapping_compare(const void * a,const void * b)559 mapping_compare (const void *a,
560                  const void *b)
561 {
562   PalEntry *m1 = (PalEntry *) a;
563   PalEntry *m2 = (PalEntry *) b;
564 
565   return (m2->used_count - m1->used_count);
566 }
567 
568 /* FWIW, the make_remap_table() and mapping_compare() function source
569  * and PalEntry may be re-used under the XFree86-style license.
570  * <adam@gimp.org>
571  */
572 static void
make_remap_table(const guchar old_palette[],guchar new_palette[],const guint64 index_used_count[],guchar remap_table[],gint * num_entries)573 make_remap_table (const guchar  old_palette[],
574                   guchar        new_palette[],
575                   const guint64 index_used_count[],
576                   guchar        remap_table[],
577                   gint         *num_entries)
578 {
579   gint      i, j, k;
580   guchar    temppal[256 * 3];
581   guint64   tempuse[256];
582   guint64   transmap[256];
583   PalEntry *palentries;
584   gint      used = 0;
585 
586   memset (temppal, 0, 256 * 3);
587   memset (tempuse, 0, 256 * sizeof (guint64));
588   memset (transmap, 255, 256 * sizeof (guint64));
589 
590   /* First pass - only collect entries which are marked as being used
591    * at all in index_used_count.
592    */
593   for (i = 0; i < *num_entries; i++)
594     {
595       if (index_used_count[i])
596         {
597           temppal[used*3 + 0] = old_palette[i*3 + 0];
598           temppal[used*3 + 1] = old_palette[i*3 + 1];
599           temppal[used*3 + 2] = old_palette[i*3 + 2];
600 
601           tempuse[used] = index_used_count[i];
602           transmap[i] = used;
603 
604           used++;
605         }
606     }
607 
608   /* Second pass - remove duplicates. (O(n^3), could do better!) */
609   for (i = 0; i < used; i++)
610     {
611       for (j = 0; j < i; j++)
612         {
613           if ((temppal[i*3 + 1] == temppal[j*3 + 1]) &&
614               (temppal[i*3 + 0] == temppal[j*3 + 0]) &&
615               (temppal[i*3 + 2] == temppal[j*3 + 2]) &&
616               tempuse[j] &&
617               tempuse[i])
618             {
619               /* Move the 'used' tally from one to the other. */
620               tempuse[i] += tempuse[j];
621               /* zero one of them, deactivating its entry. */
622               tempuse[j] = 0;
623 
624               /* change all mappings from this dead index to the live
625                * one.
626                */
627               for (k = 0; k < *num_entries; k++)
628                 {
629                   if (index_used_count[k] && (transmap[k] == j))
630                     transmap[k] = i;
631                 }
632             }
633         }
634     }
635 
636   /* Third pass - rank all used indices to the beginning of the
637    * palette.
638    */
639   palentries = g_new (PalEntry, used);
640 
641   for (i = 0; i < used; i++)
642     {
643       palentries[i].initial_index = i;
644       palentries[i].used_count    = tempuse[i];
645     }
646 
647   qsort (palentries, used, sizeof (PalEntry), &mapping_compare);
648 
649   for (i = 0; i < *num_entries; i++)
650     {
651       if (index_used_count[i])
652         {
653           for (j = 0; j < used; j++)
654             {
655               if ((transmap[i] == palentries[j].initial_index)
656                   && (palentries[j].used_count))
657                 {
658                   remap_table[i] = j;
659                   break;
660                 }
661             }
662         }
663     }
664   for (i = 0; i < *num_entries; i++)
665     {
666       if (index_used_count[i])
667         {
668           new_palette[remap_table[i] * 3 + 0] = old_palette[i * 3 + 0];
669           new_palette[remap_table[i] * 3 + 1] = old_palette[i * 3 + 1];
670           new_palette[remap_table[i] * 3 + 2] = old_palette[i * 3 + 2];
671         }
672     }
673 
674   *num_entries = 0;
675 
676   for (j = 0; j < used; j++)
677     {
678       if (palentries[j].used_count)
679         {
680           (*num_entries)++;
681         }
682     }
683 
684   g_free (palentries);
685 }
686 
687 static void
remap_indexed_layer(GimpLayer * layer,const guchar * remap_table,gint num_entries)688 remap_indexed_layer (GimpLayer    *layer,
689                      const guchar *remap_table,
690                      gint          num_entries)
691 {
692   GeglBufferIterator *iter;
693   const Babl         *format;
694   gint                bpp;
695   gboolean            has_alpha;
696 
697   format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
698 
699   bpp       = babl_format_get_bytes_per_pixel (format);
700   has_alpha = babl_format_has_alpha (format);
701 
702   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
703                                    NULL, 0, NULL,
704                                    GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE, 1);
705 
706   while (gegl_buffer_iterator_next (iter))
707     {
708       guchar *data   = iter->items[0].data;
709       gint    length = iter->length;
710 
711       if (has_alpha)
712         {
713           while (length--)
714             {
715               if (data[ALPHA_I])
716                 data[INDEXED] = remap_table[data[INDEXED]];
717               else
718                 data[INDEXED] = 0;
719 
720               data += bpp;
721             }
722         }
723       else
724         {
725           while (length--)
726             {
727               data[INDEXED] = remap_table[data[INDEXED]];
728 
729               data += bpp;
730             }
731         }
732     }
733 }
734 
735 static gint
color_quicksort(const void * c1,const void * c2)736 color_quicksort (const void *c1,
737                  const void *c2)
738 {
739   Color *color1 = (Color *) c1;
740   Color *color2 = (Color *) c2;
741 
742   gdouble v1 = GIMP_RGB_LUMINANCE (color1->red, color1->green, color1->blue);
743   gdouble v2 = GIMP_RGB_LUMINANCE (color2->red, color2->green, color2->blue);
744 
745   if (v1 < v2)
746     return -1;
747   else if (v1 > v2)
748     return 1;
749   else
750     return 0;
751 }
752 
753 gboolean
gimp_image_convert_indexed(GimpImage * image,GimpConvertPaletteType palette_type,gint max_colors,gboolean remove_duplicates,GimpConvertDitherType dither_type,gboolean dither_alpha,gboolean dither_text_layers,GimpPalette * custom_palette,GimpProgress * progress,GError ** error)754 gimp_image_convert_indexed (GimpImage               *image,
755                             GimpConvertPaletteType   palette_type,
756                             gint                     max_colors,
757                             gboolean                 remove_duplicates,
758                             GimpConvertDitherType    dither_type,
759                             gboolean                 dither_alpha,
760                             gboolean                 dither_text_layers,
761                             GimpPalette             *custom_palette,
762                             GimpProgress            *progress,
763                             GError                 **error)
764 {
765   QuantizeObj       *quantobj     = NULL;
766   GimpObjectQueue   *queue        = NULL;
767   GimpProgress      *sub_progress = NULL;
768   GimpImageBaseType  old_type;
769   GList             *all_layers;
770   GList             *list;
771   GimpColorProfile  *dest_profile = NULL;
772 
773   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
774   g_return_val_if_fail (gimp_image_get_base_type (image) != GIMP_INDEXED, FALSE);
775   g_return_val_if_fail (gimp_babl_is_valid (GIMP_INDEXED,
776                                             gimp_image_get_precision (image)),
777                         FALSE);
778   g_return_val_if_fail (custom_palette == NULL ||
779                         GIMP_IS_PALETTE (custom_palette), FALSE);
780   g_return_val_if_fail (custom_palette == NULL ||
781                         gimp_palette_get_n_colors (custom_palette) <= 256,
782                         FALSE);
783   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
784   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
785 
786   if (palette_type == GIMP_CONVERT_PALETTE_CUSTOM)
787     {
788       if (! custom_palette)
789         palette_type = GIMP_CONVERT_PALETTE_MONO;
790 
791       if (gimp_palette_get_n_colors (custom_palette) == 0)
792         {
793           g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
794                                _("Cannot convert image: palette is empty."));
795           return FALSE;
796         }
797     }
798 
799   gimp_set_busy (image->gimp);
800 
801   all_layers = gimp_image_get_layer_list (image);
802 
803   g_object_freeze_notify (G_OBJECT (image));
804 
805   gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
806                                C_("undo-type", "Convert Image to Indexed"));
807 
808   /*  Push the image type to the stack  */
809   gimp_image_undo_push_image_type (image, NULL);
810 
811   /*  Set the new base type  */
812   old_type = gimp_image_get_base_type (image);
813 
814   g_object_set (image, "base-type", GIMP_INDEXED, NULL);
815 
816   /* when converting from GRAY, convert to the new type's builtin
817    * profile.
818    */
819   if (old_type == GIMP_GRAY)
820     {
821       if (gimp_image_get_color_profile (image))
822         dest_profile = gimp_image_get_builtin_color_profile (image);
823     }
824 
825   /*  Build histogram if necessary.  */
826   rgb_to_lab_fish = babl_fish (babl_format ("R'G'B' float"),
827                                babl_format ("CIE Lab float"));
828   lab_to_rgb_fish = babl_fish (babl_format ("CIE Lab float"),
829                                babl_format ("R'G'B' float"));
830 
831   /* don't dither if the input is grayscale and we are simply mapping
832    * every color
833    */
834   if (old_type     == GIMP_GRAY &&
835       max_colors   == 256       &&
836       palette_type == GIMP_CONVERT_PALETTE_GENERATE)
837     {
838       dither_type = GIMP_CONVERT_DITHER_NONE;
839     }
840 
841   if (progress)
842     {
843       queue        = gimp_object_queue_new (progress);
844       sub_progress = GIMP_PROGRESS (queue);
845 
846       gimp_object_queue_push_list (queue, all_layers);
847     }
848 
849   quantobj = initialize_median_cut (old_type, max_colors, dither_type,
850                                     palette_type, custom_palette,
851                                     dither_alpha,
852                                     sub_progress);
853 
854   if (palette_type == GIMP_CONVERT_PALETTE_GENERATE)
855     {
856       if (old_type == GIMP_GRAY)
857         zero_histogram_gray (quantobj->histogram);
858       else
859         zero_histogram_rgb (quantobj->histogram);
860 
861       /* To begin, assume that there are fewer colors in the image
862        *  than the user actually asked for.  In that case, we don't
863        *  need to quantize or color-dither.
864        */
865       needs_quantize = FALSE;
866       had_black = FALSE;
867       had_white = FALSE;
868       num_found_cols = 0;
869 
870       /*  Build the histogram  */
871       for (list = all_layers;
872            list;
873            list = g_list_next (list))
874         {
875           GimpLayer *layer = list->data;
876 
877           if (queue)
878             gimp_object_queue_pop (queue);
879 
880           if (old_type == GIMP_GRAY)
881             {
882               generate_histogram_gray (quantobj->histogram,
883                                        layer, dither_alpha);
884             }
885           else
886             {
887               /* Note: generate_histogram_rgb may set needs_quantize
888                * if the image contains more colors than the limit
889                * specified by the user.
890                */
891               generate_histogram_rgb (quantobj->histogram,
892                                       layer, max_colors, dither_alpha,
893                                       sub_progress);
894             }
895         }
896     }
897 
898   if (progress)
899     gimp_progress_set_text_literal (progress,
900                                     _("Converting to indexed colors (stage 2)"));
901 
902   if (old_type == GIMP_RGB &&
903       ! needs_quantize     &&
904       palette_type == GIMP_CONVERT_PALETTE_GENERATE)
905     {
906       gint i;
907 
908       /*  If this is an RGB image, and the user wanted a custom-built
909        *  generated palette, and this image has no more colors than
910        *  the user asked for, we don't need the first pass
911        *  (quantization).
912        *
913        *  There's also no point in dithering, since there's no error
914        *  to spread.  So we destroy the old quantobj and make a new
915        *  one with the remapping function set to a special LUT-based
916        *  no-dither remapper.
917        */
918 
919       quantobj->delete_func (quantobj);
920       quantobj = initialize_median_cut (old_type, max_colors,
921                                         GIMP_CONVERT_DITHER_NODESTRUCT,
922                                         palette_type,
923                                         custom_palette,
924                                         dither_alpha,
925                                         sub_progress);
926       /* We can skip the first pass (palette creation) */
927 
928       quantobj->actual_number_of_colors = num_found_cols;
929       for (i = 0; i < num_found_cols; i++)
930         {
931           quantobj->cmap[i].red   = found_cols[i][0];
932           quantobj->cmap[i].green = found_cols[i][1];
933           quantobj->cmap[i].blue  = found_cols[i][2];
934         }
935     }
936   else
937     {
938       quantobj->first_pass (quantobj);
939     }
940 
941   if (palette_type == GIMP_CONVERT_PALETTE_GENERATE)
942     qsort (quantobj->cmap,
943            quantobj->actual_number_of_colors, sizeof (Color),
944            color_quicksort);
945 
946   if (progress)
947     {
948       gimp_progress_set_text_literal (progress,
949                                       _("Converting to indexed colors (stage 3)"));
950 
951       gimp_object_queue_clear (queue);
952       gimp_object_queue_push_list (queue, all_layers);
953     }
954 
955   /* Initialise data which must persist across indexed layer iterations */
956   if (quantobj->second_pass_init)
957     quantobj->second_pass_init (quantobj);
958 
959   /*  Set the generated palette on the image, we need it to
960    *  convert the layers. We optionally remove duplicate entries
961    *  after the layer conversion.
962    */
963   {
964     guchar colormap[GIMP_IMAGE_COLORMAP_SIZE];
965     gint   i, j;
966 
967     for (i = 0, j = 0; i < quantobj->actual_number_of_colors; i++)
968       {
969         colormap[j++] = quantobj->cmap[i].red;
970         colormap[j++] = quantobj->cmap[i].green;
971         colormap[j++] = quantobj->cmap[i].blue;
972       }
973 
974     gimp_image_set_colormap (image, colormap,
975                              quantobj->actual_number_of_colors, TRUE);
976   }
977 
978   /*  Convert all layers  */
979   for (list = all_layers;
980        list;
981        list = g_list_next (list))
982     {
983       GimpLayer *layer = list->data;
984       gboolean   quantize;
985 
986       if (queue)
987         gimp_object_queue_pop (queue);
988 
989       if (gimp_item_is_text_layer (GIMP_ITEM (layer)))
990         quantize = dither_text_layers;
991       else
992         quantize = TRUE;
993 
994       if (quantize)
995         {
996           GeglBuffer *new_buffer;
997           gboolean    has_alpha;
998 
999           has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
1000 
1001           new_buffer =
1002             gegl_buffer_new (GEGL_RECTANGLE (0, 0,
1003                                              gimp_item_get_width  (GIMP_ITEM (layer)),
1004                                              gimp_item_get_height (GIMP_ITEM (layer))),
1005                              gimp_image_get_layer_format (image,
1006                                                           has_alpha));
1007 
1008           quantobj->second_pass (quantobj, layer, new_buffer);
1009 
1010           gimp_drawable_set_buffer (GIMP_DRAWABLE (layer), TRUE, NULL,
1011                                     new_buffer);
1012           g_object_unref (new_buffer);
1013         }
1014       else
1015         {
1016           gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
1017                                       GIMP_INDEXED,
1018                                       gimp_drawable_get_precision (GIMP_DRAWABLE (layer)),
1019                                       gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)),
1020                                       dest_profile,
1021                                       GEGL_DITHER_NONE, GEGL_DITHER_NONE,
1022                                       TRUE, sub_progress);
1023         }
1024     }
1025 
1026   /*  Set the final palette on the image  */
1027   if (remove_duplicates &&
1028       (palette_type != GIMP_CONVERT_PALETTE_GENERATE) &&
1029       (palette_type != GIMP_CONVERT_PALETTE_MONO))
1030     {
1031       guchar colormap[GIMP_IMAGE_COLORMAP_SIZE];
1032       gint   i, j;
1033       guchar old_palette[256 * 3];
1034       guchar new_palette[256 * 3];
1035       guchar remap_table[256];
1036       gint   num_entries;
1037 
1038       for (i = 0, j = 0; i < quantobj->actual_number_of_colors; i++)
1039         {
1040           old_palette[j++] = quantobj->cmap[i].red;
1041           old_palette[j++] = quantobj->cmap[i].green;
1042           old_palette[j++] = quantobj->cmap[i].blue;
1043         }
1044 
1045       num_entries = quantobj->actual_number_of_colors;
1046 
1047       /* Generate a remapping table */
1048       make_remap_table (old_palette, new_palette,
1049                         quantobj->index_used_count,
1050                         remap_table, &num_entries);
1051 
1052       /*  Convert all layers  */
1053       for (list = all_layers; list; list = g_list_next (list))
1054         {
1055           remap_indexed_layer (list->data, remap_table, num_entries);
1056         }
1057 
1058       for (i = 0, j = 0; i < num_entries; i++)
1059         {
1060           colormap[j] = new_palette[j]; j++;
1061           colormap[j] = new_palette[j]; j++;
1062           colormap[j] = new_palette[j]; j++;
1063         }
1064 
1065       gimp_image_set_colormap (image, colormap, num_entries, TRUE);
1066     }
1067 
1068   /*  When converting from GRAY, set the new profile.
1069    */
1070   if (old_type == GIMP_GRAY)
1071     {
1072       if (gimp_image_get_color_profile (image))
1073         gimp_image_set_color_profile (image, dest_profile, NULL);
1074       else
1075         gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image));
1076     }
1077 
1078   /*  Delete the quantizer object, if there is one */
1079   if (quantobj)
1080     quantobj->delete_func (quantobj);
1081 
1082   gimp_image_undo_group_end (image);
1083 
1084   gimp_image_mode_changed (image);
1085   g_object_thaw_notify (G_OBJECT (image));
1086 
1087   g_clear_object (&queue);
1088 
1089   g_list_free (all_layers);
1090 
1091   gimp_unset_busy (image->gimp);
1092 
1093   return TRUE;
1094 }
1095 
1096 /*
1097  *  Indexed color conversion machinery
1098  */
1099 
1100 static void
zero_histogram_gray(CFHistogram histogram)1101 zero_histogram_gray (CFHistogram histogram)
1102 {
1103   gint i;
1104 
1105   for (i = 0; i < 256; i++)
1106     histogram[i] = 0;
1107 }
1108 
1109 
1110 static void
zero_histogram_rgb(CFHistogram histogram)1111 zero_histogram_rgb (CFHistogram histogram)
1112 {
1113   memset (histogram, 0,
1114           HIST_R_ELEMS * HIST_G_ELEMS * HIST_B_ELEMS * sizeof (ColorFreq));
1115 }
1116 
1117 
1118 static void
generate_histogram_gray(CFHistogram histogram,GimpLayer * layer,gboolean dither_alpha)1119 generate_histogram_gray (CFHistogram  histogram,
1120                          GimpLayer   *layer,
1121                          gboolean     dither_alpha)
1122 {
1123   GeglBufferIterator *iter;
1124   const Babl         *format;
1125   gint                bpp;
1126   gboolean            has_alpha;
1127 
1128   format = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
1129 
1130   g_return_if_fail (format == babl_format_with_space ("Y' u8", format) ||
1131                     format == babl_format_with_space ("Y'A u8", format));
1132 
1133   bpp       = babl_format_get_bytes_per_pixel (format);
1134   has_alpha = babl_format_has_alpha (format);
1135 
1136   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
1137                                    NULL, 0, format,
1138                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
1139 
1140   while (gegl_buffer_iterator_next (iter))
1141     {
1142       const guchar *data   = iter->items[0].data;
1143       gint          length = iter->length;
1144 
1145       if (has_alpha)
1146         {
1147           while (length--)
1148             {
1149               if (data[ALPHA_G] > 127)
1150                 histogram[*data]++;
1151 
1152               data += bpp;
1153             }
1154         }
1155       else
1156         {
1157           while (length--)
1158             {
1159               histogram[*data]++;
1160 
1161               data += bpp;
1162             }
1163         }
1164     }
1165 }
1166 
1167 static void
check_white_or_black(const guchar * data)1168 check_white_or_black (const guchar *data)
1169 {
1170   if (data[RED]   == 255 &&
1171       data[GREEN] == 255 &&
1172       data[BLUE]  == 255)
1173     had_white = TRUE;
1174   if (data[RED]  ==0 &&
1175       data[GREEN]==0 &&
1176       data[BLUE] ==0)
1177     had_black = TRUE;
1178 }
1179 
1180 static void
generate_histogram_rgb(CFHistogram histogram,GimpLayer * layer,gint col_limit,gboolean dither_alpha,GimpProgress * progress)1181 generate_histogram_rgb (CFHistogram   histogram,
1182                         GimpLayer    *layer,
1183                         gint          col_limit,
1184                         gboolean      dither_alpha,
1185                         GimpProgress *progress)
1186 {
1187   GeglBufferIterator *iter;
1188   const Babl         *format;
1189   GeglRectangle      *roi;
1190   ColorFreq          *colfreq;
1191   gint                nfc_iter;
1192   gint                row, col, coledge;
1193   gint                offsetx, offsety;
1194   gint64              layer_size;
1195   gint64              total_size = 0;
1196   gint                count      = 0;
1197   gint                bpp;
1198   gboolean            has_alpha;
1199 
1200   format = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
1201 
1202   g_return_if_fail (format == babl_format ("R'G'B' u8") ||
1203                     format == babl_format ("R'G'B'A u8"));
1204 
1205   bpp       = babl_format_get_bytes_per_pixel (format);
1206   has_alpha = babl_format_has_alpha (format);
1207 
1208   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
1209 
1210   layer_size = (gimp_item_get_width  (GIMP_ITEM (layer)) *
1211                 gimp_item_get_height (GIMP_ITEM (layer)));
1212 
1213   /*  g_printerr ("col_limit = %d, nfc = %d\n", col_limit, num_found_cols); */
1214 
1215   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
1216                                    NULL, 0, format,
1217                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);
1218   roi = &iter->items[0].roi;
1219 
1220   if (progress)
1221     gimp_progress_set_value (progress, 0.0);
1222 
1223   while (gegl_buffer_iterator_next (iter))
1224     {
1225       const guchar *data   = iter->items[0].data;
1226       gint          length = iter->length;
1227 
1228       total_size += length;
1229 
1230       /* g_printerr (" [%d,%d - %d,%d]", srcPR.x, src_roi->y, offsetx, offsety); */
1231 
1232       if (needs_quantize)
1233         {
1234           if (dither_alpha)
1235             {
1236               /* if alpha-dithering,
1237                  we need to be deterministic w.r.t. offsets */
1238 
1239               col = roi->x + offsetx;
1240               coledge = col + roi->width;
1241               row = roi->y + offsety;
1242 
1243               while (length--)
1244                 {
1245                   gboolean transparent = FALSE;
1246 
1247                   if (has_alpha &&
1248                       data[ALPHA] <
1249                       DM[col & DM_WIDTHMASK][row & DM_HEIGHTMASK])
1250                     transparent = TRUE;
1251 
1252                   if (! transparent)
1253                     {
1254                       colfreq = HIST_RGB (histogram,
1255                                           data[RED],
1256                                           data[GREEN],
1257                                           data[BLUE]);
1258                       check_white_or_black (data);
1259                       (*colfreq)++;
1260                     }
1261 
1262                   col++;
1263                   if (col == coledge)
1264                     {
1265                       col = roi->x + offsetx;
1266                       row++;
1267                     }
1268 
1269                   data += bpp;
1270                 }
1271             }
1272           else
1273             {
1274               while (length--)
1275                 {
1276                   if ((has_alpha && ((data[ALPHA] > 127)))
1277                       || (!has_alpha))
1278                     {
1279                       colfreq = HIST_RGB (histogram,
1280                                           data[RED],
1281                                           data[GREEN],
1282                                           data[BLUE]);
1283                       check_white_or_black (data);
1284                       (*colfreq)++;
1285                     }
1286 
1287                   data += bpp;
1288                 }
1289             }
1290         }
1291       else
1292         {
1293           /* if alpha-dithering, we need to be deterministic w.r.t. offsets */
1294           col = roi->x + offsetx;
1295           coledge = col + roi->width;
1296           row = roi->y + offsety;
1297 
1298           while (length--)
1299             {
1300               gboolean transparent = FALSE;
1301 
1302               if (has_alpha)
1303                 {
1304                   if (dither_alpha)
1305                     {
1306                       if (data[ALPHA] <
1307                           DM[col & DM_WIDTHMASK][row & DM_HEIGHTMASK])
1308                         transparent = TRUE;
1309                     }
1310                   else
1311                     {
1312                       if (data[ALPHA] <= 127)
1313                         transparent = TRUE;
1314                     }
1315                 }
1316 
1317               if (! transparent)
1318                 {
1319                   colfreq = HIST_RGB (histogram,
1320                                       data[RED],
1321                                       data[GREEN],
1322                                       data[BLUE]);
1323                   (*colfreq)++;
1324 
1325                   if (!needs_quantize)
1326                     {
1327                       for (nfc_iter = 0;
1328                            nfc_iter < num_found_cols;
1329                            nfc_iter++)
1330                         {
1331                           if ((data[RED]   == found_cols[nfc_iter][0]) &&
1332                               (data[GREEN] == found_cols[nfc_iter][1]) &&
1333                               (data[BLUE]  == found_cols[nfc_iter][2]))
1334                             goto already_found;
1335                         }
1336 
1337                       /* Color was not in the table of
1338                        * existing colors
1339                        */
1340 
1341                       num_found_cols++;
1342 
1343                       if (num_found_cols > col_limit)
1344                         {
1345                           /* There are more colors in the image than
1346                            *  were allowed.  We switch to plain
1347                            *  histogram calculation with a view to
1348                            *  quantizing at a later stage.
1349                            */
1350                           needs_quantize = TRUE;
1351                           /* g_print ("\nmax colors exceeded - needs quantize.\n");*/
1352                           goto already_found;
1353                         }
1354                       else
1355                         {
1356                           /* Remember the new color we just found.
1357                            */
1358                           found_cols[num_found_cols-1][0] = data[RED];
1359                           found_cols[num_found_cols-1][1] = data[GREEN];
1360                           found_cols[num_found_cols-1][2] = data[BLUE];
1361 
1362                           check_white_or_black (data);
1363                         }
1364                     }
1365                 }
1366             already_found:
1367 
1368               col++;
1369               if (col == coledge)
1370                 {
1371                   col = roi->x + offsetx;
1372                   row++;
1373                 }
1374 
1375               data += bpp;
1376             }
1377         }
1378 
1379       if (progress && (count % 16 == 0))
1380         gimp_progress_set_value (progress,
1381                                  (gdouble) total_size / (gdouble) layer_size);
1382     }
1383 
1384 /*  g_print ("O: col_limit = %d, nfc = %d\n", col_limit, num_found_cols);*/
1385 }
1386 
1387 
1388 
1389 static boxptr
find_split_candidate(const boxptr boxlist,const gint numboxes,AxisType * which_axis,const gint desired_colors)1390 find_split_candidate (const boxptr  boxlist,
1391                       const gint    numboxes,
1392                       AxisType     *which_axis,
1393                       const gint    desired_colors)
1394 {
1395   boxptr  boxp;
1396   gint    i;
1397   etype   maxc = 0;
1398   boxptr  which = NULL;
1399   gdouble Lbias;
1400 
1401   *which_axis = AXIS_UNDEF;
1402 
1403   /* we only perform the initial L-split bias /at all/ if the final
1404      number of desired colors is quite low, otherwise it all comes
1405      out in the wash anyway and this initial bias generally only hurts
1406      us in the long run. */
1407   if (desired_colors <= 16)
1408     {
1409 #define BIAS_FACTOR 2.66F
1410 #define BIAS_NUMBER 2 /* 0 */
1411 
1412       /* we bias towards splitting across L* for first few colors */
1413       Lbias = (numboxes > BIAS_NUMBER) ? 1.0F : ((gdouble) (BIAS_NUMBER + 1) -
1414                                                  ((gdouble) numboxes)) /
1415         ((gdouble) BIAS_NUMBER / BIAS_FACTOR);
1416       /*Lbias = 1.0;
1417         fprintf(stderr, " [[%d]] ", numboxes);
1418         fprintf(stderr, "Using ramped L-split bias.\n");
1419         fprintf(stderr, "R\n");
1420       */
1421     }
1422   else
1423     Lbias = 1.0F;
1424 
1425   for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
1426     {
1427       if (boxp->volume > 0)
1428         {
1429 #ifndef _MSC_VER
1430           etype rpe = (double)((boxp->rerror) * R_SCALE * R_SCALE);
1431           etype gpe = (double)((boxp->gerror) * G_SCALE * G_SCALE);
1432           etype bpe = (double)((boxp->berror) * B_SCALE * B_SCALE);
1433 #else
1434           /*
1435            * Sorry about the mess, otherwise would get :
1436            * error C2520: conversion from unsigned __int64 to double
1437            *              not implemented, use signed __int64
1438            */
1439           etype rpe = (double)(((__int64)boxp->rerror) * R_SCALE * R_SCALE);
1440           etype gpe = (double)(((__int64)boxp->gerror) * G_SCALE * G_SCALE);
1441           etype bpe = (double)(((__int64)boxp->berror) * B_SCALE * B_SCALE);
1442 #endif
1443 
1444           if (Lbias * rpe > maxc &&
1445               boxp->Rmin < boxp->Rmax)
1446             {
1447               which = boxp;
1448               maxc  = Lbias * rpe;
1449               *which_axis = AXIS_RED;
1450             }
1451 
1452           if (gpe > maxc &&
1453               boxp->Gmin < boxp->Gmax)
1454             {
1455               which = boxp;
1456               maxc  = gpe;
1457               *which_axis = AXIS_GREEN;
1458             }
1459 
1460           if (bpe > maxc &&
1461               boxp->Bmin < boxp->Bmax)
1462             {
1463               which = boxp;
1464               maxc  = bpe;
1465               *which_axis = AXIS_BLUE;
1466             }
1467         }
1468     }
1469 
1470   /*  fprintf(stderr, " %f,%p ", maxc, which); */
1471   /*  fprintf(stderr, " %llu ", maxc); */
1472 
1473   return which;
1474 }
1475 
1476 
1477 /* Find the splittable box with the largest (scaled) volume Returns
1478  * NULL if no splittable boxes remain
1479  */
1480 static boxptr
find_biggest_volume(const boxptr boxlist,const gint numboxes)1481 find_biggest_volume (const boxptr boxlist,
1482                      const gint   numboxes)
1483 {
1484   boxptr boxp;
1485   gint   i;
1486   gint   maxv = 0;
1487   boxptr which = NULL;
1488 
1489   for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
1490     {
1491       if (boxp->volume > maxv)
1492         {
1493           which = boxp;
1494           maxv = boxp->volume;
1495         }
1496     }
1497 
1498   return which;
1499 }
1500 
1501 
1502 /* Shrink the min/max bounds of a box to enclose only nonzero
1503  * elements, and recompute its volume and population
1504  */
1505 static void
update_box_gray(const CFHistogram histogram,boxptr boxp)1506 update_box_gray (const CFHistogram histogram,
1507                  boxptr            boxp)
1508 {
1509   gint      i, min, max, dist;
1510   ColorFreq ccount;
1511 
1512   min = boxp->Rmin;
1513   max = boxp->Rmax;
1514 
1515   if (max > min)
1516     for (i = min; i <= max; i++)
1517       {
1518         if (histogram[i] != 0)
1519           {
1520             boxp->Rmin = min = i;
1521             break;
1522           }
1523       }
1524 
1525   if (max > min)
1526     for (i = max; i >= min; i--)
1527       {
1528         if (histogram[i] != 0)
1529           {
1530             boxp->Rmax = max = i;
1531             break;
1532           }
1533       }
1534 
1535   /* Update box volume.
1536    * We use 2-norm rather than real volume here; this biases the method
1537    * against making long narrow boxes, and it has the side benefit that
1538    * a box is splittable iff norm > 0.
1539    * Since the differences are expressed in histogram-cell units,
1540    * we have to shift back to JSAMPLE units to get consistent distances;
1541    * after which, we scale according to the selected distance scale factors.
1542    */
1543   dist = max - min;
1544   boxp->volume = dist * dist;
1545 
1546   /* Now scan remaining volume of box and compute population */
1547   ccount = 0;
1548   for (i = min; i <= max; i++)
1549     if (histogram[i] != 0)
1550       ccount++;
1551 
1552   boxp->colorcount = ccount;
1553 }
1554 
1555 
1556 /* Shrink the min/max bounds of a box to enclose only nonzero
1557  * elements, and recompute its volume, population and error
1558  */
1559 static void
update_box_rgb(const CFHistogram histogram,boxptr boxp,const gint cells_remaining)1560 update_box_rgb (const CFHistogram histogram,
1561                 boxptr            boxp,
1562                 const gint        cells_remaining)
1563 {
1564   gint      R, G, B;
1565   gint      Rmin, Rmax, Gmin, Gmax, Bmin, Bmax;
1566   gint      dist0, dist1, dist2;
1567   ColorFreq ccount;
1568   /*
1569   guint64 tempRerror;
1570   guint64 tempGerror;
1571   guint64 tempBerror;
1572   */
1573   QuantizeObj dummyqo;
1574   box         dummybox;
1575 
1576   /* fprintf(stderr, "U"); */
1577 
1578   Rmin = boxp->Rmin;  Rmax = boxp->Rmax;
1579   Gmin = boxp->Gmin;  Gmax = boxp->Gmax;
1580   Bmin = boxp->Bmin;  Bmax = boxp->Bmax;
1581 
1582   if (Rmax > Rmin)
1583     for (R = Rmin; R <= Rmax; R++)
1584       for (G = Gmin; G <= Gmax; G++)
1585         {
1586           for (B = Bmin; B <= Bmax; B++)
1587             {
1588               if (*HIST_LIN (histogram, R, G, B) != 0)
1589                 {
1590                   boxp->Rmin = Rmin = R;
1591                   goto have_Rmin;
1592                 }
1593             }
1594         }
1595  have_Rmin:
1596   if (Rmax > Rmin)
1597     for (R = Rmax; R >= Rmin; R--)
1598       for (G = Gmin; G <= Gmax; G++)
1599         {
1600           for (B = Bmin; B <= Bmax; B++)
1601             {
1602               if (*HIST_LIN (histogram, R, G, B) != 0)
1603                 {
1604                   boxp->Rmax = Rmax = R;
1605                   goto have_Rmax;
1606                 }
1607             }
1608         }
1609  have_Rmax:
1610   if (Gmax > Gmin)
1611     for (G = Gmin; G <= Gmax; G++)
1612       for (R = Rmin; R <= Rmax; R++)
1613         {
1614           for (B = Bmin; B <= Bmax; B++)
1615             {
1616               if (*HIST_LIN (histogram, R, G, B) != 0)
1617                 {
1618                   boxp->Gmin = Gmin = G;
1619                   goto have_Gmin;
1620                 }
1621             }
1622         }
1623  have_Gmin:
1624   if (Gmax > Gmin)
1625     for (G = Gmax; G >= Gmin; G--)
1626       for (R = Rmin; R <= Rmax; R++)
1627         {
1628           for (B = Bmin; B <= Bmax; B++)
1629             {
1630               if (*HIST_LIN (histogram, R, G, B) != 0)
1631                 {
1632                   boxp->Gmax = Gmax = G;
1633                   goto have_Gmax;
1634                 }
1635             }
1636         }
1637  have_Gmax:
1638   if (Bmax > Bmin)
1639     for (B = Bmin; B <= Bmax; B++)
1640       for (R = Rmin; R <= Rmax; R++)
1641         {
1642           for (G = Gmin; G <= Gmax; G++)
1643             {
1644               if (*HIST_LIN (histogram, R, G, B) != 0)
1645                 {
1646                   boxp->Bmin = Bmin = B;
1647                   goto have_Bmin;
1648                 }
1649             }
1650         }
1651  have_Bmin:
1652   if (Bmax > Bmin)
1653     for (B = Bmax; B >= Bmin; B--)
1654       for (R = Rmin; R <= Rmax; R++)
1655         {
1656           for (G = Gmin; G <= Gmax; G++)
1657             {
1658               if (*HIST_LIN (histogram, R, G, B) != 0)
1659                 {
1660                   boxp->Bmax = Bmax = B;
1661                   goto have_Bmax;
1662                 }
1663             }
1664         }
1665  have_Bmax:
1666 
1667   /* Update box volume.
1668    * We use 2-norm rather than real volume here; this biases the method
1669    * against making long narrow boxes, and it has the side benefit that
1670    * a box is splittable iff norm > 0. (ADM: note: this isn't true.)
1671    * Since the differences are expressed in histogram-cell units,
1672    * we have to shift back to JSAMPLE units to get consistent distances;
1673    * after which, we scale according to the selected distance scale factors.
1674    */
1675   dist0 = ((1 + Rmax - Rmin) << R_SHIFT) * R_SCALE;
1676   dist1 = ((1 + Gmax - Gmin) << G_SHIFT) * G_SCALE;
1677   dist2 = ((1 + Bmax - Bmin) << B_SHIFT) * B_SCALE;
1678   boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
1679   /*  boxp->volume = dist0 * dist1 * dist2; */
1680 
1681   compute_color_lin8(&dummyqo, histogram, boxp, 0);
1682 
1683   /*printf("(%d %d %d)\n", dummyqo.cmap[0].red,dummyqo.cmap[0].green,dummyqo.cmap[0].blue);
1684     fflush(stdout);*/
1685 
1686   /* Now scan remaining volume of box and compute population */
1687   ccount = 0;
1688   boxp->error = 0;
1689   boxp->rerror = 0;
1690   boxp->gerror = 0;
1691   boxp->berror = 0;
1692   for (R = Rmin; R <= Rmax; R++)
1693     {
1694       for (G = Gmin; G <= Gmax; G++)
1695         {
1696           for (B = Bmin; B <= Bmax; B++)
1697             {
1698               ColorFreq freq_here;
1699 
1700               freq_here = *HIST_LIN (histogram, R, G, B);
1701 
1702               if (freq_here != 0)
1703                 {
1704                   int ge, be, re;
1705 
1706                   dummybox.Rmin = dummybox.Rmax = R;
1707                   dummybox.Gmin = dummybox.Gmax = G;
1708                   dummybox.Bmin = dummybox.Bmax = B;
1709                   compute_color_lin8(&dummyqo, histogram, &dummybox, 1);
1710 
1711                   re = dummyqo.cmap[0].red   - dummyqo.cmap[1].red;
1712                   ge = dummyqo.cmap[0].green - dummyqo.cmap[1].green;
1713                   be = dummyqo.cmap[0].blue  - dummyqo.cmap[1].blue;
1714 
1715                   boxp->rerror += freq_here * (re) * (re);
1716                   boxp->gerror += freq_here * (ge) * (ge);
1717                   boxp->berror += freq_here * (be) * (be);
1718 
1719                   ccount += freq_here;
1720                 }
1721             }
1722         }
1723     }
1724 
1725 #if 0
1726   fg d;flg fd;kg fld;gflkfld
1727   /* Scan again, taking note of halfway error point for red axis */
1728   tempRerror = 0;
1729   boxp->Rhalferror = Rmin;
1730 #warning r<=?
1731   for (R = Rmin; R <= Rmax; R++)
1732     {
1733       for (G = Gmin; G <= Gmax; G++)
1734         {
1735           for (B = Bmin; B <= Bmax; B++)
1736             {
1737               ColorFreq freq_here;
1738               freq_here = *HIST_LIN(histogram, R, G, B);
1739               if (freq_here != 0)
1740                 {
1741                   int re;
1742                   int idist;
1743                   double dist;
1744 
1745                   dummybox.Rmin = dummybox.Rmax = R;
1746                   dummybox.Gmin = dummybox.Gmax = G;
1747                   dummybox.Bmin = dummybox.Bmax = B;
1748                   compute_color_lin8(&dummyqo, histogram, &dummybox, 1);
1749 
1750                   re = dummyqo.cmap[0].red   - dummyqo.cmap[1].red;
1751 
1752                   tempRerror += freq_here * (re) * (re);
1753 
1754                   if (tempRerror*2 >= boxp->rerror)
1755                     goto green_axisscan;
1756                   else
1757                     boxp->Rhalferror = R;
1758                 }
1759             }
1760         }
1761     }
1762   fprintf(stderr, " D:");
1763  green_axisscan:
1764 
1765   fprintf(stderr, "<%d: %llu/%llu> ", R, tempRerror, boxp->rerror);
1766   /* Scan again, taking note of halfway error point for green axis */
1767   tempGerror = 0;
1768   boxp->Ghalferror = Gmin;
1769 #warning G<=?
1770   for (G = Gmin; G <= Gmax; G++)
1771     {
1772       for (R = Rmin; R <= Rmax; R++)
1773         {
1774           for (B = Bmin; B <= Bmax; B++)
1775             {
1776               ColorFreq freq_here;
1777               freq_here = *HIST_LIN(histogram, R, G, B);
1778               if (freq_here != 0)
1779                 {
1780                   int ge;
1781                   dummybox.Rmin = dummybox.Rmax = R;
1782                   dummybox.Gmin = dummybox.Gmax = G;
1783                   dummybox.Bmin = dummybox.Bmax = B;
1784                   compute_color_lin8(&dummyqo, histogram, &dummybox, 1);
1785 
1786                   ge = dummyqo.cmap[0].green - dummyqo.cmap[1].green;
1787 
1788                   tempGerror += freq_here * (ge) * (ge);
1789 
1790                   if (tempGerror*2 >= boxp->gerror)
1791                     goto blue_axisscan;
1792                   else
1793                     boxp->Ghalferror = G;
1794                 }
1795             }
1796         }
1797     }
1798 
1799  blue_axisscan:
1800   /* Scan again, taking note of halfway error point for blue axis */
1801   tempBerror = 0;
1802   boxp->Bhalferror = Bmin;
1803 #warning B<=?
1804   for (B = Bmin; B <= Bmax; B++)
1805     {
1806       for (R = Rmin; R <= Rmax; R++)
1807         {
1808           for (G = Gmin; G <= Gmax; G++)
1809             {
1810               ColorFreq freq_here;
1811               freq_here = *HIST_LIN(histogram, R, G, B);
1812               if (freq_here != 0)
1813                 {
1814                   int be;
1815                   dummybox.Rmin = dummybox.Rmax = R;
1816                   dummybox.Gmin = dummybox.Gmax = G;
1817                   dummybox.Bmin = dummybox.Bmax = B;
1818                   compute_color_lin8(&dummyqo, histogram, &dummybox, 1);
1819 
1820                   be = dummyqo.cmap[0].blue  - dummyqo.cmap[1].blue;
1821 
1822                   tempBerror += freq_here * (be) * (be);
1823 
1824                   if (tempBerror*2 >= boxp->berror)
1825                     goto finished_axesscan;
1826                   else
1827                     boxp->Bhalferror = B;
1828                 }
1829             }
1830         }
1831     }
1832  finished_axesscan:
1833 #else
1834 
1835   boxp->Rhalferror = Rmin + (Rmax - Rmin + 1) / 2;
1836   boxp->Ghalferror = Gmin + (Gmax - Gmin + 1) / 2;
1837   boxp->Bhalferror = Bmin + (Bmax - Bmin + 1) / 2;
1838 
1839   if (dist0 && dist1 && dist2)
1840     {
1841       AxisType longest_ax      = AXIS_UNDEF;
1842       gint     longest_length  = 0;
1843       gint     longest_length2 = 0;
1844       gint     ratio;
1845 
1846       /*
1847         fprintf(stderr, "[%d,%d,%d=%d,%d,%d] ",
1848         (Rmax - Rmin), (Gmax - Gmin), (Bmax - Bmin),
1849         dist0, dist1, dist2);
1850       */
1851 
1852       if (dist0 >= longest_length)
1853         {
1854           longest_length2 = longest_length;
1855           longest_length = dist0;
1856           longest_ax = AXIS_RED;
1857         }
1858       else if (dist0 >= longest_length2)
1859         {
1860           longest_length2 = dist0;
1861         }
1862 
1863       if (dist1 >= longest_length)
1864         {
1865           longest_length2 = longest_length;
1866           longest_length = dist1;
1867           longest_ax = AXIS_GREEN;
1868         }
1869       else if (dist1 >= longest_length2)
1870         {
1871           longest_length2 = dist1;
1872         }
1873 
1874       if (dist2 >= longest_length)
1875         {
1876           longest_length2 = longest_length;
1877           longest_length = dist2;
1878           longest_ax = AXIS_BLUE;
1879         }
1880       else if (dist2 >= longest_length2)
1881         {
1882           longest_length2 = dist2;
1883         }
1884 
1885       if (longest_length2 == 0)
1886         longest_length2 = 1;
1887 
1888       ratio = (longest_length + longest_length2/2) / longest_length2;
1889       /* fprintf(stderr, " ratio:(%d/%d)=%d ", longest_length, longest_length2, ratio);
1890          fprintf(stderr, "C%d ", cells_remaining); */
1891 
1892       if (ratio > cells_remaining + 1)
1893         ratio = cells_remaining + 1;
1894 
1895       if (ratio > 2)
1896         {
1897           switch (longest_ax)
1898             {
1899             case AXIS_RED:
1900               if (Rmin + (Rmax - Rmin + ratio / 2) / ratio < Rmax)
1901                 {
1902                   /* fprintf(stderr, "FR%d \007\n",ratio);*/
1903                   boxp->Rhalferror = Rmin +  (Rmax - Rmin + ratio / 2) / ratio;
1904                 }
1905               break;
1906             case AXIS_GREEN:
1907               if (Gmin + (Gmax - Gmin + ratio / 2) / ratio < Gmax)
1908                 {
1909                   /* fprintf(stderr, "FG%d \007\n",ratio);*/
1910                   boxp->Ghalferror = Gmin + (Gmax - Gmin + ratio / 2) / ratio;
1911                 }
1912               break;
1913             case AXIS_BLUE:
1914               if (Bmin + (Bmax - Bmin + ratio / 2) / ratio < Bmax)
1915                 {
1916                   /* fprintf(stderr, "FB%d \007\n",ratio);*/
1917                   boxp->Bhalferror = Bmin + (Bmax - Bmin + ratio / 2) / ratio;
1918                 }
1919               break;
1920             default:
1921               g_warning ("GRR, UNDEF LONGEST AXIS\007\n");
1922             }
1923         }
1924     }
1925 
1926   if (boxp->Rhalferror == Rmax)
1927     boxp->Rhalferror = Rmin;
1928   if (boxp->Ghalferror == Gmax)
1929     boxp->Ghalferror = Gmin;
1930   if (boxp->Bhalferror == Bmax)
1931     boxp->Bhalferror = Bmin;
1932 
1933   /*
1934   boxp->Rhalferror = RSDF(dummyqo.cmap[0].red);
1935   boxp->Ghalferror = GSDF(dummyqo.cmap[0].green);
1936   boxp->Bhalferror = BSDF(dummyqo.cmap[0].blue);
1937   */
1938 
1939   /*
1940   boxp->Rhalferror = (RSDF(dummyqo.cmap[0].red) + (Rmin+Rmax)/2)/2;
1941   boxp->Ghalferror = (GSDF(dummyqo.cmap[0].green) + (Gmin+Gmax)/2)/2;
1942   boxp->Bhalferror = (BSDF(dummyqo.cmap[0].blue) + (Bmin+Bmax)/2)/2;
1943   */
1944 
1945 
1946 #endif
1947   /*
1948   fprintf(stderr, " %d,%d", dummyqo.cmap[0].blue, boxp->Bmax);
1949 
1950   gimp_assert (boxp->Rhalferror >= boxp->Rmin);
1951   gimp_assert (boxp->Rhalferror < boxp->Rmax);
1952   gimp_assert (boxp->Ghalferror >= boxp->Gmin);
1953   gimp_assert (boxp->Ghalferror < boxp->Gmax);
1954   gimp_assert (boxp->Bhalferror >= boxp->Bmin);
1955   gimp_assert (boxp->Bhalferror < boxp->Bmax);*/
1956 
1957   /*boxp->error = (sqrt((double)(boxp->error/ccount)));*/
1958   /*  boxp->rerror = (sqrt((double)((boxp->rerror)/ccount)));
1959   boxp->gerror = (sqrt((double)((boxp->gerror)/ccount)));
1960   boxp->berror = (sqrt((double)((boxp->berror)/ccount)));*/
1961   /*printf(":%lld / %ld: ", boxp->error, ccount);
1962   printf("(%d-%d-%d)(%d-%d-%d)(%d-%d-%d)\n",
1963          Rmin, boxp->Rhalferror, Rmax,
1964          Gmin, boxp->Ghalferror, Gmax,
1965          Bmin, boxp->Bhalferror, Bmax
1966          );
1967          fflush(stdout);*/
1968 
1969   boxp->colorcount = ccount;
1970 }
1971 
1972 
1973 /* Repeatedly select and split the largest box until we have enough
1974  * boxes
1975  */
1976 static gint
median_cut_gray(CFHistogram histogram,boxptr boxlist,gint numboxes,gint desired_colors)1977 median_cut_gray (CFHistogram histogram,
1978                  boxptr      boxlist,
1979                  gint        numboxes,
1980                  gint        desired_colors)
1981 {
1982   gint   lb;
1983   boxptr b1, b2;
1984 
1985   while (numboxes < desired_colors)
1986     {
1987       /* Select box to split.
1988        * Current algorithm: by population for first half, then by volume.
1989        */
1990 
1991       b1 = find_biggest_volume (boxlist, numboxes);
1992 
1993       if (b1 == NULL)           /* no splittable boxes left! */
1994         break;
1995 
1996       b2 = boxlist + numboxes;  /* where new box will go */
1997       /* Copy the color bounds to the new box. */
1998       b2->Rmax = b1->Rmax;
1999       b2->Rmin = b1->Rmin;
2000 
2001       /* Current algorithm: split at halfway point.
2002        * (Since the box has been shrunk to minimum volume,
2003        * any split will produce two nonempty subboxes.)
2004        * Note that lb value is max for lower box, so must be < old max.
2005        */
2006       lb = (b1->Rmax + b1->Rmin) / 2;
2007       b1->Rmax = lb;
2008       b2->Rmin = lb + 1;
2009 
2010       /* Update stats for boxes */
2011       update_box_gray (histogram, b1);
2012       update_box_gray (histogram, b2);
2013       numboxes++;
2014     }
2015 
2016   return numboxes;
2017 }
2018 
2019 /* Repeatedly select and split the largest box until we have enough
2020  * boxes
2021  */
2022 static gint
median_cut_rgb(CFHistogram histogram,boxptr boxlist,gint numboxes,gint desired_colors,GimpProgress * progress)2023 median_cut_rgb (CFHistogram   histogram,
2024                 boxptr        boxlist,
2025                 gint          numboxes,
2026                 gint          desired_colors,
2027                 GimpProgress *progress)
2028 {
2029   gint     lb;
2030   boxptr   b1, b2;
2031   AxisType which_axis;
2032 
2033   while (numboxes < desired_colors)
2034     {
2035       b1 = find_split_candidate (boxlist, numboxes, &which_axis, desired_colors);
2036 
2037       if (b1 == NULL)           /* no splittable boxes left! */
2038         break;
2039 
2040       b2 = boxlist + numboxes;  /* where new box will go */
2041       /* Copy the color bounds to the new box. */
2042       b2->Rmax = b1->Rmax; b2->Gmax = b1->Gmax; b2->Bmax = b1->Bmax;
2043       b2->Rmin = b1->Rmin; b2->Gmin = b1->Gmin; b2->Bmin = b1->Bmin;
2044 
2045 
2046       /* Choose split point along selected axis, and update box bounds.
2047        * Note that lb value is max for lower box, so must be < old max.
2048        */
2049       switch (which_axis)
2050         {
2051         case AXIS_RED:
2052           lb = b1->Rhalferror;/* *0 + (b1->Rmax + b1->Rmin) / 2; */
2053           b1->Rmax = lb;
2054           b2->Rmin = lb+1;
2055           g_return_val_if_fail (b1->Rmax >= b1->Rmin, numboxes);
2056           g_return_val_if_fail (b2->Rmax >= b2->Rmin, numboxes);
2057           break;
2058         case AXIS_GREEN:
2059           lb = b1->Ghalferror;/* *0 + (b1->Gmax + b1->Gmin) / 2; */
2060           b1->Gmax = lb;
2061           b2->Gmin = lb+1;
2062           g_return_val_if_fail (b1->Gmax >= b1->Gmin, numboxes);
2063           g_return_val_if_fail (b2->Gmax >= b2->Gmin, numboxes);
2064           break;
2065         case AXIS_BLUE:
2066           lb = b1->Bhalferror;/* *0 + (b1->Bmax + b1->Bmin) / 2; */
2067           b1->Bmax = lb;
2068           b2->Bmin = lb+1;
2069           g_return_val_if_fail (b1->Bmax >= b1->Bmin, numboxes);
2070           g_return_val_if_fail (b2->Bmax >= b2->Bmin, numboxes);
2071           break;
2072         default:
2073           g_error ("Uh-oh.");
2074         }
2075       /* Update stats for boxes */
2076       numboxes++;
2077 
2078       if (progress && (numboxes % 16 == 0))
2079         gimp_progress_set_value (progress, (gdouble) numboxes / desired_colors);
2080 
2081       update_box_rgb (histogram, b1, desired_colors - numboxes);
2082       update_box_rgb (histogram, b2, desired_colors - numboxes);
2083     }
2084 
2085   return numboxes;
2086 }
2087 
2088 
2089 /* Compute representative color for a box, put it in colormap[icolor]
2090  */
2091 static void
compute_color_gray(QuantizeObj * quantobj,CFHistogram histogram,boxptr boxp,int icolor)2092 compute_color_gray (QuantizeObj *quantobj,
2093                     CFHistogram  histogram,
2094                     boxptr       boxp,
2095                     int          icolor)
2096 {
2097   gint    i, min, max;
2098   guint64 count;
2099   guint64 total;
2100   guint64 gtotal;
2101 
2102   min = boxp->Rmin;
2103   max = boxp->Rmax;
2104 
2105   total = 0;
2106   gtotal = 0;
2107 
2108   for (i = min; i <= max; i++)
2109     {
2110       count = histogram[i];
2111       if (count != 0)
2112         {
2113           total += count;
2114           gtotal += i * count;
2115         }
2116     }
2117 
2118   if (total != 0)
2119     {
2120       quantobj->cmap[icolor].red   =
2121       quantobj->cmap[icolor].green =
2122       quantobj->cmap[icolor].blue  = (gtotal + (total >> 1)) / total;
2123     }
2124   else
2125     {
2126       /* The only situation where total==0 is if the image was null or
2127        *  all-transparent.  In that case we just put a dummy value in
2128        *  the colormap.
2129        */
2130       quantobj->cmap[icolor].red   =
2131       quantobj->cmap[icolor].green =
2132       quantobj->cmap[icolor].blue  = 0;
2133     }
2134 }
2135 
2136 
2137 /* Compute representative color for a box, put it in colormap[icolor]
2138  */
2139 static void
compute_color_rgb(QuantizeObj * quantobj,CFHistogram histogram,boxptr boxp,int icolor)2140 compute_color_rgb (QuantizeObj *quantobj,
2141                    CFHistogram  histogram,
2142                    boxptr       boxp,
2143                    int          icolor)
2144 {
2145   /* Current algorithm: mean weighted by pixels (not colors) */
2146   /* Note it is important to get the rounding correct! */
2147   gint      R, G, B;
2148   gint      Rmin, Rmax;
2149   gint      Gmin, Gmax;
2150   gint      Bmin, Bmax;
2151   ColorFreq total  = 0;
2152   ColorFreq Rtotal = 0;
2153   ColorFreq Gtotal = 0;
2154   ColorFreq Btotal = 0;
2155 
2156   Rmin = boxp->Rmin;  Rmax = boxp->Rmax;
2157   Gmin = boxp->Gmin;  Gmax = boxp->Gmax;
2158   Bmin = boxp->Bmin;  Bmax = boxp->Bmax;
2159 
2160   for (R = Rmin; R <= Rmax; R++)
2161     for (G = Gmin; G <= Gmax; G++)
2162       {
2163         for (B = Bmin; B <= Bmax; B++)
2164           {
2165             ColorFreq this_freq = *HIST_LIN (histogram, R, G, B);
2166 
2167             if (this_freq != 0)
2168               {
2169                 total += this_freq;
2170                 Rtotal += R * this_freq;
2171                 Gtotal += G * this_freq;
2172                 Btotal += B * this_freq;
2173               }
2174           }
2175       }
2176 
2177   if (total > 0)
2178     {
2179       guchar red, green, blue;
2180 
2181       lin_to_rgb (/*(Rtotal + (total>>1)) / total,
2182                     (Gtotal + (total>>1)) / total,
2183                     (Btotal + (total>>1)) / total,*/
2184                   (double)Rtotal / (double)total,
2185                   (double)Gtotal / (double)total,
2186                   (double)Btotal / (double)total,
2187                   &red, &green, &blue);
2188 
2189       quantobj->cmap[icolor].red   = red;
2190       quantobj->cmap[icolor].green = green;
2191       quantobj->cmap[icolor].blue  = blue;
2192     }
2193   else
2194     {
2195       /* The only situation where total==0 is if the image was null or
2196        *  all-transparent.  In that case we just put a dummy value in
2197        *  the colormap.
2198        */
2199       quantobj->cmap[icolor].red   = 0;
2200       quantobj->cmap[icolor].green = 0;
2201       quantobj->cmap[icolor].blue  = 0;
2202     }
2203 }
2204 
2205 
2206 /* Compute representative color for a box, put it in colormap[icolor]
2207  */
2208 static void
compute_color_lin8(QuantizeObj * quantobj,CFHistogram histogram,boxptr boxp,const gint icolor)2209 compute_color_lin8 (QuantizeObj *quantobj,
2210                     CFHistogram  histogram,
2211                     boxptr       boxp,
2212                     const gint   icolor)
2213 {
2214   /* Current algorithm: mean weighted by pixels (not colors) */
2215   /* Note it is important to get the rounding correct! */
2216   gint      R, G, B;
2217   gint      Rmin, Rmax;
2218   gint      Gmin, Gmax;
2219   gint      Bmin, Bmax;
2220   ColorFreq total  = 0;
2221   ColorFreq Rtotal = 0;
2222   ColorFreq Gtotal = 0;
2223   ColorFreq Btotal = 0;
2224 
2225   Rmin = boxp->Rmin;  Rmax = boxp->Rmax;
2226   Gmin = boxp->Gmin;  Gmax = boxp->Gmax;
2227   Bmin = boxp->Bmin;  Bmax = boxp->Bmax;
2228 
2229   for (R = Rmin; R <= Rmax; R++)
2230     for (G = Gmin; G <= Gmax; G++)
2231       {
2232         for (B = Bmin; B <= Bmax; B++)
2233           {
2234             ColorFreq this_freq = *HIST_LIN (histogram, R, G, B);
2235 
2236             if (this_freq != 0)
2237               {
2238                 Rtotal += R * this_freq;
2239                 Gtotal += G * this_freq;
2240                 Btotal += B * this_freq;
2241                 total += this_freq;
2242               }
2243           }
2244       }
2245 
2246   if (total != 0)
2247     {
2248       quantobj->cmap[icolor].red   = ((Rtotal << R_SHIFT) + (total>>1)) / total;
2249       quantobj->cmap[icolor].green = ((Gtotal << G_SHIFT) + (total>>1)) / total;
2250       quantobj->cmap[icolor].blue  = ((Btotal << B_SHIFT) + (total>>1)) / total;
2251     }
2252   else
2253     {
2254       /* The only situation where total==0 is if the image was null or
2255        *  all-transparent.  In that case we just put a dummy value in
2256        *  the colormap.
2257        */
2258       g_warning ("eep.");
2259       quantobj->cmap[icolor].red   = 0;
2260       quantobj->cmap[icolor].green = 128;
2261       quantobj->cmap[icolor].blue  = 128;
2262     }
2263 }
2264 
2265 
2266 /* Master routine for color selection
2267  */
2268 static void
select_colors_gray(QuantizeObj * quantobj,CFHistogram histogram)2269 select_colors_gray (QuantizeObj *quantobj,
2270                     CFHistogram  histogram)
2271 {
2272   boxptr boxlist;
2273   gint   numboxes;
2274   gint   desired = quantobj->desired_number_of_colors;
2275   gint   i;
2276 
2277   /* Allocate workspace for box list */
2278   boxlist = g_new (box, desired);
2279 
2280   /* Initialize one box containing whole space */
2281   numboxes = 1;
2282   boxlist[0].Rmin = 0;
2283   boxlist[0].Rmax = 255;
2284   /* Shrink it to actually-used volume and set its statistics */
2285   update_box_gray (histogram, boxlist);
2286   /* Perform median-cut to produce final box list */
2287   numboxes = median_cut_gray (histogram, boxlist, numboxes, desired);
2288 
2289   quantobj->actual_number_of_colors = numboxes;
2290   /* Compute the representative color for each box, fill colormap */
2291   for (i = 0; i < numboxes; i++)
2292     compute_color_gray (quantobj, histogram, boxlist + i, i);
2293 }
2294 
2295 
2296 /* Master routine for color selection
2297  */
2298 static void
select_colors_rgb(QuantizeObj * quantobj,CFHistogram histogram)2299 select_colors_rgb (QuantizeObj *quantobj,
2300                    CFHistogram  histogram)
2301 {
2302   boxptr boxlist;
2303   gint   numboxes;
2304   gint   desired = quantobj->desired_number_of_colors;
2305   gint  i;
2306 
2307   /* Allocate workspace for box list */
2308   boxlist = g_new (box, desired);
2309 
2310   /* Initialize one box containing whole space */
2311   numboxes = 1;
2312   boxlist[0].Rmin = 0;
2313   boxlist[0].Rmax = HIST_R_ELEMS - 1;
2314   boxlist[0].Gmin = 0;
2315   boxlist[0].Gmax = HIST_G_ELEMS - 1;
2316   boxlist[0].Bmin = 0;
2317   boxlist[0].Bmax = HIST_B_ELEMS - 1;
2318   /* Shrink it to actually-used volume and set its statistics */
2319   update_box_rgb (histogram, &boxlist[0], quantobj->desired_number_of_colors);
2320   /* Perform median-cut to produce final box list */
2321   numboxes = median_cut_rgb (histogram, boxlist, numboxes, desired,
2322                              quantobj->progress);
2323 
2324   quantobj->actual_number_of_colors = numboxes;
2325   /* Compute the representative color for each box, fill colormap */
2326   for (i = 0; i < numboxes; i++)
2327     {
2328       compute_color_rgb (quantobj, histogram, &boxlist[i], i);
2329     }
2330 
2331   g_free (boxlist);
2332 }
2333 
2334 
2335 /*
2336  * These routines are concerned with the time-critical task of mapping input
2337  * colors to the nearest color in the selected colormap.
2338  *
2339  * We re-use the histogram space as an "inverse color map", essentially a
2340  * cache for the results of nearest-color searches.  All colors within a
2341  * histogram cell will be mapped to the same colormap entry, namely the one
2342  * closest to the cell's center.  This may not be quite the closest entry to
2343  * the actual input color, but it's almost as good.  A zero in the cache
2344  * indicates we haven't found the nearest color for that cell yet; the array
2345  * is cleared to zeroes before starting the mapping pass.  When we find the
2346  * nearest color for a cell, its colormap index plus one is recorded in the
2347  * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
2348  * when they need to use an unfilled entry in the cache.
2349  *
2350  * Our method of efficiently finding nearest colors is based on the "locally
2351  * sorted search" idea described by Heckbert and on the incremental distance
2352  * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
2353  * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
2354  * the distances from a given colormap entry to each cell of the histogram can
2355  * be computed quickly using an incremental method: the differences between
2356  * distances to adjacent cells themselves differ by a constant.  This allows a
2357  * fairly fast implementation of the "brute force" approach of computing the
2358  * distance from every colormap entry to every histogram cell.  Unfortunately,
2359  * it needs a work array to hold the best-distance-so-far for each histogram
2360  * cell (because the inner loop has to be over cells, not colormap entries).
2361  * The work array elements have to be ints, so the work array would need
2362  * 256Kb at our recommended precision.  This is not feasible in DOS machines.
2363  *
2364  * To get around these problems, we apply Thomas' method to compute the
2365  * nearest colors for only the cells within a small subbox of the histogram.
2366  * The work array need be only as big as the subbox, so the memory usage
2367  * problem is solved.  Furthermore, we need not fill subboxes that are never
2368  * referenced in pass2; many images use only part of the color gamut, so a
2369  * fair amount of work is saved.  An additional advantage of this
2370  * approach is that we can apply Heckbert's locality criterion to quickly
2371  * eliminate colormap entries that are far away from the subbox; typically
2372  * three-fourths of the colormap entries are rejected by Heckbert's criterion,
2373  * and we need not compute their distances to individual cells in the subbox.
2374  * The speed of this approach is heavily influenced by the subbox size: too
2375  * small means too much overhead, too big loses because Heckbert's criterion
2376  * can't eliminate as many colormap entries.  Empirically the best subbox
2377  * size seems to be about 1/512th of the histogram (1/8th in each direction).
2378  *
2379  * Thomas' article also describes a refined method which is asymptotically
2380  * faster than the brute-force method, but it is also far more complex and
2381  * cannot efficiently be applied to small subboxes.  It is therefore not
2382  * useful for programs intended to be portable to DOS machines.  On machines
2383  * with plenty of memory, filling the whole histogram in one shot with Thomas'
2384  * refined method might be faster than the present code --- but then again,
2385  * it might not be any faster, and it's certainly more complicated.
2386  */
2387 
2388 
2389 /* log2(histogram cells in update box) for each axis; this can be adjusted */
2390 /*#define BOX_R_LOG  (PRECISION_R-3)
2391   #define BOX_G_LOG  (PRECISION_G-3)
2392   #define BOX_B_LOG  (PRECISION_B-3)*/
2393 
2394 /*adam*/
2395 #define BOX_R_LOG 0
2396 #define BOX_G_LOG 0
2397 #define BOX_B_LOG 0
2398 
2399 #define BOX_R_ELEMS  (1<<BOX_R_LOG) /* # of hist cells in update box */
2400 #define BOX_G_ELEMS  (1<<BOX_G_LOG)
2401 #define BOX_B_ELEMS  (1<<BOX_B_LOG)
2402 
2403 #define BOX_R_SHIFT  (R_SHIFT + BOX_R_LOG)
2404 #define BOX_G_SHIFT  (G_SHIFT + BOX_G_LOG)
2405 #define BOX_B_SHIFT  (B_SHIFT + BOX_B_LOG)
2406 
2407 
2408 /*
2409  * The next three routines implement inverse colormap filling.  They
2410  * could all be folded into one big routine, but splitting them up
2411  * this way saves some stack space (the mindist[] and bestdist[]
2412  * arrays need not coexist) and may allow some compilers to produce
2413  * better code by registerizing more inner-loop variables.
2414  */
2415 
2416 /* Locate the colormap entries close enough to an update box to be
2417  * candidates for the nearest entry to some cell(s) in the update box.
2418  * The update box is specified by the center coordinates of its first
2419  * cell.  The number of candidate colormap entries is returned, and
2420  * their colormap indexes are placed in colorlist[].
2421  *
2422  * This routine uses Heckbert's "locally sorted search" criterion to
2423  * select the colors that need further consideration.
2424  */
2425 static gint
find_nearby_colors(QuantizeObj * quantobj,int minR,int minG,int minB,int colorlist[])2426 find_nearby_colors (QuantizeObj *quantobj,
2427                     int          minR,
2428                     int          minG,
2429                     int          minB,
2430                     int          colorlist[])
2431 {
2432   int numcolors = quantobj->actual_number_of_colors;
2433   int maxR, maxG, maxB;
2434   int centerR, centerG, centerB;
2435   int i, x, ncolors;
2436   int minmaxdist, min_dist, max_dist, tdist;
2437   int mindist[MAXNUMCOLORS];    /* min distance to colormap entry i */
2438 
2439   /* Compute true coordinates of update box's upper corner and center.
2440    * Actually we compute the coordinates of the center of the upper-corner
2441    * histogram cell, which are the upper bounds of the volume we care about.
2442    * Note that since ">>" rounds down, the "center" values may be closer to
2443    * min than to max; hence comparisons to them must be "<=", not "<".
2444    */
2445   maxR = minR + ((1 << BOX_R_SHIFT) - (1 << R_SHIFT));
2446   centerR = (minR + maxR + 1) >> 1;
2447   maxG = minG + ((1 << BOX_G_SHIFT) - (1 << G_SHIFT));
2448   centerG = (minG + maxG + 1) >> 1;
2449   maxB = minB + ((1 << BOX_B_SHIFT) - (1 << B_SHIFT));
2450   centerB = (minB + maxB + 1) >> 1;
2451 
2452   /* For each color in colormap, find:
2453    *  1. its minimum squared-distance to any point in the update box
2454    *     (zero if color is within update box);
2455    *  2. its maximum squared-distance to any point in the update box.
2456    * Both of these can be found by considering only the corners of the box.
2457    * We save the minimum distance for each color in mindist[];
2458    * only the smallest maximum distance is of interest.
2459    */
2460   minmaxdist = 0x7FFFFFFFL;
2461 
2462   for (i = 0; i < numcolors; i++)
2463     {
2464       /* We compute the squared-R-distance term, then add in the other two. */
2465       x = quantobj->clin[i].red;
2466       if (x < minR)
2467         {
2468           tdist = (x - minR) * R_SCALE;
2469           min_dist = tdist*tdist;
2470           tdist = (x - maxR) * R_SCALE;
2471           max_dist = tdist*tdist;
2472         }
2473       else if (x > maxR)
2474         {
2475           tdist = (x - maxR) * R_SCALE;
2476           min_dist = tdist*tdist;
2477           tdist = (x - minR) * R_SCALE;
2478           max_dist = tdist*tdist;
2479         }
2480       else
2481         {
2482           /* within cell range so no contribution to min_dist */
2483           min_dist = 0;
2484           if (x <= centerR)
2485             {
2486               tdist = (x - maxR) * R_SCALE;
2487               max_dist = tdist*tdist;
2488             }
2489           else
2490             {
2491               tdist = (x - minR) * R_SCALE;
2492               max_dist = tdist*tdist;
2493             }
2494         }
2495 
2496       x = quantobj->clin[i].green;
2497       if (x < minG)
2498         {
2499           tdist = (x - minG) * G_SCALE;
2500           min_dist += tdist*tdist;
2501           tdist = (x - maxG) * G_SCALE;
2502           max_dist += tdist*tdist;
2503         }
2504       else if (x > maxG)
2505         {
2506           tdist = (x - maxG) * G_SCALE;
2507           min_dist += tdist*tdist;
2508           tdist = (x - minG) * G_SCALE;
2509           max_dist += tdist*tdist;
2510         }
2511       else
2512         {
2513           /* within cell range so no contribution to min_dist */
2514           if (x <= centerG)
2515             {
2516               tdist = (x - maxG) * G_SCALE;
2517               max_dist += tdist*tdist;
2518             }
2519           else
2520             {
2521               tdist = (x - minG) * G_SCALE;
2522               max_dist += tdist*tdist;
2523             }
2524         }
2525 
2526       x = quantobj->clin[i].blue;
2527       if (x < minB)
2528         {
2529           tdist = (x - minB) * B_SCALE;
2530           min_dist += tdist*tdist;
2531           tdist = (x - maxB) * B_SCALE;
2532           max_dist += tdist*tdist;
2533         }
2534       else if (x > maxB)
2535         {
2536           tdist = (x - maxB) * B_SCALE;
2537           min_dist += tdist*tdist;
2538           tdist = (x - minB) * B_SCALE;
2539           max_dist += tdist*tdist;
2540         }
2541       else
2542         {
2543           /* within cell range so no contribution to min_dist */
2544           if (x <= centerB)
2545             {
2546               tdist = (x - maxB) * B_SCALE;
2547               max_dist += tdist*tdist;
2548             }
2549           else
2550             {
2551               tdist = (x - minB) * B_SCALE;
2552               max_dist += tdist*tdist;
2553             }
2554         }
2555 
2556       mindist[i] = min_dist;      /* save away the results */
2557       if (max_dist < minmaxdist)
2558         minmaxdist = max_dist;
2559     }
2560 
2561   /* Now we know that no cell in the update box is more than minmaxdist
2562    * away from some colormap entry.  Therefore, only colors that are
2563    * within minmaxdist of some part of the box need be considered.
2564    */
2565   ncolors = 0;
2566   for (i = 0; i < numcolors; i++)
2567     {
2568       if (mindist[i] <= minmaxdist)
2569         colorlist[ncolors++] = i;
2570     }
2571 
2572   return ncolors;
2573 }
2574 
2575 
2576 /* Find the closest colormap entry for each cell in the update box,
2577  * given the list of candidate colors prepared by find_nearby_colors.
2578  * Return the indexes of the closest entries in the bestcolor[] array.
2579  * This routine uses Thomas' incremental distance calculation method
2580  * to find the distance from a colormap entry to successive cells in
2581  * the box.
2582  */
2583 static void
find_best_colors(QuantizeObj * quantobj,gint minR,gint minG,gint minB,gint numcolors,gint colorlist[],gint bestcolor[])2584 find_best_colors (QuantizeObj *quantobj,
2585                   gint         minR,
2586                   gint         minG,
2587                   gint         minB,
2588                   gint         numcolors,
2589                   gint         colorlist[],
2590                   gint         bestcolor[])
2591 {
2592   gint  iR, iG, iB;
2593   gint  i, icolor;
2594   gint *bptr;           /* pointer into bestdist[] array */
2595   gint *cptr;           /* pointer into bestcolor[] array */
2596   gint  dist0, dist1;     /* initial distance values */
2597   gint  dist2;            /* current distance in inner loop */
2598   gint  xx0, xx1;         /* distance increments */
2599   gint  xx2;
2600   gint  inR, inG, inB;    /* initial values for increments */
2601 
2602   /* This array holds the distance to the nearest-so-far color for each cell */
2603   gint  bestdist[BOX_R_ELEMS * BOX_G_ELEMS * BOX_B_ELEMS] = { 0, };
2604 
2605   /* Initialize best-distance for each cell of the update box */
2606   bptr = bestdist;
2607   for (i = BOX_R_ELEMS*BOX_G_ELEMS*BOX_B_ELEMS-1; i >= 0; i--)
2608     *bptr++ = 0x7FFFFFFFL;
2609 
2610   /* For each color selected by find_nearby_colors,
2611    * compute its distance to the center of each cell in the box.
2612    * If that's less than best-so-far, update best distance and color number.
2613    */
2614 
2615   /* Nominal steps between cell centers ("x" in Thomas article) */
2616 #define STEP_R  ((1 << R_SHIFT) * R_SCALE)
2617 #define STEP_G  ((1 << G_SHIFT) * G_SCALE)
2618 #define STEP_B  ((1 << B_SHIFT) * B_SCALE)
2619 
2620   for (i = 0; i < numcolors; i++)
2621     {
2622       icolor = colorlist[i];
2623       /* Compute (square of) distance from minR/G/B to this color */
2624       inR = (minR - quantobj->clin[icolor].red) * R_SCALE;
2625       dist0 = inR*inR;
2626       /* special-case for L*==0: chroma diffs irrelevant */
2627       /*    if (minR > 0 || quantobj->clin[icolor].red > 0) */
2628       {
2629         inG = (minG - quantobj->clin[icolor].green) * G_SCALE;
2630         dist0 += inG*inG;
2631         inB = (minB - quantobj->clin[icolor].blue) * B_SCALE;
2632         dist0 += inB*inB;
2633       }
2634       /*    else
2635             {
2636             inG = 0;
2637             inB = 0;
2638             } */
2639       /* Form the initial difference increments */
2640       inR = inR * (2 * STEP_R) + STEP_R * STEP_R;
2641       inG = inG * (2 * STEP_G) + STEP_G * STEP_G;
2642       inB = inB * (2 * STEP_B) + STEP_B * STEP_B;
2643       /* Now loop over all cells in box, updating distance per Thomas method */
2644       bptr = bestdist;
2645       cptr = bestcolor;
2646       xx0 = inR;
2647       for (iR = BOX_R_ELEMS-1; iR >= 0; iR--)
2648         {
2649           dist1 = dist0;
2650           xx1 = inG;
2651           for (iG = BOX_G_ELEMS-1; iG >= 0; iG--)
2652             {
2653               dist2 = dist1;
2654               xx2 = inB;
2655               for (iB = BOX_B_ELEMS-1; iB >= 0; iB--)
2656                 {
2657                   if (dist2 < *bptr)
2658                     {
2659                       *bptr = dist2;
2660                       *cptr = icolor;
2661                     }
2662                   dist2 += xx2;
2663                   xx2 += 2 * STEP_B * STEP_B;
2664                   bptr++;
2665                   cptr++;
2666                 }
2667               dist1 += xx1;
2668               xx1 += 2 * STEP_G * STEP_G;
2669             }
2670           dist0 += xx0;
2671           xx0 += 2 * STEP_R * STEP_R;
2672         }
2673     }
2674 }
2675 
2676 
2677 /* Fill the inverse-colormap entries in the update box that contains
2678  * histogram cell R/G/B.  (Only that one cell MUST be filled, but we
2679  * can fill as many others as we wish.)
2680  */
2681 static void
fill_inverse_cmap_gray(QuantizeObj * quantobj,CFHistogram histogram,gint pixel)2682 fill_inverse_cmap_gray (QuantizeObj *quantobj,
2683                         CFHistogram  histogram,
2684                         gint         pixel)
2685 {
2686   Color *cmap = quantobj->cmap;
2687   gint64 mindist;
2688   gint   mindisti;
2689   gint   i;
2690 
2691   g_return_if_fail (quantobj->actual_number_of_colors > 0);
2692 
2693   mindist  = G_MAXLONG;
2694   mindisti = -1;
2695 
2696   for (i = 0; i < quantobj->actual_number_of_colors; i++)
2697     {
2698       gint64 dist = ABS (pixel - cmap[i].red);
2699 
2700       if (dist < mindist)
2701         {
2702           mindist  = dist;
2703           mindisti = i;
2704 
2705           if (mindist == 0)
2706             break;
2707         }
2708     }
2709 
2710   histogram[pixel] = mindisti + 1;
2711 }
2712 
2713 
2714 /* Fill the inverse-colormap entries in the update box that contains
2715  * histogram cell R/G/B.  (Only that one cell MUST be filled, but we
2716  * can fill as many others as we wish.)
2717  */
2718 static void
fill_inverse_cmap_rgb(QuantizeObj * quantobj,CFHistogram histogram,gint R,gint G,gint B)2719 fill_inverse_cmap_rgb (QuantizeObj *quantobj,
2720                        CFHistogram  histogram,
2721                        gint         R,
2722                        gint         G,
2723                        gint         B)
2724 {
2725   gint  minR, minG, minB; /* lower left corner of update box */
2726   gint  iR, iG, iB;
2727   gint *cptr;           /* pointer into bestcolor[] array */
2728   /* This array lists the candidate colormap indexes. */
2729   gint  colorlist[MAXNUMCOLORS];
2730   gint  numcolors;                /* number of candidate colors */
2731   /* This array holds the actually closest colormap index for each cell. */
2732   gint  bestcolor[BOX_R_ELEMS * BOX_G_ELEMS * BOX_B_ELEMS] = { 0, };
2733 
2734   /* Convert cell coordinates to update box id */
2735   R >>= BOX_R_LOG;
2736   G >>= BOX_G_LOG;
2737   B >>= BOX_B_LOG;
2738 
2739   /* Compute true coordinates of update box's origin corner.
2740    * Actually we compute the coordinates of the center of the corner
2741    * histogram cell, which are the lower bounds of the volume we care about.
2742    */
2743   minR = (R << BOX_R_SHIFT) + ((1 << R_SHIFT) >> 1);
2744   minG = (G << BOX_G_SHIFT) + ((1 << G_SHIFT) >> 1);
2745   minB = (B << BOX_B_SHIFT) + ((1 << B_SHIFT) >> 1);
2746 
2747   /* Determine which colormap entries are close enough to be candidates
2748    * for the nearest entry to some cell in the update box.
2749    */
2750   numcolors = find_nearby_colors (quantobj, minR, minG, minB, colorlist);
2751 
2752   /* Determine the actually nearest colors. */
2753   find_best_colors (quantobj, minR, minG, minB, numcolors, colorlist,
2754                     bestcolor);
2755 
2756   /* Save the best color numbers (plus 1) in the main cache array */
2757   R <<= BOX_R_LOG;              /* convert id back to base cell indexes */
2758   G <<= BOX_G_LOG;
2759   B <<= BOX_B_LOG;
2760   cptr = bestcolor;
2761   for (iR = 0; iR < BOX_R_ELEMS; iR++)
2762     {
2763       for (iG = 0; iG < BOX_G_ELEMS; iG++)
2764         {
2765           for (iB = 0; iB < BOX_B_ELEMS; iB++)
2766             {
2767               *HIST_LIN (histogram, R + iR, G + iG, B + iB) = (*cptr++) + 1;
2768             }
2769         }
2770     }
2771 }
2772 
2773 
2774 /*  This is pass 1  */
2775 
2776 static void
median_cut_pass1_gray(QuantizeObj * quantobj)2777 median_cut_pass1_gray (QuantizeObj *quantobj)
2778 {
2779   select_colors_gray (quantobj, quantobj->histogram);
2780 }
2781 
2782 static void
snap_to_black_and_white(QuantizeObj * quantobj)2783 snap_to_black_and_white (QuantizeObj *quantobj)
2784 {
2785   /* find whitest and blackest colors in palette, if they are closer
2786    * than 24 units of euclidian distance in sRGB snap them to pure
2787    * black / white.
2788    */
2789 #define POW2(a) ((a)*(a))
2790   gint   desired  = quantobj->desired_number_of_colors;
2791   gint   whitest  = 0;
2792   gint   blackest = 0;
2793 
2794   gint64 white_dist = POW2(255) * 3;
2795   gint64 black_dist = POW2(255) * 3;
2796   gint   i;
2797 
2798   for (i = 0; i < desired; i ++)
2799     {
2800        int dist;
2801 
2802        dist = POW2 (quantobj->cmap[i].red   - 255) +
2803               POW2 (quantobj->cmap[i].green - 255) +
2804               POW2( quantobj->cmap[i].blue  - 255);
2805        if (dist < white_dist)
2806          {
2807            white_dist = dist;
2808            whitest = i;
2809          }
2810 
2811        dist = POW2(quantobj->cmap[i].red   - 0) +
2812               POW2(quantobj->cmap[i].green - 0) +
2813               POW2(quantobj->cmap[i].blue  - 0);
2814        if (dist < black_dist)
2815          {
2816            black_dist = dist;
2817            blackest = i;
2818          }
2819     }
2820 
2821   if (desired > 2 &&
2822       had_white   &&
2823       white_dist < POW2(128))
2824   {
2825      quantobj->cmap[whitest].red   =
2826      quantobj->cmap[whitest].green =
2827      quantobj->cmap[whitest].blue  = 255;
2828   }
2829   if (desired > 2 &&
2830       had_black   &&
2831       black_dist < POW2(128))
2832   {
2833      quantobj->cmap[blackest].red   =
2834      quantobj->cmap[blackest].green =
2835      quantobj->cmap[blackest].blue  = 0;
2836   }
2837 #undef POW2
2838 }
2839 
2840 static void
median_cut_pass1_rgb(QuantizeObj * quantobj)2841 median_cut_pass1_rgb (QuantizeObj *quantobj)
2842 {
2843   select_colors_rgb (quantobj, quantobj->histogram);
2844   snap_to_black_and_white (quantobj);
2845 }
2846 
2847 
2848 static void
monopal_pass1(QuantizeObj * quantobj)2849 monopal_pass1 (QuantizeObj *quantobj)
2850 {
2851   quantobj->actual_number_of_colors = 2;
2852 
2853   quantobj->cmap[0].red   = 0;
2854   quantobj->cmap[0].green = 0;
2855   quantobj->cmap[0].blue  = 0;
2856   quantobj->cmap[1].red   = 255;
2857   quantobj->cmap[1].green = 255;
2858   quantobj->cmap[1].blue  = 255;
2859 }
2860 
2861 static void
webpal_pass1(QuantizeObj * quantobj)2862 webpal_pass1 (QuantizeObj *quantobj)
2863 {
2864   int i;
2865 
2866   quantobj->actual_number_of_colors = 216;
2867 
2868   for (i=0; i < 216; i++)
2869     {
2870       quantobj->cmap[i].red   = webpal[i * 3];
2871       quantobj->cmap[i].green = webpal[i * 3 +1];
2872       quantobj->cmap[i].blue  = webpal[i * 3 +2];
2873     }
2874 }
2875 
2876 static void
custompal_pass1(QuantizeObj * quantobj)2877 custompal_pass1 (QuantizeObj *quantobj)
2878 {
2879   gint   i;
2880   GList *list;
2881 
2882   /* fprintf(stderr,
2883              "custompal_pass1: using (theCustomPalette %s) from (file %s)\n",
2884              theCustomPalette->name, theCustomPalette->filename); */
2885 
2886   for (i = 0, list = gimp_palette_get_colors (quantobj->custom_palette);
2887        list;
2888        i++, list = g_list_next (list))
2889     {
2890       GimpPaletteEntry *entry = list->data;
2891       guchar            r, g, b;
2892 
2893       gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
2894 
2895       quantobj->cmap[i].red   = (gint) r;
2896       quantobj->cmap[i].green = (gint) g;
2897       quantobj->cmap[i].blue  = (gint) b;
2898     }
2899 
2900   quantobj -> actual_number_of_colors = i;
2901 }
2902 
2903 /*
2904  * Map some rows of pixels to the output colormapped representation.
2905  */
2906 
2907 static void
median_cut_pass2_no_dither_gray(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)2908 median_cut_pass2_no_dither_gray (QuantizeObj *quantobj,
2909                                  GimpLayer   *layer,
2910                                  GeglBuffer  *new_buffer)
2911 {
2912   GeglBufferIterator *iter;
2913   CFHistogram         histogram = quantobj->histogram;
2914   ColorFreq          *cachep;
2915   const Babl         *src_format;
2916   const Babl         *dest_format;
2917   GeglRectangle      *src_roi;
2918   gint                src_bpp;
2919   gint                dest_bpp;
2920   gint                has_alpha;
2921   guint64            *index_used_count = quantobj->index_used_count;
2922   gboolean            dither_alpha     = quantobj->want_dither_alpha;
2923   gint                offsetx, offsety;
2924 
2925   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
2926 
2927   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
2928   dest_format = gegl_buffer_get_format (new_buffer);
2929 
2930   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
2931   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
2932 
2933   has_alpha = babl_format_has_alpha (src_format);
2934 
2935   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
2936                                    NULL, 0, NULL,
2937                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
2938   src_roi = &iter->items[0].roi;
2939 
2940   gegl_buffer_iterator_add (iter, new_buffer,
2941                             NULL, 0, NULL,
2942                             GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
2943 
2944   while (gegl_buffer_iterator_next (iter))
2945     {
2946       const guchar *src  = iter->items[0].data;
2947       guchar       *dest = iter->items[1].data;
2948       gint          row;
2949 
2950       for (row = 0; row < src_roi->height; row++)
2951         {
2952           gint col;
2953 
2954           for (col = 0; col < src_roi->width; col++)
2955             {
2956               /* get pixel value and index into the cache */
2957               gint pixel = src[GRAY];
2958 
2959               cachep = &histogram[pixel];
2960               /* If we have not seen this color before, find nearest
2961                * colormap entry and update the cache
2962                */
2963               if (*cachep == 0)
2964                 fill_inverse_cmap_gray (quantobj, histogram, pixel);
2965 
2966               if (has_alpha)
2967                 {
2968                   gboolean transparent = FALSE;
2969 
2970                   if (dither_alpha)
2971                     {
2972                       gint dither_x = (col + offsetx + src_roi->x) & DM_WIDTHMASK;
2973                       gint dither_y = (row + offsety + src_roi->y) & DM_HEIGHTMASK;
2974 
2975                       if ((src[ALPHA_G]) < DM[dither_x][dither_y])
2976                         transparent = TRUE;
2977                     }
2978                   else
2979                     {
2980                       if (src[ALPHA_G] <= 127)
2981                         transparent = TRUE;
2982                     }
2983 
2984                   if (transparent)
2985                     {
2986                       dest[ALPHA_I] = 0;
2987                     }
2988                   else
2989                     {
2990                       dest[ALPHA_I] = 255;
2991                       index_used_count[dest[INDEXED] = *cachep - 1]++;
2992                     }
2993                 }
2994               else
2995                 {
2996                   /* Now emit the colormap index for this cell */
2997                   index_used_count[dest[INDEXED] = *cachep - 1]++;
2998                 }
2999 
3000               src  += src_bpp;
3001               dest += dest_bpp;
3002             }
3003         }
3004     }
3005 }
3006 
3007 static void
median_cut_pass2_fixed_dither_gray(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)3008 median_cut_pass2_fixed_dither_gray (QuantizeObj *quantobj,
3009                                     GimpLayer   *layer,
3010                                     GeglBuffer  *new_buffer)
3011 {
3012   GeglBufferIterator *iter;
3013   CFHistogram         histogram = quantobj->histogram;
3014   ColorFreq          *cachep;
3015   const Babl         *src_format;
3016   const Babl         *dest_format;
3017   GeglRectangle      *src_roi;
3018   gint                src_bpp;
3019   gint                dest_bpp;
3020   gboolean            has_alpha;
3021   gint                pixval1 = 0;
3022   gint                pixval2 = 0;
3023   gint                err1;
3024   gint                err2;
3025   Color              *color1;
3026   Color              *color2;
3027   guint64            *index_used_count = quantobj->index_used_count;
3028   gboolean            dither_alpha     = quantobj->want_dither_alpha;
3029   gint                offsetx, offsety;
3030 
3031   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
3032 
3033   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
3034   dest_format = gegl_buffer_get_format (new_buffer);
3035 
3036   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
3037   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
3038 
3039   has_alpha = babl_format_has_alpha (src_format);
3040 
3041   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
3042                                    NULL, 0, NULL,
3043                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
3044   src_roi = &iter->items[0].roi;
3045 
3046   gegl_buffer_iterator_add (iter, new_buffer,
3047                             NULL, 0, NULL,
3048                             GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
3049 
3050   while (gegl_buffer_iterator_next (iter))
3051     {
3052       const guchar *src  = iter->items[0].data;
3053       guchar       *dest = iter->items[1].data;
3054       gint          row;
3055 
3056       for (row = 0; row < src_roi->height; row++)
3057         {
3058           gint col;
3059 
3060           for (col = 0; col < src_roi->width; col++)
3061             {
3062               gint       pixel;
3063               const gint dmval =
3064                 DM[(col + offsetx + src_roi->x) & DM_WIDTHMASK]
3065                 [(row + offsety + src_roi->y) & DM_HEIGHTMASK];
3066 
3067               /* get pixel value and index into the cache */
3068               pixel = src[GRAY];
3069 
3070               cachep = &histogram[pixel];
3071               /* If we have not seen this color before, find nearest
3072                * colormap entry and update the cache
3073                */
3074               if (*cachep == 0)
3075                 fill_inverse_cmap_gray (quantobj, histogram, pixel);
3076 
3077               pixval1 = *cachep - 1;
3078               color1 = &quantobj->cmap[pixval1];
3079 
3080               if (quantobj->actual_number_of_colors > 2)
3081                 {
3082                   const int re = src[GRAY] - (int)color1->red;
3083                   int RV = src[GRAY] + re;
3084 
3085                   do
3086                     {
3087                       const gint R = CLAMP0255 (RV);
3088 
3089                       cachep = &histogram[R];
3090                       /* If we have not seen this color before, find
3091                        * nearest colormap entry and update the cache
3092                        */
3093                       if (*cachep == 0)
3094                         fill_inverse_cmap_gray (quantobj, histogram, R);
3095 
3096                       pixval2 = *cachep - 1;
3097                       RV += re;
3098                     }
3099                   while ((pixval1 == pixval2) &&
3100                          (! (RV>255 || RV<0) ) &&
3101                          re);
3102                 }
3103               else
3104                 {
3105                   /* not enough colors to bother looking for an 'alternative'
3106                      color (we may fail to do so anyway), so decide that
3107                      the alternative color is simply the other cmap entry. */
3108                   pixval2 = (pixval1 + 1) %
3109                     (quantobj->actual_number_of_colors);
3110                 }
3111 
3112               /* always deterministically sort pixval1 and pixval2, to
3113                  avoid artifacts in the dither range due to inverting our
3114                  relative color viewpoint -- most obvious in 1-bit dither. */
3115               if (pixval1 > pixval2)
3116                 {
3117                   gint tmpval = pixval1;
3118                   pixval1 = pixval2;
3119                   pixval2 = tmpval;
3120                   color1 = &quantobj->cmap[pixval1];
3121                 }
3122 
3123               color2 = &quantobj->cmap[pixval2];
3124 
3125               err1 = ABS(color1->red - src[GRAY]);
3126               err2 = ABS(color2->red - src[GRAY]);
3127               if (err1 || err2)
3128                 {
3129                   const int proportion2 = (256 * 255 * err2) / (err1 + err2);
3130 
3131                   if ((dmval * 256) > proportion2)
3132                     {
3133                       pixval1 = pixval2; /* use color2 instead of color1*/
3134                     }
3135                 }
3136 
3137               if (has_alpha)
3138                 {
3139                   gboolean transparent = FALSE;
3140 
3141                   if (dither_alpha)
3142                     {
3143                       if (src[ALPHA_G] < dmval)
3144                         transparent = TRUE;
3145                     }
3146                   else
3147                     {
3148                       if (src[ALPHA_G] <= 127)
3149                         transparent = TRUE;
3150                     }
3151 
3152                   if (transparent)
3153                     {
3154                       dest[ALPHA_I] = 0;
3155                     }
3156                   else
3157                     {
3158                       dest[ALPHA_I] = 255;
3159                       index_used_count[dest[INDEXED] = pixval1]++;
3160                     }
3161                 }
3162               else
3163                 {
3164                   /* Now emit the colormap index for this cell, barfbarf */
3165                   index_used_count[dest[INDEXED] = pixval1]++;
3166                 }
3167 
3168               src  += src_bpp;
3169               dest += dest_bpp;
3170             }
3171         }
3172     }
3173 }
3174 
3175 static void
median_cut_pass2_no_dither_rgb(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)3176 median_cut_pass2_no_dither_rgb (QuantizeObj *quantobj,
3177                                 GimpLayer   *layer,
3178                                 GeglBuffer  *new_buffer)
3179 {
3180   GeglBufferIterator *iter;
3181   CFHistogram         histogram = quantobj->histogram;
3182   ColorFreq          *cachep;
3183   const Babl         *src_format;
3184   const Babl         *dest_format;
3185   GeglRectangle      *src_roi;
3186   gint                src_bpp;
3187   gint                dest_bpp;
3188   gint                has_alpha;
3189   gint                R, G, B;
3190   gint                red_pix          = RED;
3191   gint                green_pix        = GREEN;
3192   gint                blue_pix         = BLUE;
3193   gint                alpha_pix        = ALPHA;
3194   gboolean            dither_alpha     = quantobj->want_dither_alpha;
3195   gint                offsetx, offsety;
3196   guint64            *index_used_count = quantobj->index_used_count;
3197   gint64              total_size       = 0;
3198   gint64              layer_size;
3199   gint                count            = 0;
3200 
3201   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
3202 
3203   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
3204   dest_format = gegl_buffer_get_format (new_buffer);
3205 
3206   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
3207   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
3208 
3209   has_alpha = babl_format_has_alpha (src_format);
3210 
3211   /*  In the case of web/mono palettes, we actually force
3212    *   grayscale drawables through the rgb pass2 functions
3213    */
3214   if (gimp_drawable_is_gray (GIMP_DRAWABLE (layer)))
3215     {
3216       red_pix = green_pix = blue_pix = GRAY;
3217       alpha_pix = ALPHA_G;
3218     }
3219 
3220   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
3221                                    NULL, 0, NULL,
3222                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
3223   src_roi = &iter->items[0].roi;
3224 
3225   gegl_buffer_iterator_add (iter, new_buffer,
3226                             NULL, 0, NULL,
3227                             GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
3228 
3229   layer_size = (gimp_item_get_width  (GIMP_ITEM (layer)) *
3230                 gimp_item_get_height (GIMP_ITEM (layer)));
3231 
3232   while (gegl_buffer_iterator_next (iter))
3233     {
3234       const guchar *src  = iter->items[0].data;
3235       guchar       *dest = iter->items[1].data;
3236       gint          row;
3237 
3238       total_size += src_roi->height * src_roi->width;
3239 
3240       for (row = 0; row < src_roi->height; row++)
3241         {
3242           gint col;
3243 
3244           for (col = 0; col < src_roi->width; col++)
3245             {
3246               if (has_alpha)
3247                 {
3248                   gboolean transparent = FALSE;
3249 
3250                   if (dither_alpha)
3251                     {
3252                       gint dither_x = (col + offsetx + src_roi->x) & DM_WIDTHMASK;
3253                       gint dither_y = (row + offsety + src_roi->y) & DM_HEIGHTMASK;
3254 
3255                       if ((src[alpha_pix]) < DM[dither_x][dither_y])
3256                         transparent = TRUE;
3257                     }
3258                   else
3259                     {
3260                       if (src[alpha_pix] <= 127)
3261                         transparent = TRUE;
3262                     }
3263 
3264                   if (transparent)
3265                     {
3266                       dest[ALPHA_I] = 0;
3267                       goto next_pixel;
3268                     }
3269                   else
3270                     {
3271                       dest[ALPHA_I] = 255;
3272                     }
3273                 }
3274 
3275               /* get pixel value and index into the cache */
3276               rgb_to_lin (src[red_pix], src[green_pix], src[blue_pix],
3277                           &R, &G, &B);
3278 
3279               cachep = HIST_LIN (histogram, R, G, B);
3280               /* If we have not seen this color before, find nearest
3281                * colormap entry and update the cache
3282                */
3283               if (*cachep == 0)
3284                 fill_inverse_cmap_rgb (quantobj, histogram, R, G, B);
3285 
3286               /* Now emit the colormap index for this cell, barfbarf */
3287               index_used_count[dest[INDEXED] = *cachep - 1]++;
3288 
3289             next_pixel:
3290 
3291               src  += src_bpp;
3292               dest += dest_bpp;
3293             }
3294         }
3295 
3296       if (quantobj->progress && (count % 16 == 0))
3297          gimp_progress_set_value (quantobj->progress,
3298                                   (gdouble) total_size / (gdouble) layer_size);
3299     }
3300 }
3301 
3302 static void
median_cut_pass2_fixed_dither_rgb(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)3303 median_cut_pass2_fixed_dither_rgb (QuantizeObj *quantobj,
3304                                    GimpLayer   *layer,
3305                                    GeglBuffer  *new_buffer)
3306 {
3307   GeglBufferIterator *iter;
3308   CFHistogram         histogram = quantobj->histogram;
3309   ColorFreq          *cachep;
3310   const Babl         *src_format;
3311   const Babl         *dest_format;
3312   GeglRectangle      *src_roi;
3313   gint                src_bpp;
3314   gint                dest_bpp;
3315   gint                has_alpha;
3316   gint                pixval1 = 0;
3317   gint                pixval2 = 0;
3318   Color              *color1;
3319   Color              *color2;
3320   gint                R, G, B;
3321   gint                err1;
3322   gint                err2;
3323   gint                red_pix          = RED;
3324   gint                green_pix        = GREEN;
3325   gint                blue_pix         = BLUE;
3326   gint                alpha_pix        = ALPHA;
3327   gboolean            dither_alpha     = quantobj->want_dither_alpha;
3328   gint                offsetx, offsety;
3329   guint64            *index_used_count = quantobj->index_used_count;
3330   gint64              total_size       = 0;
3331   gint64              layer_size;
3332   gint                count            = 0;
3333 
3334   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
3335 
3336   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
3337   dest_format = gegl_buffer_get_format (new_buffer);
3338 
3339   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
3340   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
3341 
3342   has_alpha = babl_format_has_alpha (src_format);
3343 
3344   /*  In the case of web/mono palettes, we actually force
3345    *   grayscale drawables through the rgb pass2 functions
3346    */
3347   if (gimp_drawable_is_gray (GIMP_DRAWABLE (layer)))
3348     {
3349       red_pix = green_pix = blue_pix = GRAY;
3350       alpha_pix = ALPHA_G;
3351     }
3352 
3353   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
3354                                    NULL, 0, NULL,
3355                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
3356   src_roi = &iter->items[0].roi;
3357 
3358   gegl_buffer_iterator_add (iter, new_buffer,
3359                             NULL, 0, NULL,
3360                             GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
3361 
3362   layer_size = (gimp_item_get_width  (GIMP_ITEM (layer)) *
3363                 gimp_item_get_height (GIMP_ITEM (layer)));
3364 
3365   while (gegl_buffer_iterator_next (iter))
3366     {
3367       const guchar *src  = iter->items[0].data;
3368       guchar       *dest = iter->items[1].data;
3369       gint          row;
3370 
3371       total_size += src_roi->height * src_roi->width;
3372 
3373       for (row = 0; row < src_roi->height; row++)
3374         {
3375           gint col;
3376 
3377           for (col = 0; col < src_roi->width; col++)
3378             {
3379               const int dmval =
3380                 DM[(col + offsetx + src_roi->x) & DM_WIDTHMASK]
3381                 [(row + offsety + src_roi->y) & DM_HEIGHTMASK];
3382 
3383               if (has_alpha)
3384                 {
3385                   gboolean transparent = FALSE;
3386 
3387                   if (dither_alpha)
3388                     {
3389                       if (src[alpha_pix] < dmval)
3390                         transparent = TRUE;
3391                     }
3392                   else
3393                     {
3394                       if (src[alpha_pix] <= 127)
3395                         transparent = TRUE;
3396                     }
3397 
3398                   if (transparent)
3399                     {
3400                       dest[ALPHA_I] = 0;
3401                       goto next_pixel;
3402                     }
3403                   else
3404                     {
3405                       dest[ALPHA_I] = 255;
3406                     }
3407                 }
3408 
3409               /* get pixel value and index into the cache */
3410               rgb_to_lin (src[red_pix], src[green_pix], src[blue_pix],
3411                           &R, &G, &B);
3412 
3413               cachep = HIST_LIN (histogram, R, G, B);
3414               /* If we have not seen this color before, find nearest
3415                * colormap entry and update the cache
3416                */
3417               if (*cachep == 0)
3418                 fill_inverse_cmap_rgb (quantobj, histogram, R, G, B);
3419 
3420               /* We now try to find a color which, when mixed in some
3421                * fashion with the closest match, yields something
3422                * closer to the desired color.  We do this by
3423                * repeatedly extrapolating the color vector from one to
3424                * the other until we find another color cell.  Then we
3425                * assess the distance of both mixer colors from the
3426                * intended color to determine their relative
3427                * probabilities of being chosen.
3428                */
3429               pixval1 = *cachep - 1;
3430               color1 = &quantobj->cmap[pixval1];
3431 
3432               if (quantobj->actual_number_of_colors > 2)
3433                 {
3434                   const gint re = src[red_pix]   - (gint) color1->red;
3435                   const gint ge = src[green_pix] - (gint) color1->green;
3436                   const gint be = src[blue_pix]  - (gint) color1->blue;
3437                   gint       RV = src[red_pix]   + re;
3438                   gint       GV = src[green_pix] + ge;
3439                   gint       BV = src[blue_pix]  + be;
3440 
3441                   do
3442                     {
3443                       rgb_to_lin ((CLAMP0255(RV)),
3444                                   (CLAMP0255(GV)),
3445                                   (CLAMP0255(BV)),
3446                                   &R, &G, &B);
3447 
3448                       cachep = HIST_LIN (histogram, R, G, B);
3449                       /* If we have not seen this color before, find
3450                        * nearest colormap entry and update the cache
3451                        */
3452                       if (*cachep == 0)
3453                         fill_inverse_cmap_rgb (quantobj, histogram, R, G, B);
3454 
3455                       pixval2 = *cachep - 1;
3456                       RV += re;  GV += ge;  BV += be;
3457                     }
3458                   while ((pixval1 == pixval2) &&
3459                          (!( (RV>255 || RV<0) || (GV>255 || GV<0) || (BV>255 || BV<0) )) &&
3460                          (re || ge || be));
3461                 }
3462 
3463               if (quantobj->actual_number_of_colors <= 2
3464                   /* || pixval1 == pixval2 */) {
3465                 /* not enough colors to bother looking for an 'alternative'
3466                    color (we may fail to do so anyway), so decide that
3467                    the alternative color is simply the other cmap entry. */
3468                 pixval2 = (pixval1 + 1) %
3469                   (quantobj->actual_number_of_colors);
3470               }
3471 
3472               /* always deterministically sort pixval1 and pixval2, to
3473                  avoid artifacts in the dither range due to inverting our
3474                  relative color viewpoint -- most obvious in 1-bit dither. */
3475               if (pixval1 > pixval2)
3476                 {
3477                   gint tmpval = pixval1;
3478                   pixval1 = pixval2;
3479                   pixval2 = tmpval;
3480                   color1 = &quantobj->cmap[pixval1];
3481                 }
3482 
3483               color2 = &quantobj->cmap[pixval2];
3484 
3485               /* now figure out the relative probabilites of choosing
3486                  either of our candidates. */
3487 #define DISTP(R1,G1,B1,R2,G2,B2,D) do {D = sqrt( 30*SQR((R1)-(R2)) + \
3488                                                  59*SQR((G1)-(G2)) + \
3489                                                  11*SQR((B1)-(B2)) ); }while(0)
3490 #define LIN_DISTP(R1,G1,B1,R2,G2,B2,D) do { \
3491                 int spacer1, spaceg1, spaceb1; \
3492                 int spacer2, spaceg2, spaceb2; \
3493                 rgb_to_unshifted_lin (R1,G1,B1, &spacer1, &spaceg1, &spaceb1); \
3494                 rgb_to_unshifted_lin (R2,G2,B2, &spacer2, &spaceg2, &spaceb2); \
3495                 D = sqrt(R_SCALE * SQR((spacer1)-(spacer2)) +           \
3496                          G_SCALE * SQR((spaceg1)-(spaceg2)) + \
3497                          B_SCALE * SQR((spaceb1)-(spaceb2))); \
3498               } while(0)
3499 
3500               /* although LIN_DISTP is more correct, DISTP is much faster and
3501                  barely distinguishable. */
3502               DISTP (color1->red, color1->green, color1->blue,
3503                      src[red_pix], src[green_pix], src[blue_pix],
3504                      err1);
3505               DISTP (color2->red, color2->green, color2->blue,
3506                      src[red_pix], src[green_pix], src[blue_pix],
3507                      err2);
3508 
3509               if (err1 || err2)
3510                 {
3511                   const int proportion2 = (255 * err2) / (err1 + err2);
3512                   if (dmval > proportion2)
3513                     {
3514                       pixval1 = pixval2; /* use color2 instead of color1*/
3515                     }
3516                 }
3517 
3518               /* Now emit the colormap index for this cell, barfbarf */
3519               index_used_count[dest[INDEXED] = pixval1]++;
3520 
3521             next_pixel:
3522 
3523               src  += src_bpp;
3524               dest += dest_bpp;
3525             }
3526         }
3527 
3528       if (quantobj->progress && (count % 16 == 0))
3529         gimp_progress_set_value (quantobj->progress,
3530                                  (gdouble) total_size / (gdouble) layer_size);
3531     }
3532 }
3533 
3534 static void
median_cut_pass2_nodestruct_dither_rgb(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)3535 median_cut_pass2_nodestruct_dither_rgb (QuantizeObj *quantobj,
3536                                         GimpLayer   *layer,
3537                                         GeglBuffer  *new_buffer)
3538 {
3539   GeglBufferIterator *iter;
3540   const Babl         *src_format;
3541   const Babl         *dest_format;
3542   GeglRectangle      *src_roi;
3543   gint                src_bpp;
3544   gint                dest_bpp;
3545   gint                has_alpha;
3546   gboolean            dither_alpha = quantobj->want_dither_alpha;
3547   gint                red_pix      = RED;
3548   gint                green_pix    = GREEN;
3549   gint                blue_pix     = BLUE;
3550   gint                alpha_pix    = ALPHA;
3551   gint                lastindex    = 0;
3552   gint                lastred      = -1;
3553   gint                lastgreen    = -1;
3554   gint                lastblue     = -1;
3555   gint                offsetx, offsety;
3556 
3557   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
3558 
3559   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
3560   dest_format = gegl_buffer_get_format (new_buffer);
3561 
3562   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
3563   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
3564 
3565   has_alpha = babl_format_has_alpha (src_format);
3566 
3567   iter = gegl_buffer_iterator_new (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)),
3568                                    NULL, 0, NULL,
3569                                    GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 2);
3570   src_roi = &iter->items[0].roi;
3571 
3572   gegl_buffer_iterator_add (iter, new_buffer,
3573                             NULL, 0, NULL,
3574                             GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
3575 
3576   while (gegl_buffer_iterator_next (iter))
3577     {
3578       const guchar *src  = iter->items[0].data;
3579       guchar       *dest = iter->items[1].data;
3580       gint          row;
3581 
3582       for (row = 0; row < src_roi->height; row++)
3583         {
3584           gint col;
3585 
3586           for (col = 0; col < src_roi->width; col++)
3587             {
3588               gboolean transparent = FALSE;
3589 
3590               if (has_alpha)
3591                 {
3592                   if (dither_alpha)
3593                     {
3594                       gint dither_x = (col + src_roi->x + offsetx) & DM_WIDTHMASK;
3595                       gint dither_y = (row + src_roi->y + offsety) & DM_HEIGHTMASK;
3596 
3597                       if ((src[alpha_pix]) < DM[dither_x][dither_y])
3598                         transparent = TRUE;
3599                     }
3600                   else
3601                     {
3602                       if (src[alpha_pix] < 128)
3603                         transparent = TRUE;
3604                     }
3605                 }
3606 
3607               if (! transparent)
3608                 {
3609                   if ((lastred   == src[red_pix]) &&
3610                       (lastgreen == src[green_pix]) &&
3611                       (lastblue  == src[blue_pix]))
3612                     {
3613                       /*  same pixel color as last time  */
3614                       dest[INDEXED] = lastindex;
3615                       if (has_alpha)
3616                         dest[ALPHA_I] = 255;
3617                     }
3618                   else
3619                     {
3620                       gint i;
3621 
3622                       for (i = 0 ;
3623                            i < quantobj->actual_number_of_colors;
3624                            i++)
3625                         {
3626                           if ((quantobj->cmap[i].green == src[green_pix]) &&
3627                               (quantobj->cmap[i].red   == src[red_pix]) &&
3628                               (quantobj->cmap[i].blue  == src[blue_pix]))
3629                           {
3630                             lastred   = src[red_pix];
3631                             lastgreen = src[green_pix];
3632                             lastblue  = src[blue_pix];
3633                             lastindex = i;
3634 
3635                             goto got_color;
3636                           }
3637                         }
3638                       g_error ("Non-existant color was expected to "
3639                                "be in non-destructive colormap.");
3640                     got_color:
3641                       dest[INDEXED] = lastindex;
3642                       if (has_alpha)
3643                         dest[ALPHA_I] = 255;
3644                     }
3645                 }
3646               else
3647                 { /*  have alpha, and transparent  */
3648                   dest[ALPHA_I] = 0;
3649                 }
3650 
3651               src  += src_bpp;
3652               dest += dest_bpp;
3653             }
3654         }
3655     }
3656 }
3657 
3658 
3659 /*
3660  * Initialize the error-limiting transfer function (lookup table).
3661  * The raw F-S error computation can potentially compute error values of up to
3662  * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
3663  * much less, otherwise obviously wrong pixels will be created.  (Typical
3664  * effects include weird fringes at color-area boundaries, isolated bright
3665  * pixels in a dark area, etc.)  The standard advice for avoiding this problem
3666  * is to ensure that the "corners" of the color cube are allocated as output
3667  * colors; then repeated errors in the same direction cannot cause cascading
3668  * error buildup.  However, that only prevents the error from getting
3669  * completely out of hand; Aaron Giles reports that error limiting improves
3670  * the results even with corner colors allocated.
3671  * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
3672  * well, but the smoother transfer function used below is even better.  Thanks
3673  * to Aaron Giles for this idea.
3674  */
3675 
3676 static gint *
init_error_limit(const int error_freedom)3677 init_error_limit (const int error_freedom)
3678 /* Allocate and fill in the error_limiter table */
3679 {
3680   gint *table;
3681   gint  inp, out;
3682 
3683   /* #define STEPSIZE 16 */
3684   /* #define STEPSIZE 200 */
3685 
3686   table = g_new (gint, 255 * 2 + 1);
3687   table += 255;                 /* so we can index -255 ... +255 */
3688 
3689   if (error_freedom == 0)
3690     {
3691       /* Coarse function, much bleeding. */
3692 
3693       const gint STEPSIZE = 190;
3694 
3695       for (inp = 0; inp < STEPSIZE; inp++)
3696         {
3697           table[inp] = inp;
3698           table[-inp] = -inp;
3699         }
3700 
3701       for (; inp <= 255; inp++)
3702         {
3703           table[inp] = STEPSIZE;
3704           table[-inp] = -STEPSIZE;
3705         }
3706 
3707       return (table);
3708     }
3709   else
3710     {
3711       /* Smooth function, bleeding more constrained */
3712 
3713       const gint STEPSIZE = 24;
3714 
3715       /* Map errors 1:1 up to +- STEPSIZE */
3716       out = 0;
3717       for (inp = 0; inp < STEPSIZE; inp++, out++)
3718         {
3719           table[inp] = out;
3720           table[-inp] = -out;
3721         }
3722 
3723       /* Map errors 1:2 up to +- 3*STEPSIZE */
3724       for (; inp < STEPSIZE*3; inp++, out += (inp&1) ? 0 : 1)
3725         {
3726           table[inp] = out;
3727           table[-inp] = -out;
3728         }
3729 
3730       /* Clamp the rest to final out value (which is STEPSIZE*2) */
3731       for (; inp <= 255; inp++)
3732         {
3733           table[inp] = out;
3734           table[-inp] = -out;
3735         }
3736 
3737       return table;
3738     }
3739 }
3740 
3741 
3742 /*
3743  * Map some rows of pixels to the output colormapped representation.
3744  * Perform floyd-steinberg dithering.
3745  */
3746 
3747 static void
median_cut_pass2_fs_dither_gray(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)3748 median_cut_pass2_fs_dither_gray (QuantizeObj *quantobj,
3749                                  GimpLayer   *layer,
3750                                  GeglBuffer  *new_buffer)
3751 {
3752   GeglBuffer   *src_buffer;
3753   CFHistogram   histogram = quantobj->histogram;
3754   ColorFreq    *cachep;
3755   Color        *color;
3756   gint         *error_limiter;
3757   const gshort *fs_err1, *fs_err2;
3758   const gshort *fs_err3, *fs_err4;
3759   const guchar *range_limiter;
3760   const Babl   *src_format;
3761   const Babl   *dest_format;
3762   gint          src_bpp;
3763   gint          dest_bpp;
3764   guchar       *src_buf, *dest_buf;
3765   gint         *next_row, *prev_row;
3766   gint         *nr, *pr;
3767   gint         *tmp;
3768   gint          pixel;
3769   gint          pixele;
3770   gint          row, col;
3771   gint          index;
3772   gint          step_dest, step_src;
3773   gint          odd_row;
3774   gboolean      has_alpha;
3775   gint          offsetx, offsety;
3776   gboolean      dither_alpha = quantobj->want_dither_alpha;
3777   gint          width, height;
3778   guint64      *index_used_count = quantobj->index_used_count;
3779 
3780   src_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
3781 
3782   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
3783 
3784   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
3785   dest_format = gegl_buffer_get_format (new_buffer);
3786 
3787   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
3788   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
3789 
3790   has_alpha = babl_format_has_alpha (src_format);
3791 
3792   width  = gimp_item_get_width  (GIMP_ITEM (layer));
3793   height = gimp_item_get_height (GIMP_ITEM (layer));
3794 
3795   error_limiter = init_error_limit (quantobj->error_freedom);
3796   range_limiter = range_array + 256;
3797 
3798   src_buf  = g_malloc (width * src_bpp);
3799   dest_buf = g_malloc (width * dest_bpp);
3800 
3801   next_row = g_new (gint, width + 2);
3802   prev_row = g_new0 (gint, width + 2);
3803 
3804   fs_err1 = floyd_steinberg_error1 + 511;
3805   fs_err2 = floyd_steinberg_error2 + 511;
3806   fs_err3 = floyd_steinberg_error3 + 511;
3807   fs_err4 = floyd_steinberg_error4 + 511;
3808 
3809   odd_row = 0;
3810 
3811   for (row = 0; row < height; row++)
3812     {
3813       const guchar *src;
3814       guchar       *dest;
3815 
3816       gegl_buffer_get (src_buffer, GEGL_RECTANGLE (0, row, width, 1),
3817                        1.0, NULL, src_buf,
3818                        GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
3819 
3820       src  = src_buf;
3821       dest = dest_buf;
3822 
3823       nr = next_row;
3824       pr = prev_row + 1;
3825 
3826       if (odd_row)
3827         {
3828           step_dest = -dest_bpp;
3829           step_src  = -src_bpp;
3830 
3831           src  += (width * src_bpp) - src_bpp;
3832           dest += (width * dest_bpp) - dest_bpp;
3833 
3834           nr += width + 1;
3835           pr += width;
3836 
3837           *(nr - 1) = 0;
3838         }
3839       else
3840         {
3841           step_dest = dest_bpp;
3842           step_src  = src_bpp;
3843 
3844           *(nr + 1) = 0;
3845         }
3846 
3847       *nr = 0;
3848 
3849       for (col = 0; col < width; col++)
3850         {
3851           pixel = range_limiter[src[GRAY] + error_limiter[*pr]];
3852 
3853           cachep = &histogram[pixel];
3854           /* If we have not seen this color before, find nearest
3855            * colormap entry and update the cache
3856            */
3857           if (*cachep == 0)
3858             fill_inverse_cmap_gray (quantobj, histogram, pixel);
3859 
3860           if (has_alpha)
3861             {
3862               gboolean transparent = FALSE;
3863 
3864               if (odd_row)
3865                 {
3866                   if (dither_alpha)
3867                     {
3868                       gint dither_x = ((width-col)+offsetx-1) & DM_WIDTHMASK;
3869                       gint dither_y = (row+offsety) & DM_HEIGHTMASK;
3870 
3871                       if ((src[ALPHA_G]) < DM[dither_x][dither_y])
3872                         transparent = TRUE;
3873                     }
3874                   else
3875                     {
3876                       if (src[ALPHA_G] <= 127)
3877                         transparent = TRUE;
3878                     }
3879 
3880                   if (transparent)
3881                     {
3882                       dest[ALPHA_I] = 0;
3883                       pr--;
3884                       nr--;
3885                       *(nr - 1) = 0;
3886                       goto next_pixel;
3887                     }
3888                   else
3889                     {
3890                       dest[ALPHA_I] = 255;
3891                     }
3892                 }
3893               else
3894                 {
3895                   if (dither_alpha)
3896                     {
3897                       gint dither_x = (col + offsetx) & DM_WIDTHMASK;
3898                       gint dither_y = (row + offsety) & DM_HEIGHTMASK;
3899 
3900                       if ((src[ALPHA_G]) < DM[dither_x][dither_y])
3901                         transparent = TRUE;
3902                     }
3903                   else
3904                     {
3905                       if (src[ALPHA_G] <= 127)
3906                         transparent = TRUE;
3907                     }
3908 
3909                   if (transparent)
3910                     {
3911                       dest[ALPHA_I] = 0;
3912                       pr++;
3913                       nr++;
3914                       *(nr + 1) = 0;
3915                       goto next_pixel;
3916                     }
3917                   else
3918                     {
3919                       dest[ALPHA_I] = 255;
3920                     }
3921                 }
3922             }
3923 
3924           index = *cachep - 1;
3925           index_used_count[dest[INDEXED] = index]++;
3926 
3927           color = &quantobj->cmap[index];
3928           pixele = pixel - color->red;
3929 
3930           if (odd_row)
3931             {
3932               *(--pr) += fs_err1[pixele];
3933               *nr-- += fs_err2[pixele];
3934               *nr += fs_err3[pixele];
3935               *(nr-1) = fs_err4[pixele];
3936             }
3937           else
3938             {
3939               *(++pr) += fs_err1[pixele];
3940               *nr++ += fs_err2[pixele];
3941               *nr += fs_err3[pixele];
3942               *(nr+1) = fs_err4[pixele];
3943             }
3944 
3945         next_pixel:
3946 
3947           dest += step_dest;
3948           src += step_src;
3949         }
3950 
3951       tmp = next_row;
3952       next_row = prev_row;
3953       prev_row = tmp;
3954 
3955       odd_row = !odd_row;
3956 
3957       gegl_buffer_set (new_buffer, GEGL_RECTANGLE (0, row, width, 1),
3958                        0, NULL, dest_buf,
3959                        GEGL_AUTO_ROWSTRIDE);
3960     }
3961 
3962   g_free (error_limiter - 255); /* good lord. */
3963   g_free (next_row);
3964   g_free (prev_row);
3965   g_free (src_buf);
3966   g_free (dest_buf);
3967 }
3968 
3969 static void
median_cut_pass2_rgb_init(QuantizeObj * quantobj)3970 median_cut_pass2_rgb_init (QuantizeObj *quantobj)
3971 {
3972   int i;
3973 
3974   zero_histogram_rgb (quantobj->histogram);
3975 
3976   /* Mark all indices as currently unused */
3977   memset (quantobj->index_used_count, 0, 256 * sizeof (guint64));
3978 
3979   /* Make a version of our discovered colormap in linear space */
3980   for (i = 0; i < quantobj->actual_number_of_colors; i++)
3981     {
3982       rgb_to_unshifted_lin (quantobj->cmap[i].red,
3983                             quantobj->cmap[i].green,
3984                             quantobj->cmap[i].blue,
3985                             &quantobj->clin[i].red,
3986                             &quantobj->clin[i].green,
3987                             &quantobj->clin[i].blue);
3988     }
3989 }
3990 
3991 static void
median_cut_pass2_gray_init(QuantizeObj * quantobj)3992 median_cut_pass2_gray_init (QuantizeObj *quantobj)
3993 {
3994   zero_histogram_gray (quantobj->histogram);
3995 
3996   /* Mark all indices as currently unused */
3997   memset (quantobj->index_used_count, 0, 256 * sizeof (guint64));
3998 }
3999 
4000 static void
median_cut_pass2_fs_dither_rgb(QuantizeObj * quantobj,GimpLayer * layer,GeglBuffer * new_buffer)4001 median_cut_pass2_fs_dither_rgb (QuantizeObj *quantobj,
4002                                 GimpLayer   *layer,
4003                                 GeglBuffer  *new_buffer)
4004 {
4005   GeglBuffer   *src_buffer;
4006   CFHistogram   histogram = quantobj->histogram;
4007   ColorFreq    *cachep;
4008   Color        *color;
4009   gint         *error_limiter;
4010   const gshort *fs_err1, *fs_err2;
4011   const gshort *fs_err3, *fs_err4;
4012   const guchar *range_limiter;
4013   const Babl   *src_format;
4014   const Babl   *dest_format;
4015   gint          src_bpp;
4016   gint          dest_bpp;
4017   guchar       *src_buf, *dest_buf;
4018   gint         *red_n_row, *red_p_row;
4019   gint         *grn_n_row, *grn_p_row;
4020   gint         *blu_n_row, *blu_p_row;
4021   gint         *rnr, *rpr;
4022   gint         *gnr, *gpr;
4023   gint         *bnr, *bpr;
4024   gint         *tmp;
4025   gint          re, ge, be;
4026   gint          row, col;
4027   gint          index;
4028   gint          step_dest, step_src;
4029   gint          odd_row;
4030   gboolean      has_alpha;
4031   gint          width, height;
4032   gint          red_pix   = RED;
4033   gint          green_pix = GREEN;
4034   gint          blue_pix  = BLUE;
4035   gint          alpha_pix = ALPHA;
4036   gint          offsetx, offsety;
4037   gboolean      dither_alpha     = quantobj->want_dither_alpha;
4038   guint64      *index_used_count = quantobj->index_used_count;
4039   gint          global_rmax = 0, global_rmin = G_MAXINT;
4040   gint          global_gmax = 0, global_gmin = G_MAXINT;
4041   gint          global_bmax = 0, global_bmin = G_MAXINT;
4042 
4043   src_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
4044 
4045   gimp_item_get_offset (GIMP_ITEM (layer), &offsetx, &offsety);
4046 
4047   /*  In the case of web/mono palettes, we actually force
4048    *   grayscale drawables through the rgb pass2 functions
4049    */
4050   if (gimp_drawable_is_gray (GIMP_DRAWABLE (layer)))
4051     red_pix = green_pix = blue_pix = GRAY;
4052 
4053   src_format  = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
4054   dest_format = gegl_buffer_get_format (new_buffer);
4055 
4056   src_bpp  = babl_format_get_bytes_per_pixel (src_format);
4057   dest_bpp = babl_format_get_bytes_per_pixel (dest_format);
4058 
4059   has_alpha = babl_format_has_alpha (src_format);
4060 
4061   width  = gimp_item_get_width  (GIMP_ITEM (layer));
4062   height = gimp_item_get_height (GIMP_ITEM (layer));
4063 
4064   error_limiter = init_error_limit (quantobj->error_freedom);
4065   range_limiter = range_array + 256;
4066 
4067   /* find the bounding box of the palette colors --
4068      we use this for hard-clamping our error-corrected
4069      values so that we can't continuously accelerate outside
4070      of our attainable gamut, which looks icky. */
4071   for (index = 0; index < quantobj->actual_number_of_colors; index++)
4072     {
4073       global_rmax = MAX(global_rmax, quantobj->clin[index].red);
4074       global_rmin = MIN(global_rmin, quantobj->clin[index].red);
4075       global_gmax = MAX(global_gmax, quantobj->clin[index].green);
4076       global_gmin = MIN(global_gmin, quantobj->clin[index].green);
4077       global_bmax = MAX(global_bmax, quantobj->clin[index].blue);
4078       global_bmin = MIN(global_bmin, quantobj->clin[index].blue);
4079     }
4080 
4081   src_buf  = g_malloc (width * src_bpp);
4082   dest_buf = g_malloc (width * dest_bpp);
4083 
4084   red_n_row = g_new (gint, width + 2);
4085   red_p_row = g_new0 (gint, width + 2);
4086   grn_n_row = g_new (gint, width + 2);
4087   grn_p_row = g_new0 (gint, width + 2);
4088   blu_n_row = g_new (gint, width + 2);
4089   blu_p_row = g_new0 (gint, width + 2);
4090 
4091   fs_err1 = floyd_steinberg_error1 + 511;
4092   fs_err2 = floyd_steinberg_error2 + 511;
4093   fs_err3 = floyd_steinberg_error3 + 511;
4094   fs_err4 = floyd_steinberg_error4 + 511;
4095 
4096   odd_row = 0;
4097 
4098   for (row = 0; row < height; row++)
4099     {
4100       const guchar *src;
4101       guchar       *dest;
4102 
4103       gegl_buffer_get (src_buffer, GEGL_RECTANGLE (0, row, width, 1),
4104                        1.0, NULL, src_buf,
4105                        GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
4106 
4107       src  = src_buf;
4108       dest = dest_buf;
4109 
4110       rnr = red_n_row;
4111       gnr = grn_n_row;
4112       bnr = blu_n_row;
4113       rpr = red_p_row + 1;
4114       gpr = grn_p_row + 1;
4115       bpr = blu_p_row + 1;
4116 
4117       if (odd_row)
4118         {
4119           step_dest = -dest_bpp;
4120           step_src  = -src_bpp;
4121 
4122           src += (width * src_bpp) - src_bpp;
4123           dest += (width * dest_bpp) - dest_bpp;
4124 
4125           rnr += width + 1;
4126           gnr += width + 1;
4127           bnr += width + 1;
4128           rpr += width;
4129           gpr += width;
4130           bpr += width;
4131 
4132           *(rnr - 1) = *(gnr - 1) = *(bnr - 1) = 0;
4133         }
4134       else
4135         {
4136           step_dest = dest_bpp;
4137           step_src  = src_bpp;
4138 
4139           *(rnr + 1) = *(gnr + 1) = *(bnr + 1) = 0;
4140         }
4141 
4142       *rnr = *gnr = *bnr = 0;
4143 
4144       for (col = 0; col < width; col++)
4145         {
4146           if (has_alpha)
4147             {
4148               gboolean transparent = FALSE;
4149 
4150               if (odd_row)
4151                 {
4152                   if (dither_alpha)
4153                     {
4154                       gint dither_x = ((width-col)+offsetx-1) & DM_WIDTHMASK;
4155                       gint dither_y = (row+offsety) & DM_HEIGHTMASK;
4156 
4157                       if ((src[alpha_pix]) < DM[dither_x][dither_y])
4158                         transparent = TRUE;
4159                     }
4160                   else
4161                     {
4162                       if (src[alpha_pix] <= 127)
4163                         transparent = TRUE;
4164                     }
4165 
4166                   if (transparent)
4167                     {
4168                       dest[ALPHA_I] = 0;
4169                       rpr--; gpr--; bpr--;
4170                       rnr--; gnr--; bnr--;
4171                       *(rnr - 1) = *(gnr - 1) = *(bnr - 1) = 0;
4172                       goto next_pixel;
4173                     }
4174                   else
4175                     {
4176                       dest[ALPHA_I] = 255;
4177                     }
4178                 }
4179               else
4180                 {
4181                   if (dither_alpha)
4182                     {
4183                       gint dither_x = (col + offsetx) & DM_WIDTHMASK;
4184                       gint dither_y = (row + offsety) & DM_HEIGHTMASK;
4185 
4186                       if ((src[alpha_pix]) < DM[dither_x][dither_y])
4187                         transparent = TRUE;
4188                     }
4189                   else
4190                     {
4191                       if (src[alpha_pix] <= 127)
4192                         transparent = TRUE;
4193                     }
4194 
4195                   if (transparent)
4196                     {
4197                       dest[ALPHA_I] = 0;
4198                       rpr++; gpr++; bpr++;
4199                       rnr++; gnr++; bnr++;
4200                       *(rnr + 1) = *(gnr + 1) = *(bnr + 1) = 0;
4201                       goto next_pixel;
4202                     }
4203                   else
4204                     {
4205                       dest[ALPHA_I] = 255;
4206                     }
4207                 }
4208             }
4209 
4210 #if 0
4211           /* hmm. */
4212 
4213           r = range_limiter[src[red_pix] + error_limiter[*rpr]];
4214           g = range_limiter[src[green_pix] + error_limiter[*gpr]];
4215           b = range_limiter[src[blue_pix] + error_limiter[*bpr]];
4216 
4217           re = r >> R_SHIFT;
4218           ge = g >> G_SHIFT;
4219           be = b >> B_SHIFT;
4220 
4221           rgb_to_lin (r, g, b, &re, &ge, &be);
4222 #endif
4223           rgb_to_unshifted_lin (src[red_pix], src[green_pix], src[blue_pix],
4224                                 &re, &ge, &be);
4225 
4226           /*
4227             re = CLAMP(re, global_rmin, global_rmax);
4228             ge = CLAMP(ge, global_gmin, global_gmax);
4229             be = CLAMP(be, global_bmin, global_bmax);*/
4230 
4231           re = range_limiter[re + error_limiter[*rpr]];
4232           ge = range_limiter[ge + error_limiter[*gpr]];
4233           be = range_limiter[be + error_limiter[*bpr]];
4234 
4235           cachep = HIST_LIN (histogram,
4236                              RSDF (re),
4237                              GSDF (ge),
4238                              BSDF (be));
4239           /* If we have not seen this color before, find nearest
4240            * colormap entry and update the cache
4241            */
4242           if (*cachep == 0)
4243             fill_inverse_cmap_rgb (quantobj, histogram,
4244                                    RSDF (re),
4245                                    GSDF (ge),
4246                                    BSDF (be));
4247 
4248           index = *cachep - 1;
4249           index_used_count[index]++;
4250           dest[INDEXED] = index;
4251 
4252           /*if (re > global_rmax)
4253             re = (re + 3*global_rmax) / 4;
4254           else if (re < global_rmin)
4255           re = (re + 3*global_rmin) / 4;*/
4256 
4257           /* We constrain chroma error extra-hard so that it
4258              doesn't run away and steal the thunder from the
4259              lightness error where all the detail usually is. */
4260           if (ge > global_gmax)
4261             ge = (ge + 3*global_gmax) / 4;
4262           else if (ge < global_gmin)
4263             ge = (ge + 3*global_gmin) / 4;
4264           if (be > global_bmax)
4265             be = (be + 3*global_bmax) / 4;
4266           else if (be < global_bmin)
4267             be = (be + 3*global_bmin) / 4;
4268 
4269           color = &quantobj->clin[index];
4270 
4271 #if 0
4272           if ((re > 0 && re < 255) /* HMM &&
4273               ge >= 0 && ge <= 255 &&
4274               be >= 0 && be <= 255*/)
4275             {
4276               ge = ge - color->green;
4277               be = be - color->blue;
4278               re = re - color->red;
4279             }
4280           else
4281             {
4282               /* color pretty much undefined now; nullify error. */
4283               re = ge = be = 0;
4284             }
4285 #endif
4286 
4287           if (re <= 0 || re >= 255)
4288             re = ge = be = 0;
4289           else
4290             {
4291               re = re - color->red;
4292               ge = ge - color->green;
4293               be = be - color->blue;
4294             }
4295 
4296           if (odd_row)
4297             {
4298               *(--rpr) += fs_err1[re];
4299               *(--gpr) += fs_err1[ge];
4300               *(--bpr) += fs_err1[be];
4301 
4302               *rnr-- += fs_err2[re];
4303               *gnr-- += fs_err2[ge];
4304               *bnr-- += fs_err2[be];
4305 
4306               *rnr += fs_err3[re];
4307               *gnr += fs_err3[ge];
4308               *bnr += fs_err3[be];
4309 
4310               *(rnr-1) = fs_err4[re];
4311               *(gnr-1) = fs_err4[ge];
4312               *(bnr-1) = fs_err4[be];
4313             }
4314           else
4315             {
4316               *(++rpr) += fs_err1[re];
4317               *(++gpr) += fs_err1[ge];
4318               *(++bpr) += fs_err1[be];
4319 
4320               *rnr++ += fs_err2[re];
4321               *gnr++ += fs_err2[ge];
4322               *bnr++ += fs_err2[be];
4323 
4324               *rnr += fs_err3[re];
4325               *gnr += fs_err3[ge];
4326               *bnr += fs_err3[be];
4327 
4328               *(rnr+1) = fs_err4[re];
4329               *(gnr+1) = fs_err4[ge];
4330               *(bnr+1) = fs_err4[be];
4331             }
4332 
4333         next_pixel:
4334 
4335           dest += step_dest;
4336           src += step_src;
4337         }
4338 
4339       tmp = red_n_row;
4340       red_n_row = red_p_row;
4341       red_p_row = tmp;
4342 
4343       tmp = grn_n_row;
4344       grn_n_row = grn_p_row;
4345       grn_p_row = tmp;
4346 
4347       tmp = blu_n_row;
4348       blu_n_row = blu_p_row;
4349       blu_p_row = tmp;
4350 
4351       odd_row = !odd_row;
4352 
4353       gegl_buffer_set (new_buffer, GEGL_RECTANGLE (0, row, width, 1),
4354                        0, NULL, dest_buf,
4355                        GEGL_AUTO_ROWSTRIDE);
4356 
4357       if (quantobj->progress && (row % 16 == 0))
4358         gimp_progress_set_value (quantobj->progress,
4359                                  (gdouble) row / (gdouble) height);
4360     }
4361 
4362   g_free (error_limiter - 255);
4363   g_free (red_n_row);
4364   g_free (red_p_row);
4365   g_free (grn_n_row);
4366   g_free (grn_p_row);
4367   g_free (blu_n_row);
4368   g_free (blu_p_row);
4369   g_free (src_buf);
4370   g_free (dest_buf);
4371 }
4372 
4373 
4374 static void
delete_median_cut(QuantizeObj * quantobj)4375 delete_median_cut (QuantizeObj *quantobj)
4376 {
4377   g_free (quantobj->histogram);
4378   g_free (quantobj);
4379 }
4380 
4381 
4382 void
gimp_image_convert_indexed_set_dither_matrix(const guchar * matrix,gint width,gint height)4383 gimp_image_convert_indexed_set_dither_matrix (const guchar *matrix,
4384                                               gint          width,
4385                                               gint          height)
4386 {
4387   gint x;
4388   gint y;
4389 
4390   /* if matrix is invalid, restore the default matrix */
4391   if (matrix == NULL || width == 0 || height == 0)
4392     {
4393       matrix = (const guchar *) DM_ORIGINAL;
4394       width  = DM_WIDTH;
4395       height = DM_HEIGHT;
4396     }
4397 
4398   g_return_if_fail ((DM_WIDTH % width) == 0);
4399   g_return_if_fail ((DM_HEIGHT % height) == 0);
4400 
4401   for (y = 0; y < DM_HEIGHT; y++)
4402     {
4403       for (x = 0; x < DM_WIDTH; x++)
4404         {
4405           DM[x][y] = matrix[((x % width) * height) + (y % height)];
4406         }
4407     }
4408 }
4409 
4410 
4411 /**************************************************************/
4412 static QuantizeObj *
initialize_median_cut(GimpImageBaseType type,gint num_colors,GimpConvertDitherType dither_type,GimpConvertPaletteType palette_type,GimpPalette * custom_palette,gboolean want_dither_alpha,GimpProgress * progress)4413 initialize_median_cut (GimpImageBaseType       type,
4414                        gint                    num_colors,
4415                        GimpConvertDitherType   dither_type,
4416                        GimpConvertPaletteType  palette_type,
4417                        GimpPalette            *custom_palette,
4418                        gboolean                want_dither_alpha,
4419                        GimpProgress           *progress)
4420 {
4421   QuantizeObj *quantobj;
4422 
4423   /* Initialize the data structures */
4424   quantobj = g_new (QuantizeObj, 1);
4425 
4426   if (type == GIMP_GRAY && palette_type == GIMP_CONVERT_PALETTE_GENERATE)
4427     quantobj->histogram = g_new (ColorFreq, 256);
4428   else
4429     quantobj->histogram = g_new (ColorFreq,
4430                                  HIST_R_ELEMS * HIST_G_ELEMS * HIST_B_ELEMS);
4431 
4432   quantobj->custom_palette           = custom_palette;
4433   quantobj->desired_number_of_colors = num_colors;
4434   quantobj->want_dither_alpha        = want_dither_alpha;
4435   quantobj->progress                 = progress;
4436 
4437   switch (type)
4438     {
4439     case GIMP_GRAY:
4440       switch (palette_type)
4441         {
4442         case GIMP_CONVERT_PALETTE_GENERATE:
4443           quantobj->first_pass = median_cut_pass1_gray;
4444           break;
4445         case GIMP_CONVERT_PALETTE_WEB:
4446           quantobj->first_pass = webpal_pass1;
4447           break;
4448         case GIMP_CONVERT_PALETTE_CUSTOM:
4449           quantobj->first_pass = custompal_pass1;
4450           needs_quantize = TRUE;
4451           break;
4452         case GIMP_CONVERT_PALETTE_MONO:
4453         default:
4454           quantobj->first_pass = monopal_pass1;
4455         }
4456 
4457       if (palette_type == GIMP_CONVERT_PALETTE_WEB ||
4458           palette_type == GIMP_CONVERT_PALETTE_CUSTOM)
4459         {
4460           switch (dither_type)
4461             {
4462             case GIMP_CONVERT_DITHER_NODESTRUCT:
4463             default:
4464               g_warning("Uh-oh, bad dither type, W1");
4465             case GIMP_CONVERT_DITHER_NONE:
4466               quantobj->second_pass_init = median_cut_pass2_rgb_init;
4467               quantobj->second_pass = median_cut_pass2_no_dither_rgb;
4468               break;
4469             case GIMP_CONVERT_DITHER_FS:
4470               quantobj->error_freedom = 0;
4471               quantobj->second_pass_init = median_cut_pass2_rgb_init;
4472               quantobj->second_pass = median_cut_pass2_fs_dither_rgb;
4473               break;
4474             case GIMP_CONVERT_DITHER_FS_LOWBLEED:
4475               quantobj->error_freedom = 1;
4476               quantobj->second_pass_init = median_cut_pass2_rgb_init;
4477               quantobj->second_pass = median_cut_pass2_fs_dither_rgb;
4478               break;
4479             case GIMP_CONVERT_DITHER_FIXED:
4480               quantobj->second_pass_init = median_cut_pass2_rgb_init;
4481               quantobj->second_pass = median_cut_pass2_fixed_dither_rgb;
4482               break;
4483             }
4484         }
4485       else
4486         {
4487           switch (dither_type)
4488             {
4489             case GIMP_CONVERT_DITHER_NODESTRUCT:
4490             default:
4491               g_warning("Uh-oh, bad dither type, W2");
4492             case GIMP_CONVERT_DITHER_NONE:
4493               quantobj->second_pass_init = median_cut_pass2_gray_init;
4494               quantobj->second_pass = median_cut_pass2_no_dither_gray;
4495               break;
4496             case GIMP_CONVERT_DITHER_FS:
4497               quantobj->error_freedom = 0;
4498               quantobj->second_pass_init = median_cut_pass2_gray_init;
4499               quantobj->second_pass = median_cut_pass2_fs_dither_gray;
4500               break;
4501             case GIMP_CONVERT_DITHER_FS_LOWBLEED:
4502               quantobj->error_freedom = 1;
4503               quantobj->second_pass_init = median_cut_pass2_gray_init;
4504               quantobj->second_pass = median_cut_pass2_fs_dither_gray;
4505               break;
4506             case GIMP_CONVERT_DITHER_FIXED:
4507               quantobj->second_pass_init = median_cut_pass2_gray_init;
4508               quantobj->second_pass = median_cut_pass2_fixed_dither_gray;
4509               break;
4510             }
4511         }
4512       break;
4513 
4514     case GIMP_RGB:
4515       switch (palette_type)
4516         {
4517         case GIMP_CONVERT_PALETTE_GENERATE:
4518           quantobj->first_pass = median_cut_pass1_rgb;
4519           break;
4520         case GIMP_CONVERT_PALETTE_WEB:
4521           quantobj->first_pass = webpal_pass1;
4522           needs_quantize = TRUE;
4523           break;
4524         case GIMP_CONVERT_PALETTE_CUSTOM:
4525           quantobj->first_pass = custompal_pass1;
4526           needs_quantize = TRUE;
4527           break;
4528         case GIMP_CONVERT_PALETTE_MONO:
4529         default:
4530           quantobj->first_pass = monopal_pass1;
4531         }
4532 
4533       switch (dither_type)
4534         {
4535         case GIMP_CONVERT_DITHER_NONE:
4536           quantobj->second_pass_init = median_cut_pass2_rgb_init;
4537           quantobj->second_pass = median_cut_pass2_no_dither_rgb;
4538           break;
4539         case GIMP_CONVERT_DITHER_FS:
4540           quantobj->error_freedom = 0;
4541           quantobj->second_pass_init = median_cut_pass2_rgb_init;
4542           quantobj->second_pass = median_cut_pass2_fs_dither_rgb;
4543           break;
4544         case GIMP_CONVERT_DITHER_FS_LOWBLEED:
4545           quantobj->error_freedom = 1;
4546           quantobj->second_pass_init = median_cut_pass2_rgb_init;
4547           quantobj->second_pass = median_cut_pass2_fs_dither_rgb;
4548           break;
4549         case GIMP_CONVERT_DITHER_NODESTRUCT:
4550           quantobj->second_pass_init = NULL;
4551           quantobj->second_pass = median_cut_pass2_nodestruct_dither_rgb;
4552           break;
4553         case GIMP_CONVERT_DITHER_FIXED:
4554           quantobj->second_pass_init = median_cut_pass2_rgb_init;
4555           quantobj->second_pass = median_cut_pass2_fixed_dither_rgb;
4556           break;
4557         }
4558       break;
4559 
4560     default:
4561       break;
4562     }
4563 
4564   quantobj->delete_func = delete_median_cut;
4565 
4566   return quantobj;
4567 }
4568