/* =========================================================================== Copyright (c) 1994-2000 K.U.Leuven This software is provided AS IS, without any express or implied warranty. In no event will the authors or the K.U.Leuven be held liable for any damages or loss of profit arising from the use or non-fitness for a particular purpose of this software. See file 0README in the home directory of RenderPark for details about copyrights and licensing. =========================================================================== NAME: image TYPE: c++ code PROJECT: Renderpark - Image output CONTENT: ANSI-C interface to the image output library =========================================================================== AUTHORS: pb Philippe Bekaert jp Jan Prikryl =========================================================================== HISTORY: 06-Mar-00 11:23:34 jp last modification 06-Mar-00 11:22:51 jp typo in NEW_TIFF_GENERAL_HANDLE for no TIFF 20-Sep-99 21:51:43 jp changes for libtiff autoconf 03-Oct-98 15:26:04 pb released =========================================================================== */ #include #include #include "mystrings.h" #include "image.H" #include "color.h" #include "error.h" /* --------------------------------------------------------------------------- RGB x LOGLUV TIFF MACROS ------------------------------------------------------------------------- */ #define NEW_TIFF_RGB_HANDLE(_fn, _w, _h) \ new LZWRGBTiffOutputHandle(_fn, _w, _h) #ifdef HAVE_LIBTIFF /* TIFFLIB: We have found libtiff somewhere on the system. */ #ifdef HAVE_TIFFINITSGILOG /* TIFFLIB/LOGLUV: The libtiff supports high dynamic range images. */ #define IS_TIFF_EXT(_ext) \ IS_TIFF_RGB_EXT(_ext) || IS_TIFF_LOGLUV_EXT(_ext) #define PRE_TIFF_LOGLUV_HANDLE(_func) #define NEW_TIFF_LOGLUV_HANDLE(_fn, _w, _h, _lum) \ new SGILogLuvTiffOutputHandle(_fn, _w, _h, _lum) #define NEW_TIFF_LOGLUV_HANDLE_HDR(_fn, _w, _h, _hdr, _lum) \ _hdr ? \ (ImageOutputHandle *) NEW_TIFF_LOGLUV_HANDLE(_fn, _w, _h, _lum) : /* TIFFLIB/LOGLUV: End of definitions. */ #else /* TIFFLIB/RGB: The libtiff suports RGB only. */ #define IS_TIFF_EXT(_ext) \ IS_TIFF_RGB_EXT(_ext) #define PRE_TIFF_LOGLUV_HANDLE(_func) \ Error(_func, \ "Your libtiff does not support high dynamic range images.") #define NEW_TIFF_LOGLUV_HANDLE(_fn, _w, _h, _lum) \ (ImageOutputHandle *)NULL #define NEW_TIFF_LOGLUV_HANDLE_HDR(_fn, _w, _h, _hdr, _lum) /* TIFFLIB/RGB: End of definitions. */ #endif /* TIFFLIB: Common code for both LOGLUV and RGB libtiff. */ #define PRE_TIFF_GENERAL_HANDLE(_func) #define NEW_TIFF_GENERAL_HANDLE(_fn, _w, _h, _hdr, _lum) \ NEW_TIFF_LOGLUV_HANDLE_HDR(_fn, _w, _h, _hdr, _lum) \ NEW_TIFF_RGB_HANDLE(_fn, _w, _h) /* TIFFLIB: End of definitions. */ #else /* NO TIFFLIB: No suport for any kind of TIFF files. */ #define PRE_TIFF_GENERAL_HANDLE(_func) \ Error(_func, "TIFF support has not been compiled in") #define NEW_TIFF_GENERAL_HANDLE(_fn, _w, _h, _hdr, _lum) \ (ImageOutputHandle *)NULL /* NO TIFFLIB: End of definitions. */ #endif /* --------------------------------------------------------------------------- DEFAULT IMPLEMENTATIONS ------------------------------------------------------------------------- */ int ImageOutputHandle::WriteDisplayRGB(unsigned char *) { static bool wgiv = false; if (!wgiv) { fprintf(stderr, "%s does not support display RGB output.\n", drivername); wgiv = true; } return 0; } #define GAMMACORRECT(rgb, gamma) { \ (rgb).r = (gamma)[0] == 1. ? (rgb).r : pow((rgb).r, 1./(gamma)[0]); \ (rgb).g = (gamma)[1] == 1. ? (rgb).g : pow((rgb).g, 1./(gamma)[1]); \ (rgb).b = (gamma)[2] == 1. ? (rgb).b : pow((rgb).b, 1./(gamma)[2]); \ } int ImageOutputHandle::WriteDisplayRGB(float *rgbflt) { #ifdef RGBCOLORS unsigned char *rgb = new unsigned char[3*width]; for (int i=0; i=fname && *ext!='.') ext--; if ((!strcmp(ext, ".Z")) || (!strcmp(ext, ".gz")) || (!strcmp(ext, ".bz")) || (!strcmp(ext, ".bz2"))) { ext--; /* before '.' */ while (ext>=fname && *ext!='.') ext--; /* find extension before .gz or .Z */ } return ext+1; /* after '.' */ } /* Examines filename extension in order to decide what file format to * use to write radiance image.*/ ImageOutputHandle * CreateRadianceImageOutputHandle(char *fname, FILE *fp, int ispipe, int width, int height, float reference_luminance) { if (fp) { char *ext = ispipe ? (char *)"ppm" : ImageFileExtension(fname); // assume PPM format if pipe if (strncasecmp(ext, "ppm", 3) == 0) { return new PPMOutputHandle(fp, width, height); } #ifdef HAVE_LIBTIFF else if (IS_TIFF_EXT(ext)) { if (ispipe) { Error("CreateRadianceImageOutputHandle", "Can't write TIFF output to a pipe.\n"); return (ImageOutputHandle *)0; } freopen("/dev/null", "w", fp); /* the TIFF library maintains its own file pointer */ if (IS_TIFF_LOGLUV_EXT(ext)) { PRE_TIFF_LOGLUV_HANDLE("CreateRadianceImageOutputHandle"); return NEW_TIFF_LOGLUV_HANDLE(fname, width, height, reference_luminance); } else { return NEW_TIFF_RGB_HANDLE(fname, width, height); } } #endif /* olaf: HDR PIC output */ else if(strncasecmp(ext, "pic", 3) == 0) { if (ispipe) { Error("CreateRadianceImageOutputHandle", "Can't write PIC output to a pipe.\n"); return (ImageOutputHandle *)0; } freopen("/dev/null", "w", fp); return new PicOutputHandle(fname, width, height); } else { PRE_TIFF_GENERAL_HANDLE("CreateRadianceImageOutputHandle"); Error("CreateRadianceImageOutputHandle", "Can't save high dynamic range images to a '%s' file.", ext); return (ImageOutputHandle *)0; } } return (ImageOutputHandle *)0; } /* Same, but for writing "normal" display RGB images instead radiance image. */ ImageOutputHandle * CreateImageOutputHandle(char *fname, FILE *fp, int ispipe, int width, int height) { if (fp) { char *ext = ispipe ? (char *)"ppm" : ImageFileExtension(fname); if (strncasecmp(ext, "ppm", 3) == 0) { return new PPMOutputHandle(fp, width, height); } #ifdef HAVE_LIBTIFF else if (IS_TIFF_RGB_EXT(ext)) { if (ispipe) { Error("CreateImageOutputHandle", "Can't write TIFF output to a pipe.\n"); return (ImageOutputHandle *)0; } freopen("/dev/null", "w", fp); /* the TIFF library maintains its own file pointer */ return new LZWRGBTiffOutputHandle(fname, width, height); } #endif else { PRE_TIFF_GENERAL_HANDLE("CreateImageOutputHandle"); Error("CreateImageOutputHandle", "Can't save display-RGB images to a '%s' file.\n", ext); return (ImageOutputHandle *)0; } } return (ImageOutputHandle *)0; } ImageOutputHandle * CreatePPMOutputHandle(FILE *fp, int width, int height) { return (ImageOutputHandle *)new PPMOutputHandle(fp, width, height); } ImageOutputHandle * CreateTiffOutputHandle(char *filename, int width, int height, int high_dynamic_range, float stonits) { PRE_TIFF_GENERAL_HANDLE("CreateTiffOutputHandle"); return NEW_TIFF_GENERAL_HANDLE(filename, width, height, high_dynamic_range, stonits <= EPSILON ? 1. : stonits); } int WriteDisplayRGB(ImageOutputHandle *img, unsigned char *data) { return img->WriteDisplayRGB(data); } int WriteRadianceRGB(ImageOutputHandle *img, float *data) { return img->WriteRadianceRGB(data); } int WriteRadianceXYZ(ImageOutputHandle *img, float *data) { return img->WriteRadianceXYZ(data); } void DeleteImageOutputHandle(ImageOutputHandle *img) { delete img; }