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