--- ray/src/common/tmaptiff.c 2003/02/22 02:07:22 3.1 +++ ray/src/common/tmaptiff.c 2003/07/14 04:56:54 3.3 @@ -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.3 2003/07/14 04:56:54 greg Exp $"; #endif /* * Perform tone mapping on TIFF input. @@ -7,83 +7,88 @@ 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 "tmprivat.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(TMbright **lpp, BYTE **cpp, int *xp, int *yp, char *fname, TIFF *tp) { char *funcName = fname==NULL ? "tmLoadTIFF" : fname; + RGBPRIMP inppri = tmTop->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 */ @@ -98,59 +103,121 @@ 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(TM_XYZPRIM, stonits); + break; + case TC_LOGL16: TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_16BIT); sl.w = (uint16 *)malloc(width*sizeof(uint16)); - } else + tmSetSpace(tmTop->monpri, stonits); + break; + case TC_RGBFLOAT: + sl.f = (float *)malloc(width*3*sizeof(float)); + tmSetSpace(inppri, stonits); + break; + case TC_GRYFLOAT: + sl.f = (float *)malloc(width*sizeof(float)); + tmSetSpace(tmTop->monpri, stonits); + break; + case TC_RGBSHORT: + sl.w = (uint16 *)malloc(width*3*sizeof(uint16)); + tmSetSpace(inppri, stonits); + break; + case TC_GRYSHORT: + sl.w = (uint16 *)malloc(width*sizeof(uint16)); + tmSetSpace(tmTop->monpri, stonits); + break; + default: + err = TM_E_CODERR1; goto done; + } *lpp = (TMbright *)malloc(width*height*sizeof(TMbright)); 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(*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(*lpp + y*width, cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, sl.l, width); + break; + case TC_LOGL16: + err = tmCvL16(*lpp + y*width, sl.w, width); + break; + case TC_RGBFLOAT: + err = tmCvColors(*lpp + y*width, + cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, + (COLOR *)sl.f, width); + break; + case TC_GRYFLOAT: + err = tmCvGrays(*lpp + y*width, sl.f, width); + break; + case TC_RGBSHORT: + err = tmCvRGB48(*lpp + y*width, + cpp==TM_NOCHROMP ? TM_NOCHROM : *cpp+y*3*width, + (uint16 (*)[3])sl.w, width, DEFGAM); + break; + case TC_GRYSHORT: + err = tmCvGray16(*lpp + y*width, sl.w, width, DEFGAM); + break; + default: + err = TM_E_CODERR1; + break; + } if (err != TM_E_OK) break; } @@ -182,14 +249,8 @@ 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; TMbright *lp;