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