PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 00037 #ifndef INCLUDED_IMF_OUTPUT_FILE_H 00038 #define INCLUDED_IMF_OUTPUT_FILE_H 00039 00040 //----------------------------------------------------------------------------- 00041 // 00042 // class OutputFile 00043 // 00044 //----------------------------------------------------------------------------- 00045 00046 #include <ImfHeader.h> 00047 #include <ImfFrameBuffer.h> 00048 #include <ImfThreading.h> 00049 00050 namespace Imf { 00051 00052 class InputFile; 00053 struct PreviewRgba; 00054 00055 00056 class OutputFile 00057 { 00058 public: 00059 00060 //----------------------------------------------------------- 00061 // Constructor -- opens the file and writes the file header. 00062 // The file header is also copied into the OutputFile object, 00063 // and can later be accessed via the header() method. 00064 // Destroying this OutputFile object automatically closes 00065 // the file. 00066 // 00067 // numThreads determines the number of threads that will be 00068 // used to write the file (see ImfThreading.h). 00069 //----------------------------------------------------------- 00070 00071 OutputFile (const char fileName[], const Header &header, 00072 int numThreads = globalThreadCount()); 00073 00074 00075 //------------------------------------------------------------ 00076 // Constructor -- attaches the new OutputFile object to a file 00077 // that has already been opened, and writes the file header. 00078 // The file header is also copied into the OutputFile object, 00079 // and can later be accessed via the header() method. 00080 // Destroying this OutputFile object does not automatically 00081 // close the file. 00082 // 00083 // numThreads determines the number of threads that will be 00084 // used to write the file (see ImfThreading.h). 00085 //------------------------------------------------------------ 00086 00087 OutputFile (OStream &os, const Header &header, 00088 int numThreads = globalThreadCount()); 00089 00090 00091 //------------------------------------------------- 00092 // Destructor 00093 // 00094 // Destroying the OutputFile object before writing 00095 // all scan lines within the data window results in 00096 // an incomplete file. 00097 //------------------------------------------------- 00098 00099 virtual ~OutputFile (); 00100 00101 00102 //------------------------ 00103 // Access to the file name 00104 //------------------------ 00105 00106 const char * fileName () const; 00107 00108 00109 //-------------------------- 00110 // Access to the file header 00111 //-------------------------- 00112 00113 const Header & header () const; 00114 00115 00116 //------------------------------------------------------- 00117 // Set the current frame buffer -- copies the FrameBuffer 00118 // object into the OutputFile object. 00119 // 00120 // The current frame buffer is the source of the pixel 00121 // data written to the file. The current frame buffer 00122 // must be set at least once before writePixels() is 00123 // called. The current frame buffer can be changed 00124 // after each call to writePixels. 00125 //------------------------------------------------------- 00126 00127 void setFrameBuffer (const FrameBuffer &frameBuffer); 00128 00129 00130 //----------------------------------- 00131 // Access to the current frame buffer 00132 //----------------------------------- 00133 00134 const FrameBuffer & frameBuffer () const; 00135 00136 00137 //------------------------------------------------------------------- 00138 // Write pixel data: 00139 // 00140 // writePixels(n) retrieves the next n scan lines worth of data from 00141 // the current frame buffer, starting with the scan line indicated by 00142 // currentScanLine(), and stores the data in the output file, and 00143 // progressing in the direction indicated by header.lineOrder(). 00144 // 00145 // To produce a complete and correct file, exactly m scan lines must 00146 // be written, where m is equal to 00147 // header().dataWindow().max.y - header().dataWindow().min.y + 1. 00148 //------------------------------------------------------------------- 00149 00150 void writePixels (int numScanLines = 1); 00151 00152 00153 //------------------------------------------------------------------ 00154 // Access to the current scan line: 00155 // 00156 // currentScanLine() returns the y coordinate of the first scan line 00157 // that will be read from the current frame buffer during the next 00158 // call to writePixels(). 00159 // 00160 // If header.lineOrder() == INCREASING_Y: 00161 // 00162 // The current scan line before the first call to writePixels() 00163 // is header().dataWindow().min.y. After writing each scan line, 00164 // the current scan line is incremented by 1. 00165 // 00166 // If header.lineOrder() == DECREASING_Y: 00167 // 00168 // The current scan line before the first call to writePixels() 00169 // is header().dataWindow().max.y. After writing each scan line, 00170 // the current scan line is decremented by 1. 00171 // 00172 //------------------------------------------------------------------ 00173 00174 int currentScanLine () const; 00175 00176 00177 //-------------------------------------------------------------- 00178 // Shortcut to copy all pixels from an InputFile into this file, 00179 // without uncompressing and then recompressing the pixel data. 00180 // This file's header must be compatible with the InputFile's 00181 // header: The two header's "dataWindow", "compression", 00182 // "lineOrder" and "channels" attributes must be the same. 00183 //-------------------------------------------------------------- 00184 00185 void copyPixels (InputFile &in); 00186 00187 00188 //-------------------------------------------------------------- 00189 // Updating the preview image: 00190 // 00191 // updatePreviewImage() supplies a new set of pixels for the 00192 // preview image attribute in the file's header. If the header 00193 // does not contain a preview image, updatePreviewImage() throws 00194 // an Iex::LogicExc. 00195 // 00196 // Note: updatePreviewImage() is necessary because images are 00197 // often stored in a file incrementally, a few scan lines at a 00198 // time, while the image is being generated. Since the preview 00199 // image is an attribute in the file's header, it gets stored in 00200 // the file as soon as the file is opened, but we may not know 00201 // what the preview image should look like until we have written 00202 // the last scan line of the main image. 00203 // 00204 //-------------------------------------------------------------- 00205 00206 void updatePreviewImage (const PreviewRgba newPixels[]); 00207 00208 00209 //--------------------------------------------------------- 00210 // Break a scan line -- for testing and debugging only: 00211 // 00212 // breakScanLine(y,p,n,c) introduces an error into the 00213 // output file by writing n copies of character c, starting 00214 // p bytes from the beginning of the pixel data block that 00215 // contains scan line y. 00216 // 00217 // Warning: Calling this function usually results in a 00218 // broken image file. The file or parts of it may not 00219 // be readable, or the file may contain bad data. 00220 // 00221 //--------------------------------------------------------- 00222 00223 void breakScanLine (int y, int offset, int length, char c); 00224 00225 00226 struct Data; 00227 00228 private: 00229 00230 OutputFile (const OutputFile &); // not implemented 00231 OutputFile & operator = (const OutputFile &); // not implemented 00232 00233 void initialize (const Header &header); 00234 00235 Data * _data; 00236 }; 00237 00238 00239 } // namespace Imf 00240 00241 #endif