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