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.2 by greg, Tue Oct 13 09:07:51 1992 UTC

# 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 + #define CLOSEST         1
36  
37  
38   new_histo()             /* clear our histogram */
# Line 66 | Line 68 | int    ncolors;
68                  ncolors = 256;
69                                  /* partition color space */
70          cut(CLRCUBE, 0, ncolors);
71 + #ifdef CLOSEST
72 +        closest(ncolors);       /* ensure colors picked are closest */
73 + #endif
74                                  /* return new color table size */
75          return(ncolors);
76   }
# Line 253 | Line 258 | register int   box[3][2];
258                  clrtab[p][BLU] = (box[BLU][0]+box[BLU][1])*256/NBLU/2;
259          }
260   }
261 +
262 +
263 + #ifdef CLOSEST
264 + #define NBSIZ           32
265 + static
266 + closest(n)                      /* make sure we have the closest colors */
267 + int     n;
268 + {
269 +        BYTE    *neigh[256];
270 +        register int    r, g, b;
271 + #define i r
272 +                                        /* get space for neighbor lists */
273 +        for (i = 0; i < n; i++) {
274 +                if ((neigh[i] = (BYTE *)malloc(NBSIZ)) == NULL) {
275 +                        while (i--)
276 +                                free(neigh[i]);
277 +                        return;                 /* ENOMEM -- abandon effort */
278 +                }
279 +                neigh[i][0] = i;                /* identity is terminator */
280 +        }
281 +                                        /* make neighbor lists */
282 +        for (r = 0; r < NRED-1; r++)
283 +            for (g = 0; g < NGRN-1; g++)
284 +                for (b = 0; b < NBLU-1; b++) {
285 +                    if (histo[r][g][b] != histo[r+1][g][b])
286 +                        addneigh(neigh, histo[r][g][b], histo[r+1][g][b]);
287 +                    if (histo[r][g][b] != histo[r][g+1][b])
288 +                        addneigh(neigh, histo[r][g][b], histo[r][g+1][b]);
289 +                    if (histo[r][g][b] != histo[r][g][b+1])
290 +                        addneigh(neigh, histo[r][g][b], histo[r][g][b+1]);
291 +                }
292 +                                        /* assign closest values */
293 +        for (r = 0; r < NRED; r++)
294 +            for (g = 0; g < NGRN; g++)
295 +                for (b = 0; b < NBLU; b++)
296 +                    setclosest(neigh, r, g, b);
297 +                                        /* free neighbor lists */
298 +        for (i = 0; i < n; i++)
299 +                free(neigh[i]);
300 + #undef i
301 + }
302 +
303 +
304 + static
305 + addneigh(nl, i, j)              /* i and j are neighbors; add them to list */
306 + register BYTE   *nl[];
307 + register int    i;
308 + int     j;
309 + {
310 +        int     nc;
311 +        char    *nnl;
312 +        register int    t;
313 +        
314 +        for (nc = 0; nc < 2; nc++) {            /* do both neighbors */
315 +                for (t = 0; nl[i][t] != i; t++)
316 +                        if (nl[i][t] == j)
317 +                                break;          /* in list already */
318 +                if (nl[i][t] == i) {            /* add to list */
319 +                        nl[i][t++] = j;
320 +                        if (t % NBSIZ == 0) {   /* enlarge list */
321 +                                if ((nnl = realloc(nl[i], t+NBSIZ)) == NULL)
322 +                                        t--;
323 +                                else
324 +                                        nl[i] = (BYTE *)nnl;
325 +                        }
326 +                        nl[i][t] = i;           /* terminator */
327 +                }
328 +                t = i; i = j; j = t;            /* swap and do it again */
329 +        }
330 + }
331 +
332 +
333 + static unsigned
334 + dist(col, r, g, b)              /* find distance from clrtab entry to r,g,b */
335 + register BYTE   col[3];
336 + int     r, g, b;
337 + {
338 +        register unsigned       tmp;
339 +        register unsigned       sum;
340 +        
341 +        tmp = col[RED]*NRED/256 - r;
342 +        sum = tmp*tmp;
343 +        tmp = col[GRN]*NGRN/256 - g;
344 +        sum += tmp*tmp;
345 +        tmp = col[BLU]*NBLU/256 - b;
346 +        sum += tmp*tmp;
347 +        return(sum);
348 + }
349 +
350 +
351 + static
352 + setclosest(nl, r, g, b)         /* find index closest to color and assign */
353 + BYTE    *nl[];
354 + int     r, g, b;
355 + {
356 +        int     ident;
357 +        unsigned        min;
358 +        register unsigned       d;
359 +        register BYTE   *p;
360 +                                        /* get starting value */
361 +        min = dist(clrtab[ident=histo[r][g][b]], r, g, b);
362 +                                        /* find minimum */
363 +        for (p = nl[ident]; *p != ident; p++)
364 +                if ((d = dist(clrtab[*p], r, g, b)) < min) {
365 +                        min = d;
366 +                        histo[r][g][b] = *p;
367 +                }
368 + }
369 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines