--- ray/src/rt/colortab.c 1989/10/03 11:10:10 1.3
+++ 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
@@ -27,67 +83,76 @@ static char SCCSid[] = "$SunId$ LBL";
/* minimum box count for adaptive partition */
#define MINSAMP 7
/* maximum distance^2 before color reassign */
-#define MAXDST2 5
- /* maximum frame buffer depth */
-#define FBDEPTH 8
- /* color map resolution */
-#define MAPSIZ 256
+#define MAXDST2 12
/* map a color */
-#define map_col(c,p) clrmap[ colval(c,p)<1. ? \
- (int)(colval(c,p)*MAPSIZ) : MAPSIZ-1 ]
+#define map_col(c,p) clrmap[p][ colval(c,p)<1. ? \
+ (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)
#define part(cn) ((cn)>>2)
#define prim(cn) ((cn)&3)
#define pval(cn) ((cn)>>2)
/* our color table */
-struct tabent {
+static struct tabent {
long sum[3]; /* sum of colors using this entry */
- long n; /* number of colors */
- short ent[3]; /* current table value */
-} clrtab[1< 1< 0; h--) {
- if (is_pval(*p.t))
- break;
- if (cv[prim(*p.t)] < part(*p.t))
- p.t++; /* left branch */
+ for (tp = ctree, h = 0; is_branch(*tp); h++)
+ if (cv[prim(*tp)] < part(*tp))
+ tp += 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);
}
@@ -139,21 +199,44 @@ COLOR col;
}
-make_cmap(gam) /* make gamma correction map */
-double gam;
+void
+make_gmap(gam) /* make gamma correction map */
+double gam;
{
- extern double pow();
register int i;
- for (i = 0; i < MAPSIZ; i++)
- clrmap[i] = 256.0 * pow(i/(double)MAPSIZ, 1.0/gam);
+ for (i = 0; i < 256; i++)
+ clrmap[RED][i] =
+ clrmap[GRN][i] =
+ clrmap[BLU][i] = 256.0 * pow((i+0.5)/256.0, 1.0/gam);
}
-static
-cut(tree, height, box, c0, c1) /* partition color space */
+void
+set_cmap(rmap, gmap, bmap) /* set custom color correction map */
+BYTE *rmap, *gmap, *bmap;
+{
+ bcopy((char *)rmap, (char *)clrmap[RED], 256);
+ bcopy((char *)gmap, (char *)clrmap[GRN], 256);
+ bcopy((char *)bmap, (char *)clrmap[BLU], 256);
+}
+
+
+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 height;
+int level;
register int box[3][2];
int c0, c1;
{
@@ -165,14 +248,14 @@ 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, height-1, kb, c0, (c0+c1)>>1);
+ cut(tree+(1<>1);
/* do right branch */
kb[prim(*tree)][0] = part(*tree);
kb[prim(*tree)][1] = box[prim(*tree)][1];
- cut(tree+(1<>1, c1);
+ cut(tree+(1<<(level+1)), level+1, kb, (c0+c1)>>1, c1);
}
@@ -183,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])