--- ray/src/common/tmaptiff.c 2003/02/22 02:07:22 3.1
+++ ray/src/common/tmaptiff.c 2009/02/09 20:48:08 3.8
@@ -1,5 +1,5 @@
#ifndef lint
-static const char RCSid[] = "$Id: tmaptiff.c,v 3.1 2003/02/22 02:07:22 greg Exp $";
+static const char RCSid[] = "$Id: tmaptiff.c,v 3.8 2009/02/09 20:48:08 greg Exp $";
#endif
/*
* Perform tone mapping on TIFF input.
@@ -7,90 +7,97 @@ static const char RCSid[] = "$Id: tmaptiff.c,v 3.1 200
* Externals declared in tmaptiff.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
- * .
- */
+#include "copyright.h"
#include
-#include "tiffio.h"
+#include
#include "tmprivat.h"
+#include "tiffio.h"
#include "tmaptiff.h"
+ /* input cases we handle */
+#define TC_LOGLUV32 1
+#define TC_LOGLUV24 2
+#define TC_LOGL16 3
+#define TC_GRYFLOAT 4
+#define TC_RGBFLOAT 5
+#define TC_GRYSHORT 6
+#define TC_RGBSHORT 7
+/* figure out what kind of TIFF we have and if we can tone-map it */
+static int
+getTIFFtype(TIFF *tif)
+{
+ uint16 comp, phot, pconf;
+ uint16 samp_fmt, bits_samp;
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &pconf);
+ if (pconf != PLANARCONFIG_CONTIG)
+ return(0);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &phot);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &comp);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLEFORMAT, &samp_fmt);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bits_samp);
+ switch (phot) {
+ case PHOTOMETRIC_LOGLUV:
+ if (comp == COMPRESSION_SGILOG)
+ return(TC_LOGLUV32);
+ if (comp == COMPRESSION_SGILOG24)
+ return(TC_LOGLUV24);
+ return(0);
+ case PHOTOMETRIC_LOGL:
+ if (comp == COMPRESSION_SGILOG)
+ return(TC_LOGL16);
+ return(0);
+ case PHOTOMETRIC_MINISBLACK:
+ if (samp_fmt == SAMPLEFORMAT_UINT) {
+ if (bits_samp == 16)
+ return(TC_GRYSHORT);
+ return(0);
+ }
+ if (samp_fmt == SAMPLEFORMAT_IEEEFP) {
+ if (bits_samp == 8*sizeof(float))
+ return(TC_GRYFLOAT);
+ return(0);
+ }
+ return(0);
+ case PHOTOMETRIC_RGB:
+ if (samp_fmt == SAMPLEFORMAT_UINT) {
+ if (bits_samp == 16)
+ return(TC_RGBSHORT);
+ return(0);
+ }
+ if (samp_fmt == SAMPLEFORMAT_IEEEFP) {
+ if (bits_samp == 8*sizeof(float))
+ return(TC_RGBFLOAT);
+ return(0);
+ }
+ return(0);
+ }
+ return(0);
+}
+
+/* load and convert TIFF */
int
-tmLoadTIFF(lpp, cpp, xp, yp, fname, tp) /* load and convert TIFF */
-TMbright **lpp;
-BYTE **cpp;
-int *xp, *yp;
-char *fname;
-TIFF *tp;
+tmLoadTIFF(TMstruct *tms, TMbright **lpp, BYTE **cpp,
+ int *xp, int *yp, char *fname, TIFF *tp)
{
char *funcName = fname==NULL ? "tmLoadTIFF" : fname;
+ RGBPRIMP inppri = tms->monpri;
+ RGBPRIMS myprims;
+ float *fa;
TIFF *tif;
int err;
- union {uint16 *w; uint32 *l; MEM_PTR p;} sl;
- uint16 comp, phot, pconf;
+ union {uint16 *w; uint32 *l; float *f; MEM_PTR p;} sl;
uint32 width, height;
+ int tcase;
double stonits;
int y;
/* check arguments */
- if (tmTop == NULL)
+ if (tms == NULL)
returnErr(TM_E_TMINVAL);
- if (lpp == NULL | xp == NULL | yp == NULL |
- (fname == NULL & tp == NULL))
+ if ((lpp == NULL) | (xp == NULL) | (yp == NULL) |
+ ((fname == NULL) & (tp == NULL)))
returnErr(TM_E_ILLEGAL);
/* check/get TIFF tags */
sl.p = NULL; *lpp = NULL;
@@ -98,59 +105,122 @@ TIFF *tp;
err = TM_E_BADFILE;
if ((tif = tp) == NULL && (tif = TIFFOpen(fname, "r")) == NULL)
returnErr(TM_E_BADFILE);
- TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &phot);
- TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &comp);
+ tcase = getTIFFtype(tif);
+ if (!tcase)
+ goto done;
if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) ||
!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))
goto done;
*xp = width; *yp = height;
- TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &pconf);
- if (pconf != PLANARCONFIG_CONTIG)
- goto done;
+ if (TIFFGetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, &fa)) {
+ myprims[RED][CIEX] = fa[0];
+ myprims[RED][CIEY] = fa[1];
+ myprims[GRN][CIEX] = fa[2];
+ myprims[GRN][CIEY] = fa[3];
+ myprims[BLU][CIEX] = fa[4];
+ myprims[BLU][CIEY] = fa[5];
+ myprims[WHT][CIEX] = 1./3.;
+ myprims[WHT][CIEY] = 1./3.;
+ if (TIFFGetField(tif, TIFFTAG_WHITEPOINT, &fa)) {
+ myprims[WHT][CIEX] = fa[0];
+ myprims[WHT][CIEY] = fa[1];
+ }
+ inppri = myprims;
+ }
if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits))
stonits = 1.;
- if (phot == PHOTOMETRIC_LOGLUV) {
- if (comp != COMPRESSION_SGILOG && comp != COMPRESSION_SGILOG24)
- goto done;
+ switch (tcase) { /* set up conversion */
+ case TC_LOGLUV32:
+ case TC_LOGLUV24:
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_RAW);
sl.l = (uint32 *)malloc(width*sizeof(uint32));
- if (cpp != TM_NOCHROMP) {
- *cpp = (BYTE *)malloc(width*height*3*sizeof(BYTE));
- if (*cpp == NULL) {
- err = TM_E_NOMEM;
- goto done;
- }
- }
- } else if (phot == PHOTOMETRIC_LOGL) {
- if (comp != COMPRESSION_SGILOG)
- goto done;
+ tmSetSpace(tms, TM_XYZPRIM, stonits, NULL);
+ break;
+ case TC_LOGL16:
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT);
sl.w = (uint16 *)malloc(width*sizeof(uint16));
- } else
+ tmSetSpace(tms, tms->monpri, stonits, NULL);
+ break;
+ case TC_RGBFLOAT:
+ sl.f = (float *)malloc(width*3*sizeof(float));
+ tmSetSpace(tms, inppri, stonits, NULL);
+ break;
+ case TC_GRYFLOAT:
+ sl.f = (float *)malloc(width*sizeof(float));
+ tmSetSpace(tms, tms->monpri, stonits, NULL);
+ break;
+ case TC_RGBSHORT:
+ sl.w = (uint16 *)malloc(width*3*sizeof(uint16));
+ tmSetSpace(tms, inppri, stonits, NULL);
+ break;
+ case TC_GRYSHORT:
+ sl.w = (uint16 *)malloc(width*sizeof(uint16));
+ tmSetSpace(tms, tms->monpri, stonits, NULL);
+ break;
+ default:
+ err = TM_E_CODERR1;
goto done;
+ }
*lpp = (TMbright *)malloc(width*height*sizeof(TMbright));
- if (sl.p == NULL | *lpp == NULL) {
+ if ((sl.p == NULL) | (*lpp == NULL)) {
err = TM_E_NOMEM;
goto done;
}
- /* set input color space */
- tmSetSpace(TM_XYZPRIM, stonits);
+ switch (tcase) { /* allocate color if needed */
+ case TC_LOGLUV32:
+ case TC_LOGLUV24:
+ case TC_RGBFLOAT:
+ case TC_RGBSHORT:
+ if (cpp == TM_NOCHROMP)
+ break;
+ *cpp = (BYTE *)malloc(width*height*3*sizeof(BYTE));
+ if (*cpp == NULL) {
+ err = TM_E_NOMEM;
+ goto done;
+ }
+ break;
+ }
/* read and convert each scanline */
for (y = 0; y < height; y++) {
if (TIFFReadScanline(tif, sl.p, y, 0) < 0) {
err = TM_E_BADFILE;
break;
}
- if (phot == PHOTOMETRIC_LOGL)
- err = tmCvL16(*lpp + y*width, sl.w, width);
- else if (comp == COMPRESSION_SGILOG24)
- err = tmCvLuv24(*lpp + y*width,
+ switch (tcase) {
+ case TC_LOGLUV32:
+ err = tmCvLuv32(tms, *lpp + y*width,
cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
sl.l, width);
- else
- err = tmCvLuv32(*lpp + y*width,
+ break;
+ case TC_LOGLUV24:
+ err = tmCvLuv24(tms, *lpp + y*width,
cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
sl.l, width);
+ break;
+ case TC_LOGL16:
+ err = tmCvL16(tms, *lpp + y*width, sl.w, width);
+ break;
+ case TC_RGBFLOAT:
+ err = tmCvColors(tms, *lpp + y*width,
+ cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
+ (COLOR *)sl.f, width);
+ break;
+ case TC_GRYFLOAT:
+ err = tmCvGrays(tms, *lpp + y*width, sl.f, width);
+ break;
+ case TC_RGBSHORT:
+ err = tmCvRGB48(tms, *lpp + y*width,
+ cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width,
+ (uint16 (*)[3])sl.w, width, DEFGAM);
+ break;
+ case TC_GRYSHORT:
+ err = tmCvGray16(tms, *lpp + y*width,
+ sl.w, width, DEFGAM);
+ break;
+ default:
+ err = TM_E_CODERR1;
+ break;
+ }
if (err != TM_E_OK)
break;
}
@@ -182,60 +252,55 @@ done: /* clean up */
* As in tmMapPicture(), grey values are also returned if flags&TM_F_BW.
*/
int
-tmMapTIFF(psp, xp, yp, flags, monpri, gamval, Lddyn, Ldmax, fname, tp)
-BYTE **psp;
-int *xp, *yp;
-int flags;
-RGBPRIMP monpri;
-double gamval, Lddyn, Ldmax;
-char *fname;
-TIFF *tp;
+tmMapTIFF(BYTE **psp, int *xp, int *yp, int flags, RGBPRIMP monpri,
+ double gamval, double Lddyn, double Ldmax, char *fname, TIFF *tp)
{
char *funcName = fname==NULL ? "tmMapTIFF" : fname;
+ TMstruct *tms;
TMbright *lp;
BYTE *cp;
int err;
/* check arguments */
- if (psp == NULL | xp == NULL | yp == NULL | monpri == NULL |
- (fname == NULL & tp == NULL))
+ if ((psp == NULL) | (xp == NULL) | (yp == NULL) | (monpri == NULL) |
+ ((fname == NULL) & (tp == NULL)))
returnErr(TM_E_ILLEGAL);
if (gamval < MINGAM) gamval = DEFGAM;
if (Lddyn < MINLDDYN) Lddyn = DEFLDDYN;
if (Ldmax < MINLDMAX) Ldmax = DEFLDMAX;
if (flags & TM_F_BW) monpri = stdprims;
/* initialize tone mapping */
- if (tmInit(flags, monpri, gamval) == NULL)
+ if ((tms = tmInit(flags, monpri, gamval)) == NULL)
returnErr(TM_E_NOMEM);
/* load and convert TIFF */
cp = TM_NOCHROM;
- err = tmLoadTIFF(&lp, flags&TM_F_BW ? TM_NOCHROMP : &cp,
+ err = tmLoadTIFF(tms, &lp, flags&TM_F_BW ? TM_NOCHROMP : &cp,
xp, yp, fname, tp);
if (err != TM_E_OK) {
- tmDone(NULL);
+ tmDone(tms);
return(err);
}
if (cp == TM_NOCHROM) {
*psp = (BYTE *)malloc(*xp * *yp * sizeof(BYTE));
if (*psp == NULL) {
free((MEM_PTR)lp);
- tmDone(NULL);
+ tmDone(tms);
returnErr(TM_E_NOMEM);
}
} else
*psp = cp;
/* compute color mapping */
- err = tmAddHisto(lp, *xp * *yp, 1);
+ err = tmAddHisto(tms, lp, *xp * *yp, 1);
if (err != TM_E_OK)
goto done;
- err = tmComputeMapping(gamval, Lddyn, Ldmax);
+ err = tmComputeMapping(tms, gamval, Lddyn, Ldmax);
if (err != TM_E_OK)
goto done;
/* map pixels */
- err = tmMapPixels(*psp, lp, cp, *xp * *yp);
+ err = tmMapPixels(tms, *psp, lp, cp, *xp * *yp);
done: /* clean up */
free((MEM_PTR)lp);
- tmDone(NULL);
+ tmDone(tms);
if (err != TM_E_OK) { /* free memory on error */
free((MEM_PTR)*psp);
*psp = NULL;