comparison src/imgproc.c @ 269:b2472a1930f2 r20-5b33

Import from CVS: tag r20-5b33
author cvs
date Mon, 13 Aug 2007 10:27:19 +0200
parents 966663fcf606
children c5d627a313b1
comparison
equal deleted inserted replaced
268:6ced69ccd85f 269:b2472a1930f2
42 42
43 #include <config.h> 43 #include <config.h>
44 #include "lisp.h" 44 #include "lisp.h"
45 #include "imgproc.h" 45 #include "imgproc.h"
46 46
47 static void get_histogram(quant_table *qt, unsigned char *pic, 47 static void
48 int width, int height, Colorbox* box) 48 get_histogram(quant_table *qt, unsigned char *pic,
49 int width, int height, Colorbox* box)
49 { 50 {
50 register unsigned char *inptr; 51 register unsigned char *inptr;
51 register int red, green, blue; 52 register int red, green, blue;
52 register unsigned int j, i; 53 register unsigned int j, i;
53 54
54 box->rmin = box->gmin = box->bmin = 999; 55 box->rmin = box->gmin = box->bmin = 999;
55 box->rmax = box->gmax = box->bmax = -1; 56 box->rmax = box->gmax = box->bmax = -1;
56 box->total = width * height; 57 box->total = width * height;
57 58
58 {
59 register int *ptr = &(qt->histogram[0][0][0]);
60 for (i = B_LEN*B_LEN*B_LEN; i-- > 0;)
61 *ptr++ = 0;
62 }
63 inptr = pic; 59 inptr = pic;
64 for (i = 0; i < height; i++) { 60 for (i = 0; i < height; i++)
65 for (j = width; j-- > 0;) { 61 {
66 red = *inptr++ >> COLOR_SHIFT; 62 for (j = width; j-- > 0;)
67 green = *inptr++ >> COLOR_SHIFT; 63 {
68 blue = *inptr++ >> COLOR_SHIFT; 64 red = *inptr++ >> COLOR_SHIFT;
69 if (red < box->rmin) 65 green = *inptr++ >> COLOR_SHIFT;
70 box->rmin = red; 66 blue = *inptr++ >> COLOR_SHIFT;
71 if (red > box->rmax) 67 if (red < box->rmin)
72 box->rmax = red; 68 box->rmin = red;
73 if (green < box->gmin) 69 if (red > box->rmax)
74 box->gmin = green; 70 box->rmax = red;
75 if (green > box->gmax) 71 if (green < box->gmin)
76 box->gmax = green; 72 box->gmin = green;
77 if (blue < box->bmin) 73 if (green > box->gmax)
78 box->bmin = blue; 74 box->gmax = green;
79 if (blue > box->bmax) 75 if (blue < box->bmin)
80 box->bmax = blue; 76 box->bmin = blue;
81 qt->histogram[red][green][blue]++; 77 if (blue > box->bmax)
82 } 78 box->bmax = blue;
83 } 79 qt->histogram[red][green][blue]++;
80 }
81 }
84 } 82 }
85 83
86 static Colorbox * 84 static Colorbox *
87 largest_box(quant_table *qt) 85 largest_box(quant_table *qt)
88 { 86 {
101 static void 99 static void
102 shrinkbox(quant_table *qt, Colorbox* box) 100 shrinkbox(quant_table *qt, Colorbox* box)
103 { 101 {
104 register int *histp, ir, ig, ib; 102 register int *histp, ir, ig, ib;
105 103
106 if (box->rmax > box->rmin) { 104 if (box->rmax > box->rmin)
107 for (ir = box->rmin; ir <= box->rmax; ++ir) 105 {
108 for (ig = box->gmin; ig <= box->gmax; ++ig) { 106 for (ir = box->rmin; ir <= box->rmax; ++ir)
109 histp = &(qt->histogram[ir][ig][box->bmin]); 107 for (ig = box->gmin; ig <= box->gmax; ++ig)
110 for (ib = box->bmin; ib <= box->bmax; ++ib) 108 {
111 if (*histp++ != 0) { 109 histp = &(qt->histogram[ir][ig][box->bmin]);
112 box->rmin = ir; 110 for (ib = box->bmin; ib <= box->bmax; ++ib)
113 goto have_rmin; 111 if (*histp++ != 0)
112 {
113 box->rmin = ir;
114 goto have_rmin;
115 }
114 } 116 }
115 } 117 have_rmin:
116 have_rmin: 118 if (box->rmax > box->rmin)
117 if (box->rmax > box->rmin) 119 for (ir = box->rmax; ir >= box->rmin; --ir)
118 for (ir = box->rmax; ir >= box->rmin; --ir) 120 for (ig = box->gmin; ig <= box->gmax; ++ig)
119 for (ig = box->gmin; ig <= box->gmax; ++ig) { 121 {
120 histp = &(qt->histogram[ir][ig][box->bmin]); 122 histp = &(qt->histogram[ir][ig][box->bmin]);
121 ib = box->bmin; 123 ib = box->bmin;
122 for (; ib <= box->bmax; ++ib) 124 for (; ib <= box->bmax; ++ib)
123 if (*histp++ != 0) { 125 if (*histp++ != 0)
124 box->rmax = ir; 126 {
125 goto have_rmax; 127 box->rmax = ir;
126 } 128 goto have_rmax;
127 } 129 }
128 } 130 }
131 }
129 have_rmax: 132 have_rmax:
130 if (box->gmax > box->gmin) { 133 if (box->gmax > box->gmin)
131 for (ig = box->gmin; ig <= box->gmax; ++ig) 134 {
132 for (ir = box->rmin; ir <= box->rmax; ++ir) { 135 for (ig = box->gmin; ig <= box->gmax; ++ig)
133 histp = &(qt->histogram[ir][ig][box->bmin]); 136 for (ir = box->rmin; ir <= box->rmax; ++ir)
134 for (ib = box->bmin; ib <= box->bmax; ++ib) 137 {
135 if (*histp++ != 0) { 138 histp = &(qt->histogram[ir][ig][box->bmin]);
136 box->gmin = ig; 139 for (ib = box->bmin; ib <= box->bmax; ++ib)
137 goto have_gmin; 140 if (*histp++ != 0)
141 {
142 box->gmin = ig;
143 goto have_gmin;
144 }
138 } 145 }
139 } 146 have_gmin:
140 have_gmin: 147 if (box->gmax > box->gmin)
141 if (box->gmax > box->gmin) 148 for (ig = box->gmax; ig >= box->gmin; --ig)
142 for (ig = box->gmax; ig >= box->gmin; --ig) 149 for (ir = box->rmin; ir <= box->rmax; ++ir)
143 for (ir = box->rmin; ir <= box->rmax; ++ir) { 150 {
144 histp = &(qt->histogram[ir][ig][box->bmin]); 151 histp = &(qt->histogram[ir][ig][box->bmin]);
145 ib = box->bmin; 152 ib = box->bmin;
146 for (; ib <= box->bmax; ++ib) 153 for (; ib <= box->bmax; ++ib)
147 if (*histp++ != 0) { 154 if (*histp++ != 0)
148 box->gmax = ig; 155 {
149 goto have_gmax; 156 box->gmax = ig;
150 } 157 goto have_gmax;
151 } 158 }
152 } 159 }
160 }
153 have_gmax: 161 have_gmax:
154 if (box->bmax > box->bmin) { 162 if (box->bmax > box->bmin)
155 for (ib = box->bmin; ib <= box->bmax; ++ib) 163 {
156 for (ir = box->rmin; ir <= box->rmax; ++ir) { 164 for (ib = box->bmin; ib <= box->bmax; ++ib)
157 histp = &(qt->histogram[ir][box->gmin][ib]); 165 for (ir = box->rmin; ir <= box->rmax; ++ir)
158 for (ig = box->gmin; ig <= box->gmax; ++ig) { 166 {
159 if (*histp != 0) { 167 histp = &(qt->histogram[ir][box->gmin][ib]);
160 box->bmin = ib; 168 for (ig = box->gmin; ig <= box->gmax; ++ig)
161 goto have_bmin; 169 {
170 if (*histp != 0)
171 {
172 box->bmin = ib;
173 goto have_bmin;
174 }
175 histp += B_LEN;
176 }
162 } 177 }
163 histp += B_LEN; 178 have_bmin:
164 } 179 if (box->bmax > box->bmin)
165 } 180 for (ib = box->bmax; ib >= box->bmin; --ib)
166 have_bmin: 181 for (ir = box->rmin; ir <= box->rmax; ++ir)
167 if (box->bmax > box->bmin) 182 {
168 for (ib = box->bmax; ib >= box->bmin; --ib) 183 histp = &(qt->histogram[ir][box->gmin][ib]);
169 for (ir = box->rmin; ir <= box->rmax; ++ir) { 184 ig = box->gmin;
170 histp = &(qt->histogram[ir][box->gmin][ib]); 185 for (; ig <= box->gmax; ++ig)
171 ig = box->gmin; 186 {
172 for (; ig <= box->gmax; ++ig) { 187 if (*histp != 0)
173 if (*histp != 0) { 188 {
174 box->bmax = ib; 189 box->bmax = ib;
175 goto have_bmax; 190 goto have_bmax;
176 } 191 }
177 histp += B_LEN; 192 histp += B_LEN;
178 } 193 }
179 } 194 }
180 } 195 }
181 have_bmax: 196 have_bmax:
182 ; 197 ;
183 } 198 }
184 199
185 static void 200 static void
205 else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin) 220 else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin)
206 axis = GREEN; 221 axis = GREEN;
207 else 222 else
208 axis = BLUE; 223 axis = BLUE;
209 /* get histogram along longest axis */ 224 /* get histogram along longest axis */
210 switch (axis) { 225 switch (axis)
211 case RED: 226 {
212 histp = &hist2[ptr->rmin]; 227 case RED:
213 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { 228 histp = &hist2[ptr->rmin];
214 *histp = 0; 229 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir)
215 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { 230 {
216 iptr = &(qt->histogram[ir][ig][ptr->bmin]); 231 *histp = 0;
217 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) 232 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig)
218 *histp += *iptr++; 233 {
219 } 234 iptr = &(qt->histogram[ir][ig][ptr->bmin]);
220 histp++; 235 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
221 } 236 *histp += *iptr++;
222 first = ptr->rmin; 237 }
223 last = ptr->rmax; 238 histp++;
224 break;
225 case GREEN:
226 histp = &hist2[ptr->gmin];
227 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
228 *histp = 0;
229 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
230 iptr = &(qt->histogram[ir][ig][ptr->bmin]);
231 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
232 *histp += *iptr++;
233 }
234 histp++;
235 }
236 first = ptr->gmin;
237 last = ptr->gmax;
238 break;
239 case BLUE:
240 histp = &hist2[ptr->bmin];
241 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) {
242 *histp = 0;
243 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {
244 iptr = &(qt->histogram[ir][ptr->gmin][ib]);
245 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {
246 *histp += *iptr;
247 iptr += B_LEN;
248 } 239 }
249 } 240 first = ptr->rmin;
250 histp++; 241 last = ptr->rmax;
251 } 242 break;
252 first = ptr->bmin; 243 case GREEN:
253 last = ptr->bmax; 244 histp = &hist2[ptr->gmin];
254 break; 245 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig)
255 } 246 {
247 *histp = 0;
248 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir)
249 {
250 iptr = &(qt->histogram[ir][ig][ptr->bmin]);
251 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
252 *histp += *iptr++;
253 }
254 histp++;
255 }
256 first = ptr->gmin;
257 last = ptr->gmax;
258 break;
259 case BLUE:
260 histp = &hist2[ptr->bmin];
261 for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)
262 {
263 *histp = 0;
264 for (ir = ptr->rmin; ir <= ptr->rmax; ++ir)
265 {
266 iptr = &(qt->histogram[ir][ptr->gmin][ib]);
267 for (ig = ptr->gmin; ig <= ptr->gmax; ++ig)
268 {
269 *histp += *iptr;
270 iptr += B_LEN;
271 }
272 }
273 histp++;
274 }
275 first = ptr->bmin;
276 last = ptr->bmax;
277 break;
278 }
256 /* find median point */ 279 /* find median point */
257 sum2 = ptr->total / 2; 280 sum2 = ptr->total / 2;
258 histp = &hist2[first]; 281 histp = &hist2[first];
259 sum = 0; 282 sum = 0;
260 for (i = first; i <= last && (sum += *histp++) < sum2; ++i) 283 for (i = first; i <= last && (sum += *histp++) < sum2; ++i)
284 new->rmax = ptr->rmax; 307 new->rmax = ptr->rmax;
285 new->gmin = ptr->gmin; 308 new->gmin = ptr->gmin;
286 new->gmax = ptr->gmax; 309 new->gmax = ptr->gmax;
287 new->bmin = ptr->bmin; 310 new->bmin = ptr->bmin;
288 new->bmax = ptr->bmax; 311 new->bmax = ptr->bmax;
289 switch (axis) { 312 switch (axis)
290 case RED: 313 {
291 new->rmax = i-1; 314 case RED:
292 ptr->rmin = i; 315 new->rmax = i-1;
293 break; 316 ptr->rmin = i;
294 case GREEN: 317 break;
295 new->gmax = i-1; 318 case GREEN:
296 ptr->gmin = i; 319 new->gmax = i-1;
297 break; 320 ptr->gmin = i;
298 case BLUE: 321 break;
299 new->bmax = i-1; 322 case BLUE:
300 ptr->bmin = i; 323 new->bmax = i-1;
301 break; 324 ptr->bmin = i;
302 } 325 break;
303 shrinkbox(qt, new); 326 }
304 shrinkbox(qt, ptr); 327 shrinkbox (qt, new);
328 shrinkbox (qt, ptr);
305 } 329 }
306 330
307 331
308 static C_cell * 332 static C_cell *
309 create_colorcell(quant_table *qt, int num_colors, int red, int green, int blue) 333 create_colorcell(quant_table *qt, int num_colors, int red, int green, int blue)
323 /* 347 /*
324 * Step 1: find all colors inside this cell, while we're at 348 * Step 1: find all colors inside this cell, while we're at
325 * it, find distance of centermost point to furthest corner 349 * it, find distance of centermost point to furthest corner
326 */ 350 */
327 mindist = 99999999; 351 mindist = 99999999;
328 for (i = 0; i < num_colors; ++i) { 352 for (i = 0; i < num_colors; ++i)
329 if (qt->rm[i]>>(COLOR_DEPTH-C_DEPTH) != ir || 353 {
330 qt->gm[i]>>(COLOR_DEPTH-C_DEPTH) != ig || 354 if (qt->rm[i]>>(COLOR_DEPTH-C_DEPTH) != ir ||
331 qt->bm[i]>>(COLOR_DEPTH-C_DEPTH) != ib) 355 qt->gm[i]>>(COLOR_DEPTH-C_DEPTH) != ig ||
332 continue; 356 qt->bm[i]>>(COLOR_DEPTH-C_DEPTH) != ib)
333 ptr->entries[ptr->num_ents][0] = i; 357 continue;
334 ptr->entries[ptr->num_ents][1] = 0; 358 ptr->entries[ptr->num_ents][0] = i;
335 ++ptr->num_ents; 359 ptr->entries[ptr->num_ents][1] = 0;
336 tmp = qt->rm[i] - red; 360 ++ptr->num_ents;
337 if (tmp < (MAX_COLOR/C_LEN/2)) 361 tmp = qt->rm[i] - red;
338 tmp = MAX_COLOR/C_LEN-1 - tmp; 362 if (tmp < (MAX_COLOR/C_LEN/2))
339 dist = tmp*tmp; 363 tmp = MAX_COLOR/C_LEN-1 - tmp;
340 tmp = qt->gm[i] - green; 364 dist = tmp*tmp;
341 if (tmp < (MAX_COLOR/C_LEN/2)) 365 tmp = qt->gm[i] - green;
342 tmp = MAX_COLOR/C_LEN-1 - tmp; 366 if (tmp < (MAX_COLOR/C_LEN/2))
343 dist += tmp*tmp; 367 tmp = MAX_COLOR/C_LEN-1 - tmp;
344 tmp = qt->bm[i] - blue; 368 dist += tmp*tmp;
345 if (tmp < (MAX_COLOR/C_LEN/2)) 369 tmp = qt->bm[i] - blue;
346 tmp = MAX_COLOR/C_LEN-1 - tmp; 370 if (tmp < (MAX_COLOR/C_LEN/2))
347 dist += tmp*tmp; 371 tmp = MAX_COLOR/C_LEN-1 - tmp;
348 if (dist < mindist) 372 dist += tmp*tmp;
349 mindist = dist; 373 if (dist < mindist)
350 } 374 mindist = dist;
375 }
351 376
352 /* 377 /*
353 * Step 3: find all points within that distance to cell. 378 * Step 3: find all points within that distance to cell.
354 */ 379 */
355 for (i = 0; i < num_colors; ++i) { 380 for (i = 0; i < num_colors; ++i)
356 if (qt->rm[i] >> (COLOR_DEPTH-C_DEPTH) == ir && 381 {
357 qt->gm[i] >> (COLOR_DEPTH-C_DEPTH) == ig && 382 if (qt->rm[i] >> (COLOR_DEPTH-C_DEPTH) == ir &&
358 qt->bm[i] >> (COLOR_DEPTH-C_DEPTH) == ib) 383 qt->gm[i] >> (COLOR_DEPTH-C_DEPTH) == ig &&
359 continue; 384 qt->bm[i] >> (COLOR_DEPTH-C_DEPTH) == ib)
360 dist = 0; 385 continue;
361 if ((tmp = red - qt->rm[i]) > 0 || 386 dist = 0;
362 (tmp = qt->rm[i] - (red + MAX_COLOR/C_LEN-1)) > 0 ) 387 if ((tmp = red - qt->rm[i]) > 0 ||
363 dist += tmp*tmp; 388 (tmp = qt->rm[i] - (red + MAX_COLOR/C_LEN-1)) > 0 )
364 if ((tmp = green - qt->gm[i]) > 0 || 389 dist += tmp*tmp;
365 (tmp = qt->gm[i] - (green + MAX_COLOR/C_LEN-1)) > 0 ) 390 if ((tmp = green - qt->gm[i]) > 0 ||
366 dist += tmp*tmp; 391 (tmp = qt->gm[i] - (green + MAX_COLOR/C_LEN-1)) > 0 )
367 if ((tmp = blue - qt->bm[i]) > 0 || 392 dist += tmp*tmp;
368 (tmp = qt->bm[i] - (blue + MAX_COLOR/C_LEN-1)) > 0 ) 393 if ((tmp = blue - qt->bm[i]) > 0 ||
369 dist += tmp*tmp; 394 (tmp = qt->bm[i] - (blue + MAX_COLOR/C_LEN-1)) > 0 )
370 if (dist < mindist) { 395 dist += tmp*tmp;
371 ptr->entries[ptr->num_ents][0] = i; 396 if (dist < mindist)
372 ptr->entries[ptr->num_ents][1] = dist; 397 {
373 ++ptr->num_ents; 398 ptr->entries[ptr->num_ents][0] = i;
374 } 399 ptr->entries[ptr->num_ents][1] = dist;
375 } 400 ++ptr->num_ents;
401 }
402 }
376 403
377 /* 404 /*
378 * Sort color cells by distance, use cheap exchange sort 405 * Sort color cells by distance, use cheap exchange sort
379 */ 406 */
380 for (n = ptr->num_ents - 1; n > 0; n = next_n) { 407 for (n = ptr->num_ents - 1; n > 0; n = next_n)
381 next_n = 0; 408 {
382 for (i = 0; i < n; ++i) 409 next_n = 0;
383 if (ptr->entries[i][1] > ptr->entries[i+1][1]) { 410 for (i = 0; i < n; ++i)
384 tmp = ptr->entries[i][0]; 411 if (ptr->entries[i][1] > ptr->entries[i+1][1])
385 ptr->entries[i][0] = ptr->entries[i+1][0]; 412 {
386 ptr->entries[i+1][0] = tmp; 413 tmp = ptr->entries[i][0];
387 tmp = ptr->entries[i][1]; 414 ptr->entries[i][0] = ptr->entries[i+1][0];
388 ptr->entries[i][1] = ptr->entries[i+1][1]; 415 ptr->entries[i+1][0] = tmp;
389 ptr->entries[i+1][1] = tmp; 416 tmp = ptr->entries[i][1];
390 next_n = i; 417 ptr->entries[i][1] = ptr->entries[i+1][1];
391 } 418 ptr->entries[i+1][1] = tmp;
392 } 419 next_n = i;
420 }
421 }
393 return (ptr); 422 return (ptr);
394 } 423 }
395 424
396 static int 425 static int
397 map_colortable(quant_table *qt, int num_colors) 426 map_colortable(quant_table *qt, int num_colors)
401 register int j, tmp, d2, dist; 430 register int j, tmp, d2, dist;
402 int ir, ig, ib, i; 431 int ir, ig, ib, i;
403 432
404 for (ir = 0; ir < B_LEN; ++ir) 433 for (ir = 0; ir < B_LEN; ++ir)
405 for (ig = 0; ig < B_LEN; ++ig) 434 for (ig = 0; ig < B_LEN; ++ig)
406 for (ib = 0; ib < B_LEN; ++ib, histp++) { 435 for (ib = 0; ib < B_LEN; ++ib, histp++)
407 if (*histp == 0) { 436 {
408 *histp = -1; 437 if (*histp == 0)
409 continue; 438 {
439 *histp = -1;
440 continue;
441 }
442 cell = *(qt->ColorCells +
443 (((ir>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +
444 ((ig>>(B_DEPTH-C_DEPTH)) << C_DEPTH) +
445 (ib>>(B_DEPTH-C_DEPTH))));
446 if (cell == NULL )
447 cell = create_colorcell (qt, num_colors,
448 ir << COLOR_SHIFT,
449 ig << COLOR_SHIFT,
450 ib << COLOR_SHIFT);
451 if (cell == NULL) /* memory exhausted! punt! */
452 return -1;
453 dist = 9999999;
454 for (i = 0; i < cell->num_ents &&
455 dist > cell->entries[i][1]; ++i)
456 {
457 j = cell->entries[i][0];
458 d2 = qt->rm[j] - (ir << COLOR_SHIFT);
459 d2 *= d2;
460 tmp = qt->gm[j] - (ig << COLOR_SHIFT);
461 d2 += tmp*tmp;
462 tmp = qt->bm[j] - (ib << COLOR_SHIFT);
463 d2 += tmp*tmp;
464 if (d2 < dist)
465 {
466 dist = d2;
467 *histp = j;
468 }
469 }
410 } 470 }
411 cell = *(qt->ColorCells +
412 (((ir>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +
413 ((ig>>(B_DEPTH-C_DEPTH)) << C_DEPTH) +
414 (ib>>(B_DEPTH-C_DEPTH))));
415 if (cell == NULL )
416 cell = create_colorcell(qt, num_colors,
417 ir << COLOR_SHIFT,
418 ig << COLOR_SHIFT,
419 ib << COLOR_SHIFT);
420 if (cell == NULL) /* memory exhausted! punt! */
421 return -1;
422 dist = 9999999;
423 for (i = 0; i < cell->num_ents &&
424 dist > cell->entries[i][1]; ++i) {
425 j = cell->entries[i][0];
426 d2 = qt->rm[j] - (ir << COLOR_SHIFT);
427 d2 *= d2;
428 tmp = qt->gm[j] - (ig << COLOR_SHIFT);
429 d2 += tmp*tmp;
430 tmp = qt->bm[j] - (ib << COLOR_SHIFT);
431 d2 += tmp*tmp;
432 if (d2 < dist) {
433 dist = d2;
434 *histp = j;
435 }
436 }
437 }
438 return 0; 471 return 0;
439 } 472 }
440 473
441 quant_table *EImage_build_quantable(unsigned char *eimage, int width, int height, int num_colors) 474 quant_table *
475 build_EImage_quantable(unsigned char *eimage, int width, int height, int num_colors)
442 { 476 {
443 quant_table *qt; 477 quant_table *qt;
444 Colorbox *box_list, *ptr; 478 Colorbox *box_list, *ptr;
445 int i,res; 479 int i,res;
446 480
447 qt = (quant_table*)xmalloc(sizeof(quant_table)); 481 qt = (quant_table*)xmalloc_and_zero (sizeof(quant_table));
448 if (qt == NULL) return NULL; 482 if (qt == NULL) return NULL;
449 483
450 assert (num_colors < 257 && num_colors > 2); 484 assert (num_colors < 257 && num_colors > 2);
451 /* 485 /*
452 * STEP 1: create empty boxes 486 * STEP 1: create empty boxes
453 */ 487 */
454 qt->usedboxes = NULL; 488 qt->usedboxes = NULL;
455 box_list = qt->freeboxes = (Colorbox *)xmalloc(num_colors*sizeof (Colorbox)); 489 box_list = qt->freeboxes = (Colorbox *)xmalloc (num_colors*sizeof (Colorbox));
456 qt->freeboxes[0].next = &(qt->freeboxes[1]); 490 qt->freeboxes[0].next = &(qt->freeboxes[1]);
457 qt->freeboxes[0].prev = NULL; 491 qt->freeboxes[0].prev = NULL;
458 for (i = 1; i < num_colors-1; ++i) { 492 for (i = 1; i < num_colors-1; ++i)
459 qt->freeboxes[i].next = &(qt->freeboxes[i+1]); 493 {
460 qt->freeboxes[i].prev = &(qt->freeboxes[i-1]); 494 qt->freeboxes[i].next = &(qt->freeboxes[i+1]);
461 } 495 qt->freeboxes[i].prev = &(qt->freeboxes[i-1]);
496 }
462 qt->freeboxes[num_colors-1].next = NULL; 497 qt->freeboxes[num_colors-1].next = NULL;
463 qt->freeboxes[num_colors-1].prev = &(qt->freeboxes[num_colors-2]); 498 qt->freeboxes[num_colors-1].prev = &(qt->freeboxes[num_colors-2]);
464 499
465 /* 500 /*
466 * STEP 2: get histogram, initialize first box 501 * STEP 2: get histogram, initialize first box
471 qt->freeboxes->prev = NULL; 506 qt->freeboxes->prev = NULL;
472 ptr->next = qt->usedboxes; 507 ptr->next = qt->usedboxes;
473 qt->usedboxes = ptr; 508 qt->usedboxes = ptr;
474 if (ptr->next) 509 if (ptr->next)
475 ptr->next->prev = ptr; 510 ptr->next->prev = ptr;
476 get_histogram(qt, eimage, width, height, ptr); 511 get_histogram (qt, eimage, width, height, ptr);
477 512
478 /* 513 /*
479 * STEP 3: continually subdivide boxes until no more free 514 * STEP 3: continually subdivide boxes until no more free
480 * boxes remain or until all colors assigned. 515 * boxes remain or until all colors assigned.
481 */ 516 */
482 while (qt->freeboxes != NULL) { 517 while (qt->freeboxes != NULL)
483 ptr = largest_box(qt); 518 {
484 if (ptr != NULL) 519 ptr = largest_box(qt);
485 splitbox(qt, ptr); 520 if (ptr != NULL)
486 else 521 splitbox (qt, ptr);
487 qt->freeboxes = NULL; 522 else
488 } 523 qt->freeboxes = NULL;
524 }
489 525
490 /* 526 /*
491 * STEP 4: assign colors to all boxes 527 * STEP 4: assign colors to all boxes
492 */ 528 */
493 for (i = 0, ptr = qt->usedboxes; ptr != NULL; ++i, ptr = ptr->next) { 529 for (i = 0, ptr = qt->usedboxes; ptr != NULL; ++i, ptr = ptr->next)
494 qt->rm[i] = ((ptr->rmin + ptr->rmax) << COLOR_SHIFT) / 2; 530 {
495 qt->gm[i] = ((ptr->gmin + ptr->gmax) << COLOR_SHIFT) / 2; 531 qt->rm[i] = ((ptr->rmin + ptr->rmax) << COLOR_SHIFT) / 2;
496 qt->bm[i] = ((ptr->bmin + ptr->bmax) << COLOR_SHIFT) / 2; 532 qt->gm[i] = ((ptr->gmin + ptr->gmax) << COLOR_SHIFT) / 2;
497 qt->um[i] = ptr->total; 533 qt->bm[i] = ((ptr->bmin + ptr->bmax) << COLOR_SHIFT) / 2;
498 } 534 qt->um[i] = ptr->total;
535 }
499 qt->num_active_colors = i; 536 qt->num_active_colors = i;
500 537
501 /* We're done with the boxes now */ 538 /* We're done with the boxes now */
502 xfree(box_list); 539 xfree (box_list);
503 qt->freeboxes = qt->usedboxes = NULL; 540 qt->freeboxes = qt->usedboxes = NULL;
504 541
505 /* 542 /*
506 * STEP 5: scan histogram and map all values to closest color 543 * STEP 5: scan histogram and map all values to closest color
507 */ 544 */
508 /* 5a: create cell list as described in Heckbert */ 545 /* 5a: create cell list as described in Heckbert */
509 qt->ColorCells = (C_cell **)xmalloc(C_LEN*C_LEN*C_LEN*sizeof (C_cell*)); 546 qt->ColorCells = (C_cell **)xmalloc_and_zero (C_LEN*C_LEN*C_LEN*sizeof (C_cell*));
510 memset(qt->ColorCells, 0, C_LEN*C_LEN*C_LEN*sizeof (C_cell*));
511 /* 5b: create mapping from truncated pixel space to color 547 /* 5b: create mapping from truncated pixel space to color
512 table entries */ 548 table entries */
513 res = map_colortable(qt, num_colors); 549 res = map_colortable (qt, num_colors);
514 550
515 /* 5c: done with ColorCells */ 551 /* 5c: done with ColorCells */
516 for (i = 0; i < C_LEN*C_LEN*C_LEN; i++) if (qt->ColorCells[i]) xfree(qt->ColorCells[i]); 552 for (i = 0; i < C_LEN*C_LEN*C_LEN; i++)
517 xfree(qt->ColorCells); 553 if (qt->ColorCells[i]) xfree (qt->ColorCells[i]);
554 xfree (qt->ColorCells);
518 555
519 if (res) { 556 if (res)
520 /* we failed in memory allocation, so clean up an leave */ 557 {
521 xfree(qt); 558 /* we failed in memory allocation, so clean up an leave */
522 return NULL; 559 xfree(qt);
523 } 560 return NULL;
561 }
524 562
525 return qt; 563 return qt;
526 } 564 }