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