ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/clrtab.c
(Generate patch)

Comparing ray/src/px/clrtab.c (file contents):
Revision 2.1 by greg, Mon Oct 12 12:58:39 1992 UTC vs.
Revision 2.12 by greg, Sat Feb 22 02:07:27 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Simple median-cut color quantization based on colortab.c
6   */
# Line 23 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
20   #define part(cn)        ((cn)>>2)
21   #define prim(cn)        ((cn)&3)
22                                  /* our color table (global) */
23 < BYTE    clrtab[256][3];
23 > extern BYTE     clrtab[256][3];
24                                  /* histogram of colors / color assignments */
25   static unsigned histo[NRED][NGRN][NBLU];
26   #define cndx(c)         histo[((c)[RED]*NRED)>>8][((c)[GRN]*NGRN)>>8][((c)[BLU]*NBLU)>>8]
# Line 31 | Line 28 | static unsigned        histo[NRED][NGRN][NBLU];
28   static int      CLRCUBE[3][2] = {0,NRED,0,NGRN,0,NBLU};
29                                  /* maximum propagated error during dithering */
30   #define MAXERR          20
31 +                                /* define CLOSEST to get closest colors */
32 + #ifndef CLOSEST
33 + #ifdef SPEED
34 + #if  SPEED > 8
35 + #define CLOSEST         1       /* this step takes a little longer */
36 + #endif
37 + #endif
38 + #endif
39  
40 + static  cut(), mktabent(), closest(), addneigh(), setclosest();
41 + static int      split();
42 + static unsigned dist();
43  
44 < new_histo()             /* clear our histogram */
44 >
45 > new_histo(n)            /* clear our histogram */
46 > int     n;
47   {
48          bzero((char *)histo, sizeof(histo));
49 +        return(0);
50   }
51  
52  
# Line 66 | Line 77 | int    ncolors;
77                  ncolors = 256;
78                                  /* partition color space */
79          cut(CLRCUBE, 0, ncolors);
80 + #ifdef CLOSEST
81 +        closest(ncolors);       /* ensure colors picked are closest */
82 + #endif
83 +                                /* reset dithering function */
84 +        dith_colrs((BYTE *)NULL, (COLR *)NULL, 0);
85                                  /* return new color table size */
86          return(ncolors);
87   }
# Line 96 | Line 112 | register BYTE  *bs;
112   register COLR   *cs;
113   int     n;
114   {
115 <        static short    (*cerr)[3];
115 >        static short    (*cerr)[3] = NULL;
116          static int      N = 0;
117          int     err[3], errp[3];
118          register int    x, i;
119  
120          if (n != N) {           /* get error propogation array */
121 <                if (N)
122 <                        cerr = (short (*)[3])realloc((char *)cerr,
123 <                                        3*n*sizeof(short));
124 <                else
121 >                if (N) {
122 >                        free((void *)cerr);
123 >                        cerr = NULL;
124 >                }
125 >                if (n)
126                          cerr = (short (*)[3])malloc(3*n*sizeof(short));
127                  if (cerr == NULL) {
128                          N = 0;
# Line 170 | Line 187 | register int   box[3][2];
187   #define c0      r
188          register int    r, g, b;
189          int     pri;
190 <        int     t[HMAX], med;
190 >        long    t[HMAX], med;
191                                          /* find dominant axis */
192          pri = RED;
193          if (box[GRN][1]-box[GRN][0] > box[pri][1]-box[pri][0])
# Line 226 | Line 243 | mktabent(p, box)       /* compute average color for box and
243   int     p;
244   register int    box[3][2];
245   {
246 <        long    sum[3];
247 <        int     r, g, n;
248 <        register int    b, c;
246 >        unsigned long   sum[3];
247 >        unsigned        r, g;
248 >        unsigned long   n;
249 >        register unsigned       b, c;
250                                                  /* sum pixels in box */
251          n = 0;
252          sum[RED] = sum[GRN] = sum[BLU] = 0;
# Line 243 | Line 261 | register int   box[3][2];
261                      }
262                      histo[r][g][b] = p;         /* assign pixel */
263                  }
264 +        if (n >= (1L<<23)/HMAX) {               /* avoid overflow */
265 +                sum[RED] /= n;
266 +                sum[GRN] /= n;
267 +                sum[BLU] /= n;
268 +                n = 1;
269 +        }
270          if (n) {                                /* compute average */
271                  clrtab[p][RED] = sum[RED]*256/NRED/n;
272                  clrtab[p][GRN] = sum[GRN]*256/NGRN/n;
# Line 253 | Line 277 | register int   box[3][2];
277                  clrtab[p][BLU] = (box[BLU][0]+box[BLU][1])*256/NBLU/2;
278          }
279   }
280 +
281 +
282 + #ifdef CLOSEST
283 + #define NBSIZ           32
284 + static
285 + closest(n)                      /* make sure we have the closest colors */
286 + int     n;
287 + {
288 +        BYTE    *neigh[256];
289 +        register int    r, g, b;
290 + #define i r
291 +                                        /* get space for neighbor lists */
292 +        for (i = 0; i < n; i++) {
293 +                if ((neigh[i] = (BYTE *)malloc(NBSIZ)) == NULL) {
294 +                        while (i--)
295 +                                free(neigh[i]);
296 +                        return;                 /* ENOMEM -- abandon effort */
297 +                }
298 +                neigh[i][0] = i;                /* identity is terminator */
299 +        }
300 +                                        /* make neighbor lists */
301 +        for (r = 0; r < NRED; r++)
302 +            for (g = 0; g < NGRN; g++)
303 +                for (b = 0; b < NBLU; b++) {
304 +                    if (r < NRED-1 && histo[r][g][b] != histo[r+1][g][b])
305 +                        addneigh(neigh, histo[r][g][b], histo[r+1][g][b]);
306 +                    if (g < NGRN-1 && histo[r][g][b] != histo[r][g+1][b])
307 +                        addneigh(neigh, histo[r][g][b], histo[r][g+1][b]);
308 +                    if (b < NBLU-1 && histo[r][g][b] != histo[r][g][b+1])
309 +                        addneigh(neigh, histo[r][g][b], histo[r][g][b+1]);
310 +                }
311 +                                        /* assign closest values */
312 +        for (r = 0; r < NRED; r++)
313 +            for (g = 0; g < NGRN; g++)
314 +                for (b = 0; b < NBLU; b++)
315 +                    setclosest(neigh, r, g, b);
316 +                                        /* free neighbor lists */
317 +        for (i = 0; i < n; i++)
318 +                free(neigh[i]);
319 + #undef i
320 + }
321 +
322 +
323 + static
324 + addneigh(nl, i, j)              /* i and j are neighbors; add them to list */
325 + register BYTE   *nl[];
326 + register int    i;
327 + int     j;
328 + {
329 +        int     nc;
330 +        char    *nnl;
331 +        register int    t;
332 +        
333 +        for (nc = 0; nc < 2; nc++) {            /* do both neighbors */
334 +                for (t = 0; nl[i][t] != i; t++)
335 +                        if (nl[i][t] == j)
336 +                                break;          /* in list already */
337 +                if (nl[i][t] == i) {            /* add to list */
338 +                        nl[i][t++] = j;
339 +                        if (t % NBSIZ == 0) {   /* enlarge list */
340 +                                if ((nnl = realloc(nl[i], t+NBSIZ)) == NULL)
341 +                                        t--;
342 +                                else
343 +                                        nl[i] = (BYTE *)nnl;
344 +                        }
345 +                        nl[i][t] = i;           /* terminator */
346 +                }
347 +                t = i; i = j; j = t;            /* swap and do it again */
348 +        }
349 + }
350 +
351 +
352 + static unsigned
353 + dist(col, r, g, b)              /* find distance from clrtab entry to r,g,b */
354 + register BYTE   col[3];
355 + int     r, g, b;
356 + {
357 +        register int    tmp;
358 +        register unsigned       sum;
359 +        
360 +        tmp = col[RED]*NRED/256 - r;
361 +        sum = tmp*tmp;
362 +        tmp = col[GRN]*NGRN/256 - g;
363 +        sum += tmp*tmp;
364 +        tmp = col[BLU]*NBLU/256 - b;
365 +        sum += tmp*tmp;
366 +        return(sum);
367 + }
368 +
369 +
370 + static
371 + setclosest(nl, r, g, b)         /* find index closest to color and assign */
372 + BYTE    *nl[];
373 + int     r, g, b;
374 + {
375 +        int     ident;
376 +        unsigned        min;
377 +        register unsigned       d;
378 +        register BYTE   *p;
379 +                                        /* get starting value */
380 +        min = dist(clrtab[ident=histo[r][g][b]], r, g, b);
381 +                                        /* find minimum */
382 +        for (p = nl[ident]; *p != ident; p++)
383 +                if ((d = dist(clrtab[*p], r, g, b)) < min) {
384 +                        min = d;
385 +                        histo[r][g][b] = *p;
386 +                }
387 + }
388 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines