////////////////////////////////////////////////////////////////////// // // Pixie // // Copyright © 1999 - 2003, Okan Arikan // // Contact: okan@cs.berkeley.edu // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // File : openexr.cpp // Classes : // Description : This file implements the output device // that sends the image into an openEXR file // //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #ifdef WIN32 // Sadly, OpenEXR source code is very poorly written (Sorry ILM) // I suspect a lot of things will change in the future. Rather than linking against the static version, // we'll link against the DLL on windows platforms // FIXME: Check if the OpenEXR dll's are distributable with Pixie // Disable the poor exception handling warnings #pragma warning (disable: 4290) // Disable the poor non standard template usage warnings #pragma warning (disable: 4231) #define OPENEXR_DLL #endif #include #include #include #include #include #include #include #include "common/global.h" #include "common/algebra.h" #include "ri/dsply.h" // The display driver interface using namespace Imf; using namespace Imath; /////////////////////////////////////////////////////////////////////// // Class : CFramebuffer // Description : Holds the framebuffer // Comments : // Date last edited : 5/9/2002 class CFramebuffer { public: /////////////////////////////////////////////////////////////////////// // Class : CFramebuffer // Method : CFramebuffer // Description : Ctor // Return Value : - // Comments : // Date last edited : 5/9/2002 CFramebuffer(const char *name,int width,int height,int numSamples,const char *samples,TDisplayParameterFunction findParameter) { int i; float *tmp; char *software; const char *compression = NULL; Header header(width,height); // set the compression (must be before opening the file) compression = (char *) findParameter("compression",STRING_PARAMETER,1); // The default compression is none if (compression != NULL) { if (strcmp(compression,"RLE") == 0) { header.compression() = RLE_COMPRESSION; } else if (strcmp(compression,"ZIPS") == 0) { header.compression() = ZIPS_COMPRESSION; } else if (strcmp(compression,"ZIP") == 0) { header.compression() = ZIP_COMPRESSION; } else if (strcmp(compression,"PIZ") == 0) { header.compression() = PIZ_COMPRESSION; } else if (strcmp(compression,"PXR24") == 0) { header.compression() = PXR24_COMPRESSION; } } // Get the gamma params (are these needed) if ((tmp = (float *) findParameter("gamma",FLOAT_PARAMETER,1))) { gamma = tmp[0]; } if ((tmp = (float *) findParameter("gain",FLOAT_PARAMETER,1))) { gain = tmp[0]; } // Software attribute software = (char *) findParameter("Software",STRING_PARAMETER,1); if (software != NULL) header.insert("Software",StringAttribute(software)); // Add the channels const char *channelName = "R\0G\0B\0A\0Z\0"; for (int curSample=0;curSamplewidth = width; this->height = height; this->numSamples = numSamples; } /////////////////////////////////////////////////////////////////////// // Class : CFramebuffer // Method : ~CFramebuffer // Description : Dtor // Return Value : - // Comments : // Date last edited : 11/28/2001 ~CFramebuffer() { int i; if (file != NULL){ delete file; delete framebuffer; } else { return; } for (i=0;i 0) { for (i=0;i qmax) data[i] = qmax; } } #endif for (i=0;iinsert (channelName, // channel name Slice (HALF, // channel type (char *) (scanlines[lastSavedLine] + curSample), // basePtr pixelSize, // xStride 0)); // yStride (0 as we're scan at a time) channelName += 2; } file->setFrameBuffer(*framebuffer); try{ file->writePixels(1); }catch(...){ // deal with errors but shutting down printf("Error writing to openexr file!\n"); delete file; delete framebuffer; file = NULL; framebuffer = NULL; } delete [] scanlines[lastSavedLine]; scanlines[lastSavedLine] = NULL; } } else { break; } } } } half **scanlines; int *scanlineUsage; int width,height; OutputFile *file; FrameBuffer *framebuffer; int pixelSize; int numSamples; int lastSavedLine; float gamma,gain; #if 0 float qmin,qmax,qone,qzero,qamp; int bitspersample,sampleformat; #endif }; /////////////////////////////////////////////////////////////////////// // Function : displayStart // Description : Begin receiving an image // Return Value : The handle to the image on success, NULL othervise // Comments : // Date last edited : 11/28/2001 void *displayStart(const char *name,int width,int height,int numSamples,const char *samples,TDisplayParameterFunction findParameter) { CFramebuffer *fb = new CFramebuffer(name,width,height,numSamples,samples,findParameter); if (fb->file == NULL) { // If we could not open the image, return NULL delete fb; return NULL; } return fb; } /////////////////////////////////////////////////////////////////////// // Function : displayData // Description : Receive image data // Return Value : TRUE on success, FALSE otherwise // Comments : // Date last edited : 11/28/2001 int displayData(void *im,int x,int y,int w,int h,float *data) { CFramebuffer *fb = (CFramebuffer *) im; assert(fb != NULL); fb->write(x,y,w,h,data); return TRUE; } /////////////////////////////////////////////////////////////////////// // Function : displayFinish // Description : Finish receiving an image // Return Value : TRUE on success, FALSE othervise // Comments : // Date last edited : 11/28/2001 void displayFinish(void *im) { CFramebuffer *fb = (CFramebuffer *) im; assert(fb != NULL); delete fb; }