]> git.imager.perl.org - imager.git/blob - quant.c
9d3abc50cdc9ebf3d52faf6c644d663b0cb8d90b
[imager.git] / quant.c
1 /* quant.c - provides general image quantization
2    currently only used by gif.c, but maybe we'll support producing 
3    8-bit (or bigger indexed) png files at some point
4 */
5 #include "imager.h"
6
7 static void makemap_addi(i_quantize *, i_img **imgs, int count);
8 static void makemap_mediancut(i_quantize *, i_img **imgs, int count);
9
10 static
11 void
12 setcol(i_color *cl,unsigned char r,unsigned char g,unsigned char b,unsigned char a) {
13   cl->rgba.r=r;
14   cl->rgba.g=g;
15   cl->rgba.b=b;
16   cl->rgba.a=a;
17 }
18
19
20
21 /* make a colour map overwrites mc_existing/mc_count in quant Note
22    that i_makemap will be called once for each image if mc_perimage is
23    set and the format support multiple colour maps per image.
24
25    This means we don't need any special processing at this level to
26    handle multiple colour maps.
27 */
28
29 /*
30 =item i_quant_makemap(quant, imgs, count)
31
32 =category Image quantization
33
34 Analyzes the I<count> images in I<imgs> according to the rules in
35 I<quant> to build a color map (optimal or not depending on
36 quant->make_colors).
37
38 =cut
39 */
40
41 void
42 i_quant_makemap(i_quantize *quant, i_img **imgs, int count) {
43
44   if (quant->translate == pt_giflib) {
45     /* giflib does it's own color table generation */
46     /* previously we used giflib's quantizer, but it didn't handle multiple
47        images, which made it hard to build a global color map
48        We've implemented our own median cut code so we can ignore 
49        the giflib version */
50     makemap_mediancut(quant, imgs, count);
51     return;
52   }
53
54   switch (quant->make_colors & mc_mask) {
55   case mc_none:
56     /* use user's specified map */
57     break;
58   case mc_web_map:
59     {
60       int r, g, b;
61       int i = 0;
62       for (r = 0; r < 256; r+=0x33)
63         for (g = 0; g < 256; g+=0x33)
64           for (b = 0; b < 256; b += 0x33)
65             setcol(quant->mc_colors+i++, r, g, b, 255);
66       quant->mc_count = i;
67     }
68     break;
69
70   case mc_median_cut:
71     makemap_mediancut(quant, imgs, count);
72     break;
73
74   case mc_addi:
75   default:
76     makemap_addi(quant, imgs, count);
77     break;
78   }
79 }
80
81 static void translate_closest(i_quantize *, i_img *, i_palidx *);
82 static void translate_errdiff(i_quantize *, i_img *, i_palidx *);
83 static void translate_addi(i_quantize *, i_img *, i_palidx *);
84
85 /*
86 =item i_quant_translate(quant, img)
87
88 =category Image quantization
89
90 Quantize the image given the palette in quant.
91
92 On success returns a pointer to a memory block of img->xsize *
93 img->ysize i_palidx entries.
94
95 On failure returns NULL.
96
97 You should call myfree() on the returned block when you're done with
98 it.
99
100 This function will fail if the supplied palette contains no colors.
101
102 =cut
103 */
104 i_palidx *
105 i_quant_translate(i_quantize *quant, i_img *img) {
106   i_palidx *result;
107   int bytes;
108
109   mm_log((1, "quant_translate(quant %p, img %p)\n", quant, img));
110
111   /* there must be at least one color in the paletted (though even that
112      isn't very useful */
113   if (quant->mc_count == 0) {
114     i_push_error(0, "no colors available for translation");
115     return NULL;
116   }
117
118   bytes = img->xsize * img->ysize;
119   if (bytes / img->ysize != img->xsize) {
120     i_push_error(0, "integer overflow calculating memory allocation");
121     return NULL;
122   }
123   result = mymalloc(bytes);
124
125   switch (quant->translate) {
126   case pt_closest:
127   case pt_giflib:
128     translate_closest(quant, img, result);
129     break;
130     
131   case pt_errdiff:
132     translate_errdiff(quant, img, result);
133     break;
134     
135   case pt_perturb:
136   default:
137     translate_addi(quant, img, result);
138     break;
139   }
140   
141   return result;
142 }
143
144 static void translate_closest(i_quantize *quant, i_img *img, i_palidx *out) {
145   quant->perturb = 0;
146   translate_addi(quant, img, out);
147 }
148
149 #define PWR2(x) ((x)*(x))
150
151 typedef int (*cmpfunc)(const void*, const void*);
152
153 typedef struct {
154   unsigned char r,g,b;
155   char fixed;
156   char used;
157   int dr,dg,db;
158   int cdist;
159   int mcount;
160 } cvec;
161
162 typedef struct {
163   int cnt;
164   int vec[256];
165 } hashbox;
166
167 typedef struct {
168   int boxnum;
169   int pixcnt;
170   int cand;
171   int pdc;
172 } pbox;
173
174 static void prescan(i_img **im,int count, int cnum, cvec *clr, i_sample_t *line);
175 static void reorder(pbox prescan[512]);
176 static int pboxcmp(const pbox *a,const pbox *b);
177 static void boxcenter(int box,cvec *cv);
178 static float frandn(void);
179 static void boxrand(int box,cvec *cv);
180 static void bbox(int box,int *r0,int *r1,int *g0,int *g1,int *b0,int *b1);
181 static void cr_hashindex(cvec clr[256],int cnum,hashbox hb[512]);
182 static int mindist(int boxnum,cvec *cv);
183 static int maxdist(int boxnum,cvec *cv);
184
185 /* Some of the simpler functions are kept here to aid the compiler -
186    maybe some of them will be inlined. */
187
188 static int
189 pixbox(i_color *ic) { return ((ic->channel[0] & 224)<<1)+ ((ic->channel[1]&224)>>2) + ((ic->channel[2] &224) >> 5); }
190
191 static int
192 pixbox_ch(i_sample_t *chans) { return ((chans[0] & 224)<<1)+ ((chans[1]&224)>>2) + ((chans[2] &224) >> 5); }
193
194 static unsigned char
195 g_sat(int in) {
196   if (in>255) { return 255; }
197   else if (in>0) return in;
198   return 0;
199 }
200
201 static
202 float
203 frand(void) {
204   return rand()/(RAND_MAX+1.0);
205 }
206
207 #ifdef NOTEF
208 static
209 int
210 eucl_d(cvec* cv,i_color *cl) { return PWR2(cv->r-cl->channel[0])+PWR2(cv->g-cl->channel[1])+PWR2(cv->b-cl->channel[2]); }
211 #endif
212
213 static
214 int
215 eucl_d_ch(cvec* cv,i_sample_t *chans) { 
216   return PWR2(cv->r - chans[0]) + PWR2(cv->g - chans[1]) 
217     + PWR2(cv->b - chans[2]);
218 }
219
220 static
221 int
222 ceucl_d(i_color *c1, i_color *c2) { return PWR2(c1->channel[0]-c2->channel[0])+PWR2(c1->channel[1]-c2->channel[1])+PWR2(c1->channel[2]-c2->channel[2]); }
223
224 static const int
225 gray_samples[] = { 0, 0, 0 };
226
227 /* 
228
229 This quantization algorithm and implementation routines are by Arnar
230 M. Hrafnkelson. In case any new ideas are here they are mine since
231 this was written from scratch.
232
233 The algorithm uses local means in the following way:
234
235    For each point in the colormap we find which image points
236    have that point as it's closest point. We calculate the mean
237    of those points and in the next iteration it will be the new
238    entry in the colormap.
239    
240 In order to speed this process up (i.e. nearest neighbor problem) We
241 divied the r,g,b space up in equally large 512 boxes.  The boxes are
242 numbered from 0 to 511. Their numbering is so that for a given vector
243 it is known that it belongs to the box who is formed by concatenating the
244 3 most significant bits from each component of the RGB triplet.
245
246 For each box we find the list of points from the colormap who might be
247 closest to any given point within the box.  The exact solution
248 involves finding the Voronoi map (or the dual the Delauny
249 triangulation) and has many issues including numerical stability.
250
251 So we use this approximation:
252
253 1. Find which point has the shortest maximum distance to the box.
254 2. Find all points that have a shorter minimum distance than that to the box
255
256 This is a very simple task and is not computationally heavy if one
257 takes into account that the minimum distances from a pixel to a box is
258 always found by checking if it's inside the box or is closest to some
259 side or a corner. Finding the maximum distance is also either a side
260 or a corner.
261
262 This approach results 2-3 times more than the actual points needed but
263 is still a good gain over the complete space.  Usually when one has a
264 256 Colorcolor map a search over 30 is often obtained.
265
266 A bit of an enhancement to this approach is to keep a seperate list
267 for each side of the cube, but this will require even more memory. 
268
269              Arnar M. Hrafnkelsson (addi@umich.edu);
270
271 */
272 /*
273   Extracted from gifquant.c, removed dependencies on gif_lib, 
274   and added support for multiple images.
275   starting from 1nov2000 by TonyC <tony@develop-help.com>.
276
277 */
278
279 static void
280 makemap_addi(i_quantize *quant, i_img **imgs, int count) {
281   cvec *clr;
282   int cnum, i, x, y, bst_idx=0, ld, cd, iter, currhb, img_num;
283   i_sample_t *val;
284   float dlt, accerr;
285   hashbox *hb;
286   i_mempool mp;
287   int maxwidth = 0;
288   i_sample_t *line;
289   const int *sample_indices;
290
291   mm_log((1, "makemap_addi(quant %p { mc_count=%d, mc_colors=%p }, imgs %p, count %d)\n", 
292           quant, quant->mc_count, quant->mc_colors, imgs, count));
293          
294   i_mempool_init(&mp);
295
296   clr = i_mempool_alloc(&mp, sizeof(cvec) * quant->mc_size);
297   hb = i_mempool_alloc(&mp, sizeof(hashbox) * 512);
298   for (i=0; i < quant->mc_count; ++i) {
299     clr[i].r = quant->mc_colors[i].rgb.r;
300     clr[i].g = quant->mc_colors[i].rgb.g;
301     clr[i].b = quant->mc_colors[i].rgb.b;
302     clr[i].fixed = 1;
303     clr[i].mcount = 0;
304   }
305   /* mymalloc doesn't clear memory, so I think we need this */
306   for (; i < quant->mc_size; ++i) {
307     /*clr[i].r = clr[i].g = clr[i].b = 0;*/
308     clr[i].dr = 0;
309     clr[i].dg = 0;
310     clr[i].db = 0;
311     clr[i].fixed = 0;
312     clr[i].mcount = 0;
313   }
314   cnum = quant->mc_size;
315   dlt = 1;
316
317   for (img_num = 0; img_num < count; ++img_num) {
318     if (imgs[img_num]->xsize > maxwidth)
319       maxwidth = imgs[img_num]->xsize;
320   }
321   line = i_mempool_alloc(&mp, 3 * maxwidth * sizeof(*line));
322
323   prescan(imgs, count, cnum, clr, line);
324   cr_hashindex(clr, cnum, hb);
325
326   for(iter=0;iter<3;iter++) {
327     accerr=0.0;
328     
329     for (img_num = 0; img_num < count; ++img_num) {
330       i_img *im = imgs[img_num];
331       sample_indices = im->channels >= 3 ? NULL : gray_samples;
332       for(y=0;y<im->ysize;y++) {
333         i_gsamp(im, 0, im->xsize, y, line, sample_indices, 3);
334         val = line;
335         for(x=0;x<im->xsize;x++) {
336           ld=196608;
337           /*i_gpix(im,x,y,&val);*/
338           currhb=pixbox_ch(val);
339           /*      printf("box = %d \n",currhb); */
340           for(i=0;i<hb[currhb].cnt;i++) { 
341             /*  printf("comparing: pix (%d,%d,%d) vec (%d,%d,%d)\n",val.channel[0],val.channel[1],val.channel[2],clr[hb[currhb].vec[i]].r,clr[hb[currhb].vec[i]].g,clr[hb[currhb].vec[i]].b); */
342             
343             cd=eucl_d_ch(&clr[hb[currhb].vec[i]],val);
344             if (cd<ld) {
345               ld=cd;     /* shortest distance yet */
346               bst_idx=hb[currhb].vec[i]; /* index of closest vector  yet */
347             }
348           }
349           
350           clr[bst_idx].mcount++;
351           accerr+=(ld);
352           clr[bst_idx].dr+=val[0];
353           clr[bst_idx].dg+=val[1];
354           clr[bst_idx].db+=val[2];
355           
356           val += 3; /* next 3 samples (next pixel) */
357         }
358       }
359     }
360     
361     for(i=0;i<cnum;i++) 
362       if (clr[i].mcount) { 
363         clr[i].dr/=clr[i].mcount; 
364         clr[i].dg/=clr[i].mcount; 
365         clr[i].db/=clr[i].mcount; 
366       }
367       
368     /*    for(i=0;i<cnum;i++) printf("vec(%d)=(%d,%d,%d) dest=(%d,%d,%d) matchcount=%d\n",
369           i,clr[i].r,clr[i].g,clr[i].b,clr[i].dr,clr[i].dg,clr[i].db,clr[i].mcount); */
370     
371     /*    printf("total error: %.2f\n",sqrt(accerr)); */
372     
373     for(i=0;i<cnum;i++) {
374       if (clr[i].fixed) continue; /* skip reserved colors */
375       
376       if (clr[i].mcount) {
377         clr[i].used = 1;
378         clr[i].r=clr[i].r*(1-dlt)+dlt*clr[i].dr;
379         clr[i].g=clr[i].g*(1-dlt)+dlt*clr[i].dg;
380         clr[i].b=clr[i].b*(1-dlt)+dlt*clr[i].db;
381       } else {
382         /* let's try something else */
383         clr[i].used = 0;
384         clr[i].r=rand();
385         clr[i].g=rand();
386         clr[i].b=rand();
387       }
388       
389       clr[i].dr=0;
390       clr[i].dg=0;
391       clr[i].db=0;
392       clr[i].mcount=0;
393     }
394     cr_hashindex(clr,cnum,hb);
395   }
396
397
398 #ifdef NOTEF
399   for(i=0;i<cnum;i++) { 
400     cd=eucl_d(&clr[i],&val);
401     if (cd<ld) {
402       ld=cd;
403       bst_idx=i;
404     }
405   }
406 #endif
407
408   /* if defined, we only include colours with an mcount or that were
409      supplied in the fixed palette, giving us a smaller output palette */
410 #define ONLY_USE_USED
411 #ifdef ONLY_USE_USED
412   /* transfer the colors back */
413   quant->mc_count = 0;
414   for (i = 0; i < cnum; ++i) {
415     if (clr[i].fixed || clr[i].used) {
416       /*printf("Adding %d (%d,%d,%d)\n", i, clr[i].r, clr[i].g, clr[i].b);*/
417       quant->mc_colors[quant->mc_count].rgb.r = clr[i].r;
418       quant->mc_colors[quant->mc_count].rgb.g = clr[i].g;
419       quant->mc_colors[quant->mc_count].rgb.b = clr[i].b;
420       ++quant->mc_count;
421     }
422   }
423 #else
424   /* transfer the colors back */
425   for (i = 0; i < cnum; ++i) {
426     quant->mc_colors[i].rgb.r = clr[i].r;
427     quant->mc_colors[i].rgb.g = clr[i].g;
428     quant->mc_colors[i].rgb.b = clr[i].b;
429   }
430   quant->mc_count = cnum;
431 #endif
432
433 #if 0
434   mm_log((1, "makemap_addi returns - quant.mc_count = %d\n", quant->mc_count));
435   for (i = 0; i < quant->mc_count; ++i)
436     mm_log((5, "  map entry %d: (%d, %d, %d)\n", i, clr[i].r, clr[i].g, clr[i].b));
437 #endif
438
439   i_mempool_destroy(&mp);
440 }
441
442 typedef struct {
443   i_sample_t rgb[3];
444   int count;
445 } quant_color_entry;
446
447 #define MEDIAN_CUT_COLORS 32768
448
449 #define MED_CUT_INDEX(c) ((((c).rgb.r & 0xF8) << 7) | \
450         (((c).rgb.g & 0xF8) << 2) | (((c).rgb.b & 0xF8) >> 3))
451
452 #define MED_CUT_GRAY_INDEX(c) ((((c).rgb.r & 0xF8) << 7) | \
453         (((c).rgb.r & 0xF8) << 2) | (((c).rgb.r & 0xF8) >> 3))
454
455 /* scale these to cover the whole range */
456 #define MED_CUT_RED(index) ((((index) & 0x7C00) >> 10) * 255 / 31)
457 #define MED_CUT_GREEN(index) ((((index) & 0x3E0) >> 5) * 255 / 31)
458 #define MED_CUT_BLUE(index) (((index) & 0x1F) * 255 / 31)
459
460 typedef struct {
461   i_sample_t min[3]; /* minimum for each channel */
462   i_sample_t max[3]; /* maximum for each channel */
463   i_sample_t width[3]; /* width for each channel */
464   int start, size;   /* beginning and size of the partition */
465   int pixels; /* number of pixels represented by this partition */
466 } medcut_partition;
467
468 /*
469 =item calc_part(part, colors)
470
471 Calculates the new color limits for the given partition.
472
473 Giflib assumes that the limits for the non-split channels stay the
474 same, but this strikes me as incorrect, especially if the colors tend
475 to be color ramps.
476
477 Of course this could be optimized by not recalculating the channel we
478 just sorted on, but it's not worth the effort right now.
479
480 =cut
481 */
482 static void calc_part(medcut_partition *part, quant_color_entry *colors) {
483   int i, ch;
484   
485   for (ch = 0; ch < 3; ++ch) {
486     part->min[ch] = 255;
487     part->max[ch] = 0;
488   }
489   for (i = part->start; i < part->start + part->size; ++i) {
490     for (ch = 0; ch < 3; ++ch) {
491       if (part->min[ch] > colors[i].rgb[ch])
492         part->min[ch] = colors[i].rgb[ch];
493       if (part->max[ch] < colors[i].rgb[ch])
494         part->max[ch] = colors[i].rgb[ch];
495     }
496   }
497   for (ch = 0; ch < 3; ++ch) {
498     part->width[ch] = part->max[ch] - part->min[ch];
499   }
500 }
501
502 /* simple functions to sort by each channel - we could use a global, but 
503    that would be bad */
504
505 static int
506 color_sort_red(void const *left, void const *right) {
507   return ((quant_color_entry *)left)->rgb[0] - ((quant_color_entry *)right)->rgb[0];
508 }
509
510 static int
511 color_sort_green(void const *left, void const *right) {
512   return ((quant_color_entry *)left)->rgb[1] - ((quant_color_entry *)right)->rgb[1];
513 }
514
515 static int
516 color_sort_blue(void const *left, void const *right) {
517   return ((quant_color_entry *)left)->rgb[2] - ((quant_color_entry *)right)->rgb[2];
518 }
519
520 static int (*sorters[])(void const *, void const *) =
521 {
522   color_sort_red,
523   color_sort_green,
524   color_sort_blue,
525 };
526
527 static void
528 makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
529   quant_color_entry *colors;
530   i_mempool mp;
531   int imgn, x, y, i, ch;
532   int max_width;
533   i_color *line;
534   int color_count;
535   int total_pixels;
536   medcut_partition *parts;
537   int part_num;
538   int in, out;
539   /* number of channels we search for the best channel to partition
540      this isn't terribly efficient, but it should work */
541   int chan_count; 
542
543   /*printf("images %d  pal size %d\n", count, quant->mc_size);*/
544
545   i_mempool_init(&mp);
546
547   colors = i_mempool_alloc(&mp, sizeof(*colors) * MEDIAN_CUT_COLORS);
548   for (i = 0; i < MEDIAN_CUT_COLORS; ++i) {
549     colors[i].rgb[0] = MED_CUT_RED(i);
550     colors[i].rgb[1] = MED_CUT_GREEN(i);
551     colors[i].rgb[2] = MED_CUT_BLUE(i);
552     colors[i].count = 0;
553   }
554
555   max_width = -1;
556   for (imgn = 0; imgn < count; ++imgn) {
557     if (imgs[imgn]->xsize > max_width)
558       max_width = imgs[imgn]->xsize;
559   }
560   line = i_mempool_alloc(&mp, sizeof(i_color) * max_width);
561
562   /* build the stats */
563   total_pixels = 0;
564   chan_count = 1; /* assume we just have grayscale */
565   for (imgn = 0; imgn < count; ++imgn) {
566     total_pixels += imgs[imgn]->xsize * imgs[imgn]->ysize;
567     for (y = 0; y < imgs[imgn]->ysize; ++y) {
568       i_glin(imgs[imgn], 0, imgs[imgn]->xsize, y, line);
569       if (imgs[imgn]->channels > 2) {
570         chan_count = 3;
571         for (x = 0; x < imgs[imgn]->xsize; ++x) {
572           ++colors[MED_CUT_INDEX(line[x])].count;
573         }
574       }
575       else {
576         /* a gray-scale image, just use the first channel */
577         for (x = 0; x < imgs[imgn]->xsize; ++x) {
578           ++colors[MED_CUT_GRAY_INDEX(line[x])].count;
579         }
580       }
581     }
582   }
583
584   /* eliminate the empty colors */
585   out = 0;
586   for (in = 0; in < MEDIAN_CUT_COLORS; ++in) {
587     if (colors[in].count) {
588       colors[out++] = colors[in];
589     }
590   }
591   /*printf("out %d\n", out);
592
593   for (i = 0; i < out; ++i) {
594     if (colors[i].count) {
595       printf("%d: (%d,%d,%d) -> %d\n", i, colors[i].rgb[0], colors[i].rgb[1], 
596              colors[i].rgb[2], colors[i].count);
597     }
598     }*/
599
600   if (out < quant->mc_size) {
601     /* just copy them into the color table */
602     for (i = 0; i < out; ++i) {
603       for (ch = 0; ch < 3; ++ch) {
604         quant->mc_colors[i].channel[ch] = colors[i].rgb[ch];
605       }
606     }
607     quant->mc_count = out;
608   }
609   else {
610     /* build the starting partition */
611     parts = i_mempool_alloc(&mp, sizeof(*parts) * quant->mc_size);
612     parts[0].start = 0;
613     parts[0].size = out;
614     parts[0].pixels = total_pixels;
615     calc_part(parts, colors);
616     color_count = 1;
617     
618     while (color_count < quant->mc_size) {
619       /* initialized to avoid compiler warnings */
620       int max_index = 0, max_ch = 0; /* index/channel with biggest spread */
621       int max_size;
622       medcut_partition *workpart;
623       int cum_total;
624       int half;
625       
626       /* find the partition with the most biggest span with more than 
627          one color */
628       max_size = -1;
629       for (i = 0; i < color_count; ++i) {
630         for (ch = 0; ch < chan_count; ++ch) {
631           if (parts[i].width[ch] > max_size 
632               && parts[i].size > 1) {
633             max_index = i;
634             max_ch = ch;
635             max_size = parts[i].width[ch];
636           }
637         }
638       }
639       
640       /* nothing else we can split */
641       if (max_size == -1)
642         break;
643       
644       workpart = parts+max_index;
645       /*printf("splitting partition %d (pixels %ld, start %d, size %d)\n", max_index, workpart->pixels, workpart->start, workpart->size);*/
646       qsort(colors + workpart->start, workpart->size, sizeof(*colors),
647             sorters[max_ch]);
648       
649       /* find the median or something like it we need to make sure both
650          sides of the split have at least one color in them, so we don't
651          test at the first or last entry */
652       i = workpart->start;
653       cum_total = colors[i].count;
654       ++i;
655       half = workpart->pixels / 2;
656       while (i < workpart->start + workpart->size - 1
657              && cum_total < half) {
658         cum_total += colors[i++].count;
659       }
660       /*printf("Split at %d to make %d (half %ld, cumtotal %ld)\n", i, color_count, half, cum_total);*/
661       
662       /* found the spot to split */
663       parts[color_count].start = i;
664       parts[color_count].size = workpart->start + workpart->size - i;
665       workpart->size = i - workpart->start;
666       parts[color_count].pixels = workpart->pixels - cum_total;
667       workpart->pixels = cum_total;
668       
669       /* recalculate the limits */
670       calc_part(workpart, colors);
671       calc_part(parts+color_count, colors);
672       ++color_count;
673     }
674     
675     /* fill in the color table - since we could still have partitions
676        that have more than one color, we need to average the colors */
677     for (part_num = 0; part_num < color_count; ++part_num) {
678       long sums[3];
679       medcut_partition *workpart;
680       
681       workpart = parts+part_num;
682       for (ch = 0; ch < 3; ++ch)
683         sums[ch] = 0;
684       
685       for (i = workpart->start; i < workpart->start + workpart->size; ++i) {
686         for (ch = 0; ch < 3; ++ch) {
687           sums[ch] += colors[i].rgb[ch] * colors[i].count;
688         }
689       }
690       for (ch = 0; ch < 3; ++ch) {
691         quant->mc_colors[part_num].channel[ch] = sums[ch] / workpart->pixels;
692       }
693     }
694     quant->mc_count = color_count;
695   }
696   /*printf("out %d colors\n", quant->mc_count);*/
697   i_mempool_destroy(&mp);
698 }
699
700 #define pboxjump 32
701
702 /* Define one of the following 4 symbols to choose a colour search method
703    The idea is to try these out, including benchmarking, to see which
704    is fastest in a good spread of circumstances.
705    I'd expect IM_CFLINSEARCH to be fastest for very small palettes, and
706    IM_CFHASHBOX for large images with large palettes.
707
708    Some other possibilities include:
709     - search over entries sorted by luminance
710
711    Initially I was planning on testing using the macros and then
712    integrating the code directly into each function, but this means if
713    we find a bug at a late stage we will need to update N copies of
714    the same code.  Also, keeping the code in the macros means that the
715    code in the translation functions is much more to the point,
716    there's no distracting colour search code to remove attention from
717    what makes _this_ translation function different.  It may be
718    advisable to move the setup code into functions at some point, but
719    it should be possible to do this fairly transparently.
720
721    If IM_CF_COPTS is defined then CFLAGS must have an appropriate 
722    definition.
723
724    Each option needs to define 4 macros:
725     CF_VARS - variables to define in the function
726     CF_SETUP - code to setup for the colour search, eg. allocating and
727       initializing lookup tables
728     CF_FIND - code that looks for the color in val and puts the best 
729       matching index in bst_idx
730     CF_CLEANUP - code to clean up, eg. releasing memory
731 */
732 #ifndef IM_CF_COPTS
733 /*#define IM_CFLINSEARCH*/
734 #define IM_CFHASHBOX
735 /*#define IM_CFSORTCHAN*/
736 /*#define IM_CFRAND2DIST*/
737 #endif
738
739 #ifdef IM_CFHASHBOX
740
741 /* The original version I wrote for this used the sort.
742    If this is defined then we use a sort to extract the indices for 
743    the hashbox */
744 #define HB_SORT
745
746 /* assume i is available */
747 #define CF_VARS hashbox *hb = mymalloc(sizeof(hashbox) * 512); \
748                int currhb;  \
749                long ld, cd
750
751 #ifdef HB_SORT
752
753 static long *gdists; /* qsort is annoying */
754 /* int might be smaller than long, so we need to do a real compare 
755    rather than a subtraction*/
756 static int distcomp(void const *a, void const *b) {
757   long ra = gdists[*(int const *)a];
758   long rb = gdists[*(int const *)b];
759   if (ra < rb)
760     return -1;
761   else if (ra > rb)
762     return 1;
763   else
764     return 0;
765 }
766
767 #endif
768
769 /* for each hashbox build a list of colours that are in the hb or is closer
770    than other colours
771    This is pretty involved.  The original gifquant generated the hashbox
772    as part of it's normal processing, but since the map generation is now 
773    separated from the translation we need to do this on the spot.
774    Any optimizations, even if they don't produce perfect results would be
775    welcome.
776  */
777 static void hbsetup(i_quantize *quant, hashbox *hb) {
778   long *dists, mind, maxd;
779   int cr, cb, cg, hbnum, i;
780   i_color cenc;
781 #ifdef HB_SORT
782   int *indices = mymalloc(quant->mc_count * sizeof(int)); 
783 #endif
784
785   dists = mymalloc(quant->mc_count * sizeof(long)); 
786   for (cr = 0; cr < 8; ++cr) { 
787     for (cg = 0; cg < 8; ++cg) { 
788       for (cb = 0; cb < 8; ++cb) { 
789         /* centre of the hashbox */ 
790         cenc.channel[0] = cr*pboxjump+pboxjump/2; 
791         cenc.channel[1] = cg*pboxjump+pboxjump/2; 
792         cenc.channel[2] = cb*pboxjump+pboxjump/2; 
793         hbnum = pixbox(&cenc); 
794         hb[hbnum].cnt = 0; 
795         /* order indices in the order of distance from the hashbox */ 
796         for (i = 0; i < quant->mc_count; ++i) { 
797 #ifdef HB_SORT
798           indices[i] = i; 
799 #endif
800           dists[i] = ceucl_d(&cenc, quant->mc_colors+i); 
801         } 
802 #ifdef HB_SORT
803         /* it should be possible to do this without a sort 
804            but so far I'm too lazy */
805         gdists = dists; 
806         qsort(indices, quant->mc_count, sizeof(int), distcomp); 
807         /* any colors that can match are within mind+diagonal size of 
808            a hashbox */ 
809         mind = dists[indices[0]]; 
810         i = 0; 
811         maxd = (sqrt(mind)+pboxjump)*(sqrt(mind)+pboxjump);
812         while (i < quant->mc_count && dists[indices[i]] < maxd) { 
813           hb[hbnum].vec[hb[hbnum].cnt++] = indices[i++]; 
814         } 
815 #else
816         /* work out the minimum */
817         mind = 256*256*3;
818         for (i = 0; i < quant->mc_count; ++i) {
819           if (dists[i] < mind) mind = dists[i];
820         }
821         /* transfer any colours that might be closest to a colour in 
822            this hashbox */
823         maxd = (sqrt(mind)+pboxjump)*(sqrt(mind)+pboxjump);
824         for (i = 0; i < quant->mc_count; ++i) {
825           if (dists[i] < maxd)
826             hb[hbnum].vec[hb[hbnum].cnt++] = i;
827         }
828 #endif
829       } 
830     } 
831   }
832 #ifdef HB_SORT
833   myfree(indices); 
834 #endif
835   myfree(dists) ;
836 }
837 #define CF_SETUP hbsetup(quant, hb)
838
839 #define CF_FIND \
840   currhb = pixbox(&val); \
841   ld = 196608; \
842   for (i = 0; i < hb[currhb].cnt; ++i) { \
843     cd = ceucl_d(quant->mc_colors+hb[currhb].vec[i], &val); \
844     if (cd < ld) { ld = cd; bst_idx = hb[currhb].vec[i]; } \
845   }
846
847 #define CF_CLEANUP myfree(hb)
848   
849 #endif
850
851 #ifdef IM_CFLINSEARCH
852 /* as simple as it gets */
853 #define CF_VARS long ld, cd
854 #define CF_SETUP /* none needed */
855 #define CF_FIND \
856    ld = 196608; \
857    for (i = 0; i < quant->mc_count; ++i) { \
858      cd = ceucl_d(quant->mc_colors+i, &val); \
859      if (cd < ld) { ld = cd; bst_idx = i; } \
860    }
861 #define CF_CLEANUP
862 #endif
863
864 #ifdef IM_CFSORTCHAN
865 static int gsortchan;
866 static i_quantize *gquant;
867 static int chansort(void const *a, void const *b) {
868   return gquant->mc_colors[*(int const *)a].channel[gsortchan] -
869     gquant->mc_colors[*(int const *)b].channel[gsortchan];
870 }
871 #define CF_VARS int *indices, sortchan, diff; \
872                 long ld, cd; \
873                 int vindex[256] /* where to find value i of chan */
874
875 static void chansetup(i_img *img, i_quantize *quant, int *csortchan, 
876                       int *vindex, int **cindices) {
877   int *indices, sortchan, chan, i, chval;
878   int chanmins[MAXCHANNELS], chanmaxs[MAXCHANNELS], maxrange;
879
880   /* find the channel with the maximum range */ 
881   /* the maximum stddev would probably be better */
882   for (chan = 0; chan < img->channels; ++chan) { 
883     chanmins[chan] = 256; chanmaxs[chan] = 0; 
884     for (i = 0; i < quant->mc_count; ++i) { 
885       if (quant->mc_colors[i].channel[chan] < chanmins[chan]) 
886         chanmins[chan] = quant->mc_colors[i].channel[chan]; 
887       if (quant->mc_colors[i].channel[chan] > chanmaxs[chan]) 
888         chanmaxs[chan] = quant->mc_colors[i].channel[chan]; 
889     } 
890   } 
891   maxrange = -1; 
892   for (chan = 0; chan < img->channels; ++chan) { 
893     if (chanmaxs[chan]-chanmins[chan] > maxrange) { 
894       maxrange = chanmaxs[chan]-chanmins[chan]; 
895       sortchan = chan; 
896     } 
897   } 
898   indices = mymalloc(quant->mc_count * sizeof(int)) ;
899   for (i = 0; i < quant->mc_count; ++i) { 
900     indices[i] = i; 
901   } 
902   gsortchan = sortchan; 
903   gquant = quant; 
904   qsort(indices, quant->mc_count, sizeof(int), chansort) ;
905   /* now a lookup table to find entries faster */ 
906   for (chval=0, i=0; i < quant->mc_count; ++i) { 
907     while (chval < 256 && 
908            chval < quant->mc_colors[indices[i]].channel[sortchan]) { 
909       vindex[chval++] = i; 
910     } 
911   } 
912   while (chval < 256) { 
913     vindex[chval++] = quant->mc_count-1; 
914   }
915   *csortchan = sortchan;
916   *cindices = indices;
917 }
918
919 #define CF_SETUP \
920   chansetup(img, quant, &sortchan, vindex, &indices)
921
922 int chanfind(i_color val, i_quantize *quant, int *indices, int *vindex, 
923              int sortchan) {
924   int i, bst_idx, diff, maxdiff;
925   long ld, cd;
926
927   i = vindex[val.channel[sortchan]];
928   bst_idx = indices[i];
929   ld = 196608;
930   diff = 0;
931   maxdiff = quant->mc_count;
932   while (diff < maxdiff) {
933     if (i+diff < quant->mc_count) {
934       cd = ceucl_d(&val, quant->mc_colors+indices[i+diff]); 
935       if (cd < ld) {
936         bst_idx = indices[i+diff];
937         ld = cd;
938         maxdiff = sqrt(ld);
939       }
940     }
941     if (i-diff >= 0) {
942       cd = ceucl_d(&val, quant->mc_colors+indices[i-diff]); 
943       if (cd < ld) {
944         bst_idx = indices[i-diff];
945         ld = cd;
946         maxdiff = sqrt(ld);
947       }
948     }
949     ++diff;
950   }
951
952   return bst_idx;
953 }
954
955 #define CF_FIND \
956   bst_idx = chanfind(val, quant, indices, vindex, sortchan)
957   
958
959 #define CF_CLEANUP myfree(indices)
960
961 #endif
962
963 #ifdef IM_CFRAND2DIST
964
965 /* This is based on a method described by Addi in the #imager channel 
966    on the 28/2/2001.  I was about 1am Sydney time at the time, so I 
967    wasn't at my most cogent.  Well, that's my excuse :)
968
969 <TonyC> what I have at the moment is: hashboxes, with optimum hash box
970 filling; simple linear search; and a lookup in the widest channel
971 (currently the channel with the maximum range)
972 <Addi> There is one more way that might be simple to implement.
973 <Addi> You want to hear?
974 <TonyC> what's that?
975 <purl> somebody said that was not true
976 <Addi> For each of the colors in the palette start by creating a
977 sorted list of the form:
978 <Addi> [distance, color]
979 <Addi> Where they are sorted by distance.
980 <TonyC> distance to where?
981 <Addi> Where the elements in the lists are the distances and colors of
982 the other colors in the palette
983 <TonyC> ok
984 <Addi> So if you are at color 0
985 <Addi> ok - now to search for the closest color when you are creating
986 the final image is done like this:
987 <Addi> a) pick a random color from the palette
988 <Addi> b) calculate the distance to it
989 <Addi> c) only check the vectors that are within double the distance
990 in the list of the color you picked from the palette.
991 <Addi> Does that seem logical?
992 <Addi> Lets imagine that we only have grayscale to make an example:
993 <Addi> Our palette has 1 4 10 20 as colors.
994 <Addi> And we want to quantize the color 11
995 <Addi> lets say we picked 10 randomly
996 <Addi> the double distance is 2
997 <Addi> since abs(10-11)*2 is 2
998 <Addi> And the list at vector 10 is this:
999 <Addi> [0, 10], [6 4], [9, 1], [10, 20]
1000 <Addi> so we look at the first one (but not the second one since 6 is
1001 at a greater distance than 2.
1002 <Addi> Any of that make sense?
1003 <TonyC> yes, though are you suggesting another random jump to one of
1004 the colours with the possible choices? or an exhaustive search?
1005 <Addi> TonyC: It's possible to come up with a recursive/iterative 
1006 enhancement but this is the 'basic' version.
1007 <Addi> Which would do an iterative search.
1008 <Addi> You can come up with conditions where it pays to switch to a new one.
1009 <Addi> And the 'random' start can be switched over to a small tree.
1010 <Addi> So you would have a little index at the start.
1011 <Addi> to get you into the general direction
1012 <Addi> Perhaps just an 8 split.
1013 <Addi> that is - split each dimension in half.
1014 <TonyC> yep
1015 <TonyC> I get the idea
1016 <Addi> But this would seem to be a good approach in our case since we 
1017 usually have few codevectors.
1018 <Addi> So we only need 256*256 entries in a table.
1019 <Addi> We could even only index some of them that were deemed as good 
1020 candidates.
1021 <TonyC> I was considering adding paletted output support for PNG and 
1022 TIFF at some point, which support 16-bit palettes
1023 <Addi> ohh.
1024 <Addi> 'darn' ;)
1025
1026
1027 */
1028
1029
1030 typedef struct i_dists {
1031   int index;
1032   long dist;
1033 } i_dists;
1034
1035 #define CF_VARS \
1036     i_dists *dists;
1037
1038 static int dists_sort(void const *a, void const *b) {
1039   return ((i_dists *)a)->dist - ((i_dists *)b)->dist;
1040 }
1041
1042 static void rand2dist_setup(i_quantize *quant, i_dists **cdists) {
1043   i_dists *dists = 
1044     mymalloc(sizeof(i_dists)*quant->mc_count*quant->mc_count);
1045   int i, j;
1046   long cd;
1047   for (i = 0; i < quant->mc_count; ++i) {
1048     i_dists *ldists = dists + quant->mc_count * i;
1049     i_color val = quant->mc_colors[i];
1050     for (j = 0; j < quant->mc_count; ++j) {
1051       ldists[j].index = j;
1052       ldists[j].dist = ceucl_d(&val, quant->mc_colors+j);
1053     }
1054     qsort(ldists, quant->mc_count, sizeof(i_dists), dists_sort);
1055   }
1056   *cdists = dists;
1057 }
1058
1059 #define CF_SETUP \
1060                 bst_idx = rand() % quant->mc_count; \
1061                 rand2dist_setup(quant, &dists)
1062
1063 static int rand2dist_find(i_color val, i_quantize *quant, i_dists *dists, int index) {
1064   i_dists *cdists;
1065   long cd, ld;
1066   long maxld;
1067   int i;
1068   int bst_idx;
1069
1070   cdists = dists + index * quant->mc_count;
1071   ld = 3 * 256 * 256;
1072   maxld = 8 * ceucl_d(&val, quant->mc_colors+index);
1073   for (i = 0; i < quant->mc_count && cdists[i].dist <= maxld; ++i) {
1074     cd = ceucl_d(&val, quant->mc_colors+cdists[i].index);
1075     if (cd < ld) {
1076       bst_idx = cdists[i].index;
1077       ld = cd;
1078     }
1079   }
1080   return bst_idx;
1081 }
1082
1083 #define CF_FIND bst_idx = rand2dist_find(val, quant, dists, bst_idx)
1084
1085 #define CF_CLEANUP myfree(dists)
1086
1087
1088 #endif
1089
1090 static void translate_addi(i_quantize *quant, i_img *img, i_palidx *out) {
1091   int x, y, i, k, bst_idx = 0;
1092   i_color val;
1093   int pixdev = quant->perturb;
1094   CF_VARS;
1095
1096   CF_SETUP;
1097
1098   if (img->channels >= 3) {
1099     if (pixdev) {
1100       k=0;
1101       for(y=0;y<img->ysize;y++) for(x=0;x<img->xsize;x++) {
1102         i_gpix(img,x,y,&val);
1103         val.channel[0]=g_sat(val.channel[0]+(int)(pixdev*frandn()));
1104         val.channel[1]=g_sat(val.channel[1]+(int)(pixdev*frandn()));
1105         val.channel[2]=g_sat(val.channel[2]+(int)(pixdev*frandn()));
1106         CF_FIND;
1107         out[k++]=bst_idx;
1108       }
1109     } else {
1110       k=0;
1111       for(y=0;y<img->ysize;y++) for(x=0;x<img->xsize;x++) {
1112         i_gpix(img,x,y,&val);
1113         CF_FIND;
1114         out[k++]=bst_idx;
1115       }
1116     }
1117   }
1118   else {
1119     if (pixdev) {
1120       k=0;
1121       for(y=0;y<img->ysize;y++) for(x=0;x<img->xsize;x++) {
1122         i_gpix(img,x,y,&val);
1123         val.channel[1] = val.channel[2] =
1124           val.channel[0]=g_sat(val.channel[0]+(int)(pixdev*frandn()));
1125         CF_FIND;
1126         out[k++]=bst_idx;
1127       }
1128     } else {
1129       k=0;
1130       for(y=0;y<img->ysize;y++) for(x=0;x<img->xsize;x++) {
1131         i_gpix(img,x,y,&val);
1132         val.channel[1] = val.channel[2] = val.channel[0];
1133         CF_FIND;
1134         out[k++]=bst_idx;
1135       }
1136     }
1137   }
1138   CF_CLEANUP;
1139 }
1140
1141 static int floyd_map[] =
1142 {
1143   0, 0, 7,
1144   3, 5, 1
1145 };
1146
1147 static int jarvis_map[] =
1148 {
1149   0, 0, 0, 7, 5,
1150   3, 5, 7, 5, 3,
1151   1, 3, 5, 3, 1
1152 };
1153
1154 static int stucki_map[] =
1155 {
1156   0, 0, 0, 8, 4,
1157   2, 4, 8, 4, 2,
1158   1, 2, 4, 2, 1
1159 };
1160
1161 struct errdiff_map {
1162   int *map;
1163   int width, height, orig;
1164 };
1165
1166 static struct errdiff_map maps[] =
1167 {
1168   { floyd_map, 3, 2, 1 },
1169   { jarvis_map, 5, 3, 2 },
1170   { stucki_map, 5, 3, 2 },
1171 };
1172
1173 typedef struct errdiff_tag {
1174   int r, g, b;
1175 } errdiff_t;
1176
1177 /* perform an error diffusion dither */
1178 static
1179 void
1180 translate_errdiff(i_quantize *quant, i_img *img, i_palidx *out) {
1181   int *map;
1182   int mapw, maph, mapo;
1183   int i;
1184   errdiff_t *err;
1185   int errw;
1186   int difftotal;
1187   int x, y, dx, dy;
1188   int bst_idx = 0;
1189   CF_VARS;
1190
1191   if ((quant->errdiff & ed_mask) == ed_custom) {
1192     map = quant->ed_map;
1193     mapw = quant->ed_width;
1194     maph = quant->ed_height;
1195     mapo = quant->ed_orig;
1196   }
1197   else {
1198     int index = quant->errdiff & ed_mask;
1199     if (index >= ed_custom) index = ed_floyd;
1200     map = maps[index].map;
1201     mapw = maps[index].width;
1202     maph = maps[index].height;
1203     mapo = maps[index].orig;
1204   }
1205   
1206   errw = img->xsize+mapw;
1207   err = mymalloc(sizeof(*err) * maph * errw);
1208   /*errp = err+mapo;*/
1209   memset(err, 0, sizeof(*err) * maph * errw);
1210   
1211   difftotal = 0;
1212   for (i = 0; i < maph * mapw; ++i)
1213     difftotal += map[i];
1214   /*printf("map:\n");
1215  for (dy = 0; dy < maph; ++dy) {
1216    for (dx = 0; dx < mapw; ++dx) {
1217      printf("%2d", map[dx+dy*mapw]);
1218    }
1219    putchar('\n');
1220    }*/
1221
1222   CF_SETUP;
1223
1224   for (y = 0; y < img->ysize; ++y) {
1225     for (x = 0; x < img->xsize; ++x) {
1226       i_color val;
1227       long ld, cd;
1228       errdiff_t perr;
1229       i_gpix(img, x, y, &val);
1230       if (img->channels < 3) {
1231         val.channel[1] = val.channel[2] = val.channel[0];
1232       }
1233       perr = err[x+mapo];
1234       perr.r = perr.r < 0 ? -((-perr.r)/difftotal) : perr.r/difftotal;
1235       perr.g = perr.g < 0 ? -((-perr.g)/difftotal) : perr.g/difftotal;
1236       perr.b = perr.b < 0 ? -((-perr.b)/difftotal) : perr.b/difftotal;
1237       /*printf("x %3d y %3d in(%3d, %3d, %3d) di(%4d,%4d,%4d)\n", x, y, val.channel[0], val.channel[1], val.channel[2], perr.r, perr.g, perr.b);*/
1238       val.channel[0] = g_sat(val.channel[0]-perr.r);
1239       val.channel[1] = g_sat(val.channel[1]-perr.g);
1240       val.channel[2] = g_sat(val.channel[2]-perr.b);
1241       CF_FIND;
1242       /* save error */
1243       perr.r = quant->mc_colors[bst_idx].channel[0] - val.channel[0];
1244       perr.g = quant->mc_colors[bst_idx].channel[1] - val.channel[1];
1245       perr.b = quant->mc_colors[bst_idx].channel[2] - val.channel[2];
1246       /*printf("           out(%3d, %3d, %3d) er(%4d, %4d, %4d)\n", quant->mc_colors[bst_idx].channel[0], quant->mc_colors[bst_idx].channel[1], quant->mc_colors[bst_idx].channel[2], perr.r, perr.g, perr.b);*/
1247       for (dx = 0; dx < mapw; ++dx) {
1248         for (dy = 0; dy < maph; ++dy) {
1249           err[x+dx+dy*errw].r += perr.r * map[dx+mapw*dy];
1250           err[x+dx+dy*errw].g += perr.g * map[dx+mapw*dy];
1251           err[x+dx+dy*errw].b += perr.b * map[dx+mapw*dy];
1252         }
1253       }
1254       *out++ = bst_idx;
1255     }
1256     /* shift up the error matrix */
1257     for (dy = 0; dy < maph-1; ++dy) {
1258       memcpy(err+dy*errw, err+(dy+1)*errw, sizeof(*err)*errw);
1259     }
1260     memset(err+(maph-1)*errw, 0, sizeof(*err)*errw);
1261   }
1262   CF_CLEANUP;
1263   myfree(err);
1264 }
1265 /* Prescan finds the boxes in the image that have the highest number of colors 
1266    and that result is used as the initial value for the vectores */
1267
1268
1269 static void prescan(i_img **imgs,int count, int cnum, cvec *clr, i_sample_t *line) {
1270   int i,k,j,x,y;
1271   i_sample_t *val;
1272   const int *chans;
1273
1274   pbox prebox[512];
1275   for(i=0;i<512;i++) {
1276     prebox[i].boxnum=i;
1277     prebox[i].pixcnt=0;
1278     prebox[i].cand=1;
1279   }
1280
1281   /* process each image */
1282   for (i = 0; i < count; ++i) {
1283     i_img *im = imgs[i];
1284     chans = im->channels >= 3 ? NULL : gray_samples;
1285     for(y=0;y<im->ysize;y++) {
1286       i_gsamp(im, 0, im->xsize, y, line, chans, 3);
1287       val = line;
1288       for(x=0;x<im->xsize;x++) {
1289         prebox[pixbox_ch(val)].pixcnt++;
1290       }
1291     }
1292   }
1293
1294   for(i=0;i<512;i++) prebox[i].pdc=prebox[i].pixcnt;
1295   qsort(prebox,512,sizeof(pbox),(cmpfunc)pboxcmp);
1296
1297   for(i=0;i<cnum;i++) {
1298     /*      printf("Color %d\n",i); 
1299             for(k=0;k<10;k++) { printf("box=%03d %04d %d %04d \n",prebox[k].boxnum,prebox[k].pixcnt,prebox[k].cand,prebox[k].pdc); } 
1300             printf("\n\n"); */
1301     reorder(prebox);
1302   }
1303   
1304   /*    for(k=0;k<cnum;k++) { printf("box=%03d %04d %d %04d \n",prebox[k].boxnum,prebox[k].pixcnt,prebox[k].cand,prebox[k].pdc); } */
1305   
1306   k=0;
1307   j=1;
1308   i=0;
1309   while(i<cnum) {
1310     /*    printf("prebox[%d].cand=%d\n",k,prebox[k].cand); */
1311     if (clr[i].fixed) { i++; continue; } /* reserved go to next */
1312     if (j>=prebox[k].cand) { k++; j=1; } else {
1313       if (prebox[k].cand == 2) boxcenter(prebox[k].boxnum,&(clr[i]));
1314       else boxrand(prebox[k].boxnum,&(clr[i]));
1315       /*      printf("(%d,%d) %d %d -> (%d,%d,%d)\n",k,j,prebox[k].boxnum,prebox[k].pixcnt,clr[i].r,clr[i].g,clr[i].b); */
1316       j++;
1317       i++;
1318     }
1319   }
1320 }
1321   
1322
1323 static void reorder(pbox prescan[512]) {
1324   int nidx;
1325   pbox c;
1326
1327   nidx=0;
1328   c=prescan[0];
1329   
1330   c.cand++;
1331   c.pdc=c.pixcnt/(c.cand*c.cand); 
1332   /*  c.pdc=c.pixcnt/c.cand; */
1333   while(c.pdc < prescan[nidx+1].pdc && nidx < 511) {
1334     prescan[nidx]=prescan[nidx+1];
1335     nidx++;
1336   }
1337   prescan[nidx]=c;
1338 }
1339
1340 static int
1341 pboxcmp(const pbox *a,const pbox *b) {
1342   if (a->pixcnt > b->pixcnt) return -1;
1343   if (a->pixcnt < b->pixcnt) return 1;
1344   return 0;
1345 }
1346
1347 static void
1348 boxcenter(int box,cvec *cv) {
1349   cv->r=15+((box&448)>>1);
1350   cv->g=15+((box&56)<<2);
1351   cv->b=15+((box&7)<<5);
1352 }
1353
1354 static void
1355 bbox(int box,int *r0,int *r1,int *g0,int *g1,int *b0,int *b1) {
1356   *r0=(box&448)>>1;
1357   *r1=(*r0)|31;
1358   *g0=(box&56)<<2;
1359   *g1=(*g0)|31;
1360   *b0=(box&7)<<5;
1361   *b1=(*b0)|31;
1362 }
1363
1364 static void
1365 boxrand(int box,cvec *cv) {
1366   cv->r=6+(rand()%25)+((box&448)>>1);
1367   cv->g=6+(rand()%25)+((box&56)<<2);
1368   cv->b=6+(rand()%25)+((box&7)<<5);
1369 }
1370
1371 static float
1372 frandn(void) {
1373
1374   float u1,u2,w;
1375   
1376   w=1;
1377   
1378   while (w >= 1 || w == 0) {
1379     u1 = 2 * frand() - 1;
1380     u2 = 2 * frand() - 1;
1381     w = u1*u1 + u2*u2;
1382   }
1383   
1384   w = sqrt((-2*log(w))/w);
1385   return u1*w;
1386 }
1387
1388 /* Create hash index */
1389 static
1390 void
1391 cr_hashindex(cvec clr[256],int cnum,hashbox hb[512]) {
1392   
1393   int bx,mind,cd,cumcnt,bst_idx,i;
1394 /*  printf("indexing... \n");*/
1395   
1396   cumcnt=0;
1397   for(bx=0; bx<512; bx++) {
1398     mind=196608;
1399     for(i=0; i<cnum; i++) { 
1400       cd = maxdist(bx,&clr[i]);
1401       if (cd < mind) { mind=cd; bst_idx=i; } 
1402     }
1403     
1404     hb[bx].cnt=0;
1405     for(i=0;i<cnum;i++) if (mindist(bx,&clr[i])<mind) hb[bx].vec[hb[bx].cnt++]=i;
1406     /*printf("box %d -> approx -> %d\n",bx,hb[bx].cnt); */
1407     /*  statbox(bx,cnum,clr); */
1408     cumcnt+=hb[bx].cnt;
1409   }
1410   
1411 /*  printf("Average search space: %d\n",cumcnt/512); */
1412 }
1413
1414 static int
1415 maxdist(int boxnum,cvec *cv) {
1416   int r0,r1,g0,g1,b0,b1;
1417   int r,g,b,mr,mg,mb;
1418
1419   r=cv->r;
1420   g=cv->g;
1421   b=cv->b;
1422   
1423   bbox(boxnum,&r0,&r1,&g0,&g1,&b0,&b1);
1424
1425   mr=i_max(abs(b-b0),abs(b-b1));
1426   mg=i_max(abs(g-g0),abs(g-g1));
1427   mb=i_max(abs(r-r0),abs(r-r1));
1428   
1429   return PWR2(mr)+PWR2(mg)+PWR2(mb);
1430 }
1431
1432 static int
1433 mindist(int boxnum,cvec *cv) {
1434   int r0,r1,g0,g1,b0,b1;
1435   int r,g,b,mr,mg,mb;
1436
1437   r=cv->r;
1438   g=cv->g;
1439   b=cv->b;
1440   
1441   bbox(boxnum,&r0,&r1,&g0,&g1,&b0,&b1);
1442
1443   /*  printf("box %d, (%d,%d,%d)-(%d,%d,%d) vec (%d,%d,%d) ",boxnum,r0,g0,b0,r1,g1,b1,r,g,b); */
1444
1445   if (r0<=r && r<=r1 && g0<=g && g<=g1 && b0<=b && b<=b1) return 0;
1446
1447   mr=i_min(abs(b-b0),abs(b-b1));
1448   mg=i_min(abs(g-g0),abs(g-g1));
1449   mb=i_min(abs(r-r0),abs(r-r1));
1450   
1451   mr=PWR2(mr);
1452   mg=PWR2(mg);
1453   mb=PWR2(mb);
1454
1455   if (r0<=r && r<=r1 && g0<=g && g<=g1) return mb;
1456   if (r0<=r && r<=r1 && b0<=b && b<=b1) return mg;
1457   if (b0<=b && b<=b1 && g0<=g && g<=g1) return mr;
1458
1459   if (r0<=r && r<=r1) return mg+mb;
1460   if (g0<=g && g<=g1) return mr+mb;
1461   if (b0<=b && b<=b1) return mg+mr;
1462
1463   return mr+mg+mb;
1464 }
1465
1466 static void transparent_threshold(i_quantize *, i_palidx *, i_img *, i_palidx);
1467 static void transparent_errdiff(i_quantize *, i_palidx *, i_img *, i_palidx);
1468 static void transparent_ordered(i_quantize *, i_palidx *, i_img *, i_palidx);
1469
1470 /*
1471 =item i_quant_transparent(quant, data, img, trans_index)
1472
1473 =category Image quantization
1474
1475 Dither the alpha channel on I<img> into the palette indexes in
1476 I<data>.  Pixels to be transparent are replaced with I<trans_pixel>.
1477
1478 The method used depends on the tr_* members of quant.
1479
1480 =cut
1481 */
1482
1483 void 
1484 i_quant_transparent(i_quantize *quant, i_palidx *data, i_img *img,
1485                        i_palidx trans_index)
1486 {
1487   switch (quant->transp) {
1488   case tr_none:
1489     break;
1490     
1491   default:
1492     quant->tr_threshold = 128;
1493     /* fall through */
1494   case tr_threshold:
1495     transparent_threshold(quant, data, img, trans_index);
1496     break;
1497     
1498   case tr_errdiff:
1499     transparent_errdiff(quant, data, img, trans_index);
1500     break;
1501
1502   case tr_ordered:
1503     transparent_ordered(quant, data, img, trans_index);
1504     break;
1505   }
1506 }
1507
1508 static void
1509 transparent_threshold(i_quantize *quant, i_palidx *data, i_img *img,
1510                       i_palidx trans_index)
1511 {
1512   int x, y;
1513   i_sample_t *line = mymalloc(img->xsize * sizeof(i_sample_t));
1514   int trans_chan = img->channels > 2 ? 3 : 1;
1515   
1516   for (y = 0; y < img->ysize; ++y) {
1517     i_gsamp(img, 0, img->xsize, y, line, &trans_chan, 1);
1518     for (x = 0; x < img->xsize; ++x) {
1519       if (line[x] < quant->tr_threshold)
1520         data[y*img->xsize+x] = trans_index;
1521     }
1522   }
1523   myfree(line);
1524 }
1525
1526 static void
1527 transparent_errdiff(i_quantize *quant, i_palidx *data, i_img *img,
1528                     i_palidx trans_index)
1529 {
1530   int *map;
1531   int index;
1532   int mapw, maph, mapo;
1533   int errw, *err, *errp;
1534   int difftotal, out, error;
1535   int x, y, dx, dy, i;
1536   i_sample_t *line;
1537   int trans_chan = img->channels > 2 ? 3 : 1;
1538
1539   /* no custom map for transparency (yet) */
1540   index = quant->tr_errdiff & ed_mask;
1541   if (index >= ed_custom) index = ed_floyd;
1542   map = maps[index].map;
1543   mapw = maps[index].width;
1544   maph = maps[index].height;
1545   mapo = maps[index].orig;
1546
1547   errw = img->xsize+mapw-1;
1548   err = mymalloc(sizeof(*err) * maph * errw);
1549   errp = err+mapo;
1550   memset(err, 0, sizeof(*err) * maph * errw);
1551
1552   line = mymalloc(img->xsize * sizeof(i_sample_t));
1553   difftotal = 0;
1554   for (i = 0; i < maph * mapw; ++i)
1555     difftotal += map[i];
1556   for (y = 0; y < img->ysize; ++y) {
1557     i_gsamp(img, 0, img->xsize, y, line, &trans_chan, 1);
1558     for (x = 0; x < img->xsize; ++x) {
1559       line[x] = g_sat(line[x]-errp[x]/difftotal);
1560       if (line[x] < 128) {
1561         out = 0;
1562         data[y*img->xsize+x] = trans_index;
1563       }
1564       else {
1565         out = 255;
1566       }
1567       error = out - line[x];
1568       for (dx = 0; dx < mapw; ++dx) {
1569         for (dy = 0; dy < maph; ++dy) {
1570           errp[x+dx-mapo+dy*errw] += error * map[dx+mapw*dy];
1571         }
1572       }
1573     }
1574     /* shift up the error matrix */
1575     for (dy = 0; dy < maph-1; ++dy)
1576       memcpy(err+dy*errw, err+(dy+1)*errw, sizeof(*err)*errw);
1577     memset(err+(maph-1)*errw, 0, sizeof(*err)*errw);
1578   }
1579   myfree(err);
1580   myfree(line);
1581 }
1582
1583 /* builtin ordered dither maps */
1584 static unsigned char 
1585 orddith_maps[][64] =
1586 {
1587   { /* random 
1588        this is purely random - it's pretty awful
1589      */
1590      48,  72, 196, 252, 180,  92, 108,  52,
1591     228, 176,  64,   8, 236,  40,  20, 164,
1592     120, 128,  84, 116,  24,  28, 172, 220,
1593      68,   0, 188, 124, 184, 224, 192, 104,
1594     132, 100, 240, 200, 152, 160, 244,  44,
1595      96, 204, 144,  16, 140,  56, 232, 216,
1596     208,   4,  76, 212, 136, 248,  80, 168,
1597     156,  88,  32, 112, 148,  12,  36,  60,
1598   },
1599   {
1600     /* dot8
1601        perl spot.perl '($x-3.5)*($x-3.5)+($y-3.5)*($y-3.5)'
1602      */
1603     240, 232, 200, 136, 140, 192, 228, 248,
1604     220, 148, 100,  76,  80, 104, 152, 212,
1605     180, 116,  56,  32,  36,  60, 120, 176,
1606     156,  64,  28,   0,   8,  44,  88, 160,
1607     128,  92,  24,  12,   4,  40,  68, 132,
1608     184,  96,  48,  20,  16,  52, 108, 188,
1609     216, 144, 112,  72,  84, 124, 164, 224,
1610     244, 236, 196, 168, 172, 204, 208, 252,
1611   },
1612   { /* dot4
1613        perl spot.perl \
1614        'min(dist(1.5, 1.5),dist(5.5,1.5),dist(1.5,5.5),dist(5.5,5.5))'  
1615     */
1616     196,  72, 104, 220, 200,  80, 112, 224,
1617      76,   4,  24, 136,  84,   8,  32, 144,
1618     108,  28,  52, 168, 116,  36,  56, 176,
1619     216, 140, 172, 244, 228, 148, 180, 248,
1620     204,  92, 124, 236, 192,  68,  96, 208,
1621      88,  12,  44, 156,  64,   0,  16, 128,
1622     120,  40,  60, 188, 100,  20,  48, 160,
1623     232, 152, 184, 252, 212, 132, 164, 240,
1624   },
1625   { /* hline 
1626        perl spot.perl '$y-3'
1627      */
1628     160, 164, 168, 172, 176, 180, 184, 188,
1629     128, 132, 136, 140, 144, 148, 152, 156,
1630      32,  36,  40,  44,  48,  52,  56,  60,
1631       0,   4,   8,  12,  16,  20,  24,  28,
1632      64,  68,  72,  76,  80,  84,  88,  92,
1633      96, 100, 104, 108, 112, 116, 120, 124,
1634     192, 196, 200, 204, 208, 212, 216, 220,
1635     224, 228, 232, 236, 240, 244, 248, 252,
1636   },
1637   { /* vline 
1638        perl spot.perl '$x-3'
1639      */
1640     180, 100,  40,  12,  44, 104, 184, 232,
1641     204, 148,  60,  16,  64, 128, 208, 224,
1642     212, 144,  76,   8,  80, 132, 216, 244,
1643     160, 112,  68,  20,  84, 108, 172, 236,
1644     176,  96,  72,  28,  88, 152, 188, 228,
1645     200, 124,  92,   0,  32, 116, 164, 240,
1646     168, 120,  36,  24,  48, 136, 192, 248,
1647     196, 140,  52,   4,  56, 156, 220, 252,
1648   },
1649   { /* slashline 
1650        perl spot.perl '$y+$x-7'  
1651     */
1652     248, 232, 224, 192, 140,  92,  52,  28,
1653     240, 220, 196, 144, 108,  60,  12,  64,
1654     216, 180, 148, 116,  76,  20,  80, 128,
1655     204, 152, 104,  44,  16,  72, 100, 160,
1656     164,  96,  68,  24,  56, 112, 168, 176,
1657     124,  40,   8,  36,  88, 136, 184, 212,
1658      84,   4,  32, 120, 156, 188, 228, 236,
1659       0,  48, 132, 172, 200, 208, 244, 252,
1660   },
1661   { /* backline 
1662        perl spot.perl '$y-$x'
1663      */
1664       0,  32, 116, 172, 184, 216, 236, 252,
1665      56,   8,  72, 132, 136, 200, 228, 240,
1666     100,  36,  12,  40,  92, 144, 204, 220,
1667     168, 120,  60,  16,  44,  96, 156, 176,
1668     180, 164, 112,  48,  28,  52, 128, 148,
1669     208, 192, 152,  88,  84,  20,  64, 104,
1670     232, 224, 196, 140, 108,  68,  24,  76,
1671     248, 244, 212, 188, 160, 124,  80,   4,
1672   },
1673   {
1674     /* tiny
1675        good for display, bad for print
1676        hand generated
1677     */
1678       0, 128,  32, 192,   8, 136,  40, 200,
1679     224,  64, 160, 112, 232,  72, 168, 120,
1680      48, 144,  16, 208,  56, 152,  24, 216,
1681     176,  96, 240,  80, 184, 104, 248,  88,
1682      12, 140,  44, 204,   4, 132,  36, 196,
1683     236,  76, 172, 124, 228,  68, 164, 116,
1684      60, 156,  28, 220,  52, 148,  20, 212,
1685     188, 108, 252,  92, 180, 100, 244,  84,
1686   },
1687 };
1688
1689 static void
1690 transparent_ordered(i_quantize *quant, i_palidx *data, i_img *img,
1691                     i_palidx trans_index)
1692 {
1693   unsigned char *spot;
1694   int x, y;
1695   i_sample_t *line;
1696   int trans_chan = img->channels > 2 ? 3 : 1;
1697   if (quant->tr_orddith == od_custom)
1698     spot = quant->tr_custom;
1699   else
1700     spot = orddith_maps[quant->tr_orddith];
1701
1702   line = mymalloc(img->xsize * sizeof(i_sample_t));
1703   for (y = 0; y < img->ysize; ++y) {
1704     i_gsamp(img, 0, img->xsize, y, line, &trans_chan, 1);
1705     for (x = 0; x < img->xsize; ++x) {
1706       if (line[x] < spot[(x&7)+(y&7)*8])
1707         data[x+y*img->xsize] = trans_index;
1708     }
1709   }
1710   myfree(line);
1711 }
1712