--- ray/src/px/pcond2.c 1996/10/03 16:52:49 3.1 +++ ray/src/px/pcond2.c 2004/11/14 16:57:18 3.14 @@ -1,14 +1,13 @@ -/* Copyright (c) 1996 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: pcond2.c,v 3.14 2004/11/14 16:57:18 greg Exp $"; #endif - /* * Input and output conditioning routines for pcond. + * Added white-balance adjustment 10/01 (GW). */ #include "pcond.h" +#include "warp3d.h" RGBPRIMP inprims = stdprims; /* input primaries */ @@ -19,17 +18,31 @@ double (*lumf)() = rgblum; /* input luminance functio double inpexp = 1.0; /* input exposure value */ char *mbcalfile = NULL; /* macbethcal mapping file */ +char *cwarpfile = NULL; /* color space warping file */ -static struct mbc mbcond; /* macbethcal conditioning struct */ +static struct mbc { + COLORMAT cmat; + float xa[3][6], ya[3][6]; + COLOR cmin, cmax; +} mbcond; /* macbethcal conditioning struct */ +static WARP3D *cwarp; /* color warping structure */ + static COLOR *scanbuf; /* scanline processing buffer */ static int nread; /* number of scanlines processed */ +static void sfscan(COLOR *sl, int len, double sf); +static void matscan(COLOR *sl, int len, COLORMAT mat); +static void mbscan(COLOR *sl, int len, struct mbc *mb); +static void cwscan(COLOR *sl, int len, WARP3D *wp); +static void getmbcalfile(char *fn, struct mbc *mb); -double -rgblum(clr, scotopic) /* compute (scotopic) luminance of RGB color */ -COLOR clr; -int scotopic; + +extern double +rgblum( /* compute (scotopic) luminance of RGB color */ + COLOR clr, + int scotopic +) { if (scotopic) /* approximate */ return( WHTSEFFICACY * (colval(clr,RED)*.062 + @@ -40,10 +53,11 @@ int scotopic; } -double -cielum(xyz, scotopic) /* compute (scotopic) luminance of CIE color */ -COLOR xyz; -int scotopic; +extern double +cielum( /* compute (scotopic) luminance of CIE color */ + COLOR xyz, + int scotopic +) { if (scotopic) /* approximate */ return(colval(xyz,CIEY) * @@ -53,23 +67,24 @@ int scotopic; } -COLOR * -nextscan() /* read and condition next scanline */ +extern COLOR * +nextscan(void) /* read and condition next scanline */ { if (nread >= numscans(&inpres)) { -#ifdef DEBUG - fputs("done\n", stderr); -#endif - return(NULL); + if (cwarpfile != NULL) + free3dw(cwarp); + free((void *)scanbuf); + return(scanbuf = NULL); } - if (freadscan(scanbuf, scanlen(&inpres), infp) < 0) { + if (what2do&DO_ACUITY) + acuscan(scanbuf, nread); + else if (freadscan(scanbuf, scanlen(&inpres), infp) < 0) { fprintf(stderr, "%s: %s: scanline read error\n", progname, infn); exit(1); } - nread++; if (what2do&DO_VEIL) /* add veiling */ - addveil(scanbuf, nread-1); + addveil(scanbuf, nread); if (what2do&DO_COLOR) /* scotopic color loss */ scotscan(scanbuf, scanlen(&inpres)); if (what2do&DO_LINEAR) /* map luminances */ @@ -78,37 +93,44 @@ nextscan() /* read and condition next scanline */ mapscan(scanbuf, scanlen(&inpres)); if (mbcalfile != NULL) /* device color correction */ mbscan(scanbuf, scanlen(&inpres), &mbcond); - else if (lumf == cielum | inprims != outprims) + else if (cwarpfile != NULL) /* device color space warp */ + cwscan(scanbuf, scanlen(&inpres), cwarp); + else if ((lumf == cielum) | (inprims != outprims)) matscan(scanbuf, scanlen(&inpres), mbcond.cmat); + nread++; return(scanbuf); } -COLOR * -firstscan() /* return first processed scanline */ +extern COLOR * +firstscan(void) /* return first processed scanline */ { if (mbcalfile != NULL) /* load macbethcal file */ getmbcalfile(mbcalfile, &mbcond); - else + else if (cwarpfile != NULL) { + if ((cwarp = load3dw(cwarpfile, NULL)) == NULL) + syserror(cwarpfile); + } else if (lumf == rgblum) - comprgb2rgbmat(mbcond.cmat, inprims, outprims); + comprgb2rgbWBmat(mbcond.cmat, inprims, outprims); else - compxyz2rgbmat(mbcond.cmat, outprims); + compxyz2rgbWBmat(mbcond.cmat, outprims); + if (what2do&DO_ACUITY) + initacuity(); scanbuf = (COLOR *)malloc(scanlen(&inpres)*sizeof(COLOR)); if (scanbuf == NULL) syserror("malloc"); nread = 0; -#ifdef DEBUG - fprintf(stderr, "%s: processing image...", progname); -#endif return(nextscan()); } -sfscan(sl, len, sf) /* apply scalefactor to scanline */ -register COLOR *sl; -int len; -double sf; +static void +sfscan( /* apply scalefactor to scanline */ + register COLOR *sl, + int len, + double sf +) { while (len--) { scalecolor(sl[0], sf); @@ -117,27 +139,34 @@ double sf; } -matscan(sl, len, mat) /* apply color matrix to scaline */ -register COLOR *sl; -int len; -COLORMAT mat; +static void +matscan( /* apply color matrix to scaline */ + register COLOR *sl, + int len, + COLORMAT mat +) { while (len--) { colortrans(sl[0], mat, sl[0]); + clipgamut(sl[0], bright(sl[0]), CGAMUT, cblack, cwhite); sl++; } } -mbscan(sl, len, mb) /* apply macbethcal adj. to scaline */ -COLOR *sl; -int len; -register struct mbc *mb; +static void +mbscan( /* apply macbethcal adj. to scaline */ + COLOR *sl, + int len, + register struct mbc *mb +) { double d; register int i, j; while (len--) { + colortrans(sl[0], mb->cmat, sl[0]); + clipgamut(sl[0], bright(sl[0]), CGAMUT, mb->cmin, mb->cmax); for (i = 0; i < 3; i++) { d = colval(sl[0],i); for (j = 0; j < 4 && mb->xa[i][j+1] <= d; j++) @@ -146,20 +175,45 @@ register struct mbc *mb; (d - mb->xa[i][j])*mb->ya[i][j+1] ) / (mb->xa[i][j+1] - mb->xa[i][j]); } - colortrans(sl[0], mb->cmat, sl[0]); sl++; } } -getmbcalfile(fn, mb) /* load macbethcal file */ -char *fn; -register struct mbc *mb; +static void +cwscan( /* apply color space warp to scaline */ + COLOR *sl, + int len, + WARP3D *wp +) { - extern char *fgets(); + int rval; + + while (len--) { + rval = warp3d(sl[0], sl[0], wp); + if (rval & W3ERROR) + syserror("warp3d"); + if (rval & W3BADMAP) { + fprintf(stderr, "%s: %s: bad color space map\n", + progname, cwarpfile); + exit(1); + } + clipgamut(sl[0], bright(sl[0]), CGAMUT, cblack, cwhite); + sl++; + } +} + + +static void +getmbcalfile( /* load macbethcal file */ + char *fn, + register struct mbc *mb +) +{ char buf[128]; FILE *fp; int inpflags = 0; + register int i; if ((fp = fopen(fn, "r")) == NULL) syserror(fn); @@ -238,4 +292,15 @@ register struct mbc *mb; exit(1); } fclose(fp); + /* compute gamut */ + for (i = 0; i < 3; i++) { + colval(mb->cmin,i) = mb->xa[i][0] - + mb->ya[i][0] * + (mb->xa[i][1]-mb->xa[i][0]) / + (mb->ya[i][1]-mb->ya[i][0]); + colval(mb->cmax,i) = mb->xa[i][4] + + (1.-mb->ya[i][4]) * + (mb->xa[i][5] - mb->xa[i][4]) / + (mb->ya[i][5] - mb->ya[i][4]); + } }