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.6 by greg, Wed May 5 10:18:05 1993 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1992 Regents of the University of California */
1 > /* Copyright (c) 1993 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 31 | Line 31 | static unsigned        histo[NRED][NGRN][NBLU];
31   static int      CLRCUBE[3][2] = {0,NRED,0,NGRN,0,NBLU};
32                                  /* maximum propagated error during dithering */
33   #define MAXERR          20
34 +                                /* define CLOSEST to get closest colors */
35 + #ifndef CLOSEST
36 + #ifdef SPEED
37 + #if  SPEED > 8
38 + #define CLOSEST         1       /* this step takes a little longer */
39 + #endif
40 + #endif
41 + #endif
42  
43  
44   new_histo()             /* clear our histogram */
# Line 66 | Line 74 | int    ncolors;
74                  ncolors = 256;
75                                  /* partition color space */
76          cut(CLRCUBE, 0, ncolors);
77 + #ifdef CLOSEST
78 +        closest(ncolors);       /* ensure colors picked are closest */
79 + #endif
80                                  /* return new color table size */
81          return(ncolors);
82   }
# Line 170 | Line 181 | register int   box[3][2];
181   #define c0      r
182          register int    r, g, b;
183          int     pri;
184 <        int     t[HMAX], med;
184 >        long    t[HMAX], med;
185                                          /* find dominant axis */
186          pri = RED;
187          if (box[GRN][1]-box[GRN][0] > box[pri][1]-box[pri][0])
# Line 226 | Line 237 | mktabent(p, box)       /* compute average color for box and
237   int     p;
238   register int    box[3][2];
239   {
240 <        long    sum[3];
241 <        int     r, g, n;
242 <        register int    b, c;
240 >        unsigned long   sum[3];
241 >        unsigned        r, g, n;
242 >        register unsigned       b, c;
243                                                  /* sum pixels in box */
244          n = 0;
245          sum[RED] = sum[GRN] = sum[BLU] = 0;
# Line 243 | Line 254 | register int   box[3][2];
254                      }
255                      histo[r][g][b] = p;         /* assign pixel */
256                  }
257 +        if (n >= (1<<23)/HMAX) {                /* avoid overflow */
258 +                sum[RED] /= n;
259 +                sum[GRN] /= n;
260 +                sum[BLU] /= n;
261 +                n = 1;
262 +        }
263          if (n) {                                /* compute average */
264                  clrtab[p][RED] = sum[RED]*256/NRED/n;
265                  clrtab[p][GRN] = sum[GRN]*256/NGRN/n;
# Line 253 | Line 270 | register int   box[3][2];
270                  clrtab[p][BLU] = (box[BLU][0]+box[BLU][1])*256/NBLU/2;
271          }
272   }
273 +
274 +
275 + #ifdef CLOSEST
276 + #define NBSIZ           32
277 + static
278 + closest(n)                      /* make sure we have the closest colors */
279 + int     n;
280 + {
281 +        BYTE    *neigh[256];
282 +        register int    r, g, b;
283 + #define i r
284 +                                        /* get space for neighbor lists */
285 +        for (i = 0; i < n; i++) {
286 +                if ((neigh[i] = (BYTE *)malloc(NBSIZ)) == NULL) {
287 +                        while (i--)
288 +                                free(neigh[i]);
289 +                        return;                 /* ENOMEM -- abandon effort */
290 +                }
291 +                neigh[i][0] = i;                /* identity is terminator */
292 +        }
293 +                                        /* make neighbor lists */
294 +        for (r = 0; r < NRED; r++)
295 +            for (g = 0; g < NGRN; g++)
296 +                for (b = 0; b < NBLU; b++) {
297 +                    if (r < NRED-1 && histo[r][g][b] != histo[r+1][g][b])
298 +                        addneigh(neigh, histo[r][g][b], histo[r+1][g][b]);
299 +                    if (g < NGRN-1 && histo[r][g][b] != histo[r][g+1][b])
300 +                        addneigh(neigh, histo[r][g][b], histo[r][g+1][b]);
301 +                    if (b < NBLU-1 && histo[r][g][b] != histo[r][g][b+1])
302 +                        addneigh(neigh, histo[r][g][b], histo[r][g][b+1]);
303 +                }
304 +                                        /* assign closest values */
305 +        for (r = 0; r < NRED; r++)
306 +            for (g = 0; g < NGRN; g++)
307 +                for (b = 0; b < NBLU; b++)
308 +                    setclosest(neigh, r, g, b);
309 +                                        /* free neighbor lists */
310 +        for (i = 0; i < n; i++)
311 +                free(neigh[i]);
312 + #undef i
313 + }
314 +
315 +
316 + static
317 + addneigh(nl, i, j)              /* i and j are neighbors; add them to list */
318 + register BYTE   *nl[];
319 + register int    i;
320 + int     j;
321 + {
322 +        int     nc;
323 +        char    *nnl;
324 +        register int    t;
325 +        
326 +        for (nc = 0; nc < 2; nc++) {            /* do both neighbors */
327 +                for (t = 0; nl[i][t] != i; t++)
328 +                        if (nl[i][t] == j)
329 +                                break;          /* in list already */
330 +                if (nl[i][t] == i) {            /* add to list */
331 +                        nl[i][t++] = j;
332 +                        if (t % NBSIZ == 0) {   /* enlarge list */
333 +                                if ((nnl = realloc(nl[i], t+NBSIZ)) == NULL)
334 +                                        t--;
335 +                                else
336 +                                        nl[i] = (BYTE *)nnl;
337 +                        }
338 +                        nl[i][t] = i;           /* terminator */
339 +                }
340 +                t = i; i = j; j = t;            /* swap and do it again */
341 +        }
342 + }
343 +
344 +
345 + static unsigned
346 + dist(col, r, g, b)              /* find distance from clrtab entry to r,g,b */
347 + register BYTE   col[3];
348 + int     r, g, b;
349 + {
350 +        register int    tmp;
351 +        register unsigned       sum;
352 +        
353 +        tmp = col[RED]*NRED/256 - r;
354 +        sum = tmp*tmp;
355 +        tmp = col[GRN]*NGRN/256 - g;
356 +        sum += tmp*tmp;
357 +        tmp = col[BLU]*NBLU/256 - b;
358 +        sum += tmp*tmp;
359 +        return(sum);
360 + }
361 +
362 +
363 + static
364 + setclosest(nl, r, g, b)         /* find index closest to color and assign */
365 + BYTE    *nl[];
366 + int     r, g, b;
367 + {
368 +        int     ident;
369 +        unsigned        min;
370 +        register unsigned       d;
371 +        register BYTE   *p;
372 +                                        /* get starting value */
373 +        min = dist(clrtab[ident=histo[r][g][b]], r, g, b);
374 +                                        /* find minimum */
375 +        for (p = nl[ident]; *p != ident; p++)
376 +                if ((d = dist(clrtab[*p], r, g, b)) < min) {
377 +                        min = d;
378 +                        histo[r][g][b] = *p;
379 +                }
380 + }
381 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines