--- ray/src/rt/colortab.c 1989/10/16 13:43:26 1.9
+++ ray/src/rt/colortab.c 2003/02/22 02:07:28 2.5
@@ -1,9 +1,6 @@
-/* Copyright (c) 1989 Regents of the University of California */
-
#ifndef lint
-static char SCCSid[] = "$SunId$ LBL";
+static const char RCSid[] = "$Id: colortab.c,v 2.5 2003/02/22 02:07:28 greg Exp $";
#endif
-
/*
* colortab.c - allocate and control dynamic color table.
*
@@ -14,11 +11,70 @@ static char SCCSid[] = "$SunId$ LBL";
* histogram is cleared. This algorithm
* performs only as well as the next drawing's color
* distribution is correlated to the last.
+ *
+ * External symbols declared in drvier.h
*/
-#include "color.h"
+/* ====================================================================
+ * The Radiance Software License, Version 1.0
+ *
+ * Copyright (c) 1990 - 2002 The Regents of the University of California,
+ * through Lawrence Berkeley National Laboratory. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes Radiance software
+ * (http://radsite.lbl.gov/)
+ * developed by the Lawrence Berkeley National Laboratory
+ * (http://www.lbl.gov/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
+ * and "The Regents of the University of California" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact radiance@radsite.lbl.gov.
+ *
+ * 5. Products derived from this software may not be called "Radiance",
+ * nor may "Radiance" appear in their name, without prior written
+ * permission of Lawrence Berkeley National Laboratory.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of Lawrence Berkeley National Laboratory. For more
+ * information on Lawrence Berkeley National Laboratory, please see
+ * .
+ */
-#define NULL 0
+#include "standard.h"
+
+#include "color.h"
/* histogram resolution */
#define NRED 24
#define NGRN 32
@@ -33,7 +89,7 @@ static char SCCSid[] = "$SunId$ LBL";
(int)(colval(c,p)*256.) : 255 ]
/* color partition tree */
#define CNODE short
-#define set_branch(p,c) ((c)<<2|(p))
+#define set_branch(p,c) ((c)<<2|(p))
#define set_pval(pv) ((pv)<<2|3)
#define is_branch(cn) (((cn)&3)!=3)
#define is_pval(cn) (((cn)&3)==3)
@@ -43,8 +99,8 @@ static char SCCSid[] = "$SunId$ LBL";
/* our color table */
static struct tabent {
long sum[3]; /* sum of colors using this entry */
- long n; /* number of colors */
- short ent[3]; /* current table value */
+ int n; /* number of colors */
+ BYTE ent[3]; /* current table value */
} *clrtab = NULL;
/* color cube partition */
static CNODE *ctree = NULL;
@@ -53,9 +109,12 @@ static BYTE clrmap[3][256];
/* histogram of colors used */
static unsigned short histo[NRED][NGRN][NBLU];
/* initial color cube boundary */
-static int CLRCUBE[3][2] = {0,NRED,0,NGRN,0,NBLU};
+static int CLRCUBE[3][2] = {{0,NRED},{0,NGRN},{0,NBLU}};
+static int split();
+static void cut();
+
int
new_ctab(ncolors) /* start new color table with max ncolors */
int ncolors;
@@ -66,9 +125,9 @@ int ncolors;
return(0);
/* free old tables */
if (clrtab != NULL)
- free((char *)clrtab);
+ free((void *)clrtab);
if (ctree != NULL)
- free((char *)ctree);
+ free((void *)ctree);
/* get new tables */
for (treesize = 1; treesize < ncolors; treesize <<= 1)
;
@@ -80,7 +139,7 @@ int ncolors;
/* partition color space */
cut(ctree, 0, CLRCUBE, 0, ncolors);
/* clear histogram */
- bzero(histo, sizeof(histo));
+ bzero((char *)histo, sizeof(histo));
/* return number of colors used */
return(ncolors);
}
@@ -89,11 +148,11 @@ int ncolors;
int
get_pixel(col, set_pixel) /* get pixel for color */
COLOR col;
-int (*set_pixel)();
+void (*set_pixel)();
{
int r, g, b;
int cv[3];
- register union { CNODE *t; struct tabent *e; } p;
+ register CNODE *tp;
register int h;
/* map color */
r = map_col(col,RED);
@@ -106,34 +165,33 @@ int (*set_pixel)();
/* add to histogram */
histo[cv[RED]][cv[GRN]][cv[BLU]]++;
/* find pixel in tree */
- for (p.t = ctree, h = 0; is_branch(*p.t); h++)
- if (cv[prim(*p.t)] < part(*p.t))
- p.t += 1<sum[RED] += r;
- p.e->sum[GRN] += g;
- p.e->sum[BLU] += b;
- p.e->n++;
+ clrtab[h].sum[RED] += r;
+ clrtab[h].sum[GRN] += g;
+ clrtab[h].sum[BLU] += b;
+ clrtab[h].n++;
/* recompute average */
- r = p.e->sum[RED] / p.e->n;
- g = p.e->sum[GRN] / p.e->n;
- b = p.e->sum[BLU] / p.e->n;
+ r = clrtab[h].sum[RED] / clrtab[h].n;
+ g = clrtab[h].sum[GRN] / clrtab[h].n;
+ b = clrtab[h].sum[BLU] / clrtab[h].n;
/* check for movement */
- if (p.e->n == 1 ||
- (r-p.e->ent[RED])*(r-p.e->ent[RED]) +
- (g-p.e->ent[GRN])*(g-p.e->ent[GRN]) +
- (b-p.e->ent[BLU])*(b-p.e->ent[BLU]) > MAXDST2) {
- p.e->ent[RED] = r;
- p.e->ent[GRN] = g; /* reassign pixel */
- p.e->ent[BLU] = b;
-#ifdef notdef
- printf("pixel %d = (%d,%d,%d) (%d refs)\n",
- h, r, g, b, p.e->n);
+ if (clrtab[h].n == 1 ||
+ (r-clrtab[h].ent[RED])*(r-clrtab[h].ent[RED]) +
+ (g-clrtab[h].ent[GRN])*(g-clrtab[h].ent[GRN]) +
+ (b-clrtab[h].ent[BLU])*(b-clrtab[h].ent[BLU]) > MAXDST2) {
+ clrtab[h].ent[RED] = r;
+ clrtab[h].ent[GRN] = g; /* reassign pixel */
+ clrtab[h].ent[BLU] = b;
+#ifdef DEBUG
+ sprintf(errmsg, "pixel %d = (%d,%d,%d) (%d refs)\n",
+ h, r, g, b, clrtab[h].n);
+ eputs(errmsg);
#endif
(*set_pixel)(h, r, g, b);
}
@@ -141,29 +199,41 @@ int (*set_pixel)();
}
+void
make_gmap(gam) /* make gamma correction map */
-double gam;
+double gam;
{
- extern double pow();
register int i;
for (i = 0; i < 256; i++)
clrmap[RED][i] =
clrmap[GRN][i] =
- clrmap[BLU][i] = 256.0 * pow(i/256.0, 1.0/gam);
+ clrmap[BLU][i] = 256.0 * pow((i+0.5)/256.0, 1.0/gam);
}
+void
set_cmap(rmap, gmap, bmap) /* set custom color correction map */
BYTE *rmap, *gmap, *bmap;
{
- bcopy(rmap, clrmap[RED], 256);
- bcopy(gmap, clrmap[GRN], 256);
- bcopy(bmap, clrmap[BLU], 256);
+ bcopy((char *)rmap, (char *)clrmap[RED], 256);
+ bcopy((char *)gmap, (char *)clrmap[GRN], 256);
+ bcopy((char *)bmap, (char *)clrmap[BLU], 256);
}
-static
+void
+map_color(rgb, col) /* map a color to a byte triplet */
+BYTE rgb[3];
+COLOR col;
+{
+ rgb[RED] = map_col(col,RED);
+ rgb[GRN] = map_col(col,GRN);
+ rgb[BLU] = map_col(col,BLU);
+}
+
+
+static void
cut(tree, level, box, c0, c1) /* partition color space */
register CNODE *tree;
int level;
@@ -178,7 +248,7 @@ int c0, c1;
}
/* split box */
*tree = split(box);
- bcopy(box, kb, sizeof(kb));
+ bcopy((char *)box, (char *)kb, sizeof(kb));
/* do left (lesser) branch */
kb[prim(*tree)][1] = part(*tree);
cut(tree+(1<>1);
@@ -196,7 +266,7 @@ register int box[3][2];
#define c0 r
register int r, g, b;
int pri;
- int t[HMAX], med;
+ long t[HMAX], med;
/* find dominant axis */
pri = RED;
if (box[GRN][1]-box[GRN][0] > box[pri][1]-box[pri][0])