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