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