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