1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 4 // Digital Ltd. LLC 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are 10 // met: 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Industrial Light & Magic nor the names of 18 // its contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 35 36 37 #ifndef INCLUDED_IMF_OUTPUT_FILE_H 38 #define INCLUDED_IMF_OUTPUT_FILE_H 39 40 //----------------------------------------------------------------------------- 41 // 42 // class OutputFile 43 // 44 //----------------------------------------------------------------------------- 45 46 #include "ImfHeader.h" 47 #include "ImfFrameBuffer.h" 48 #include "ImfThreading.h" 49 #include "ImfGenericOutputFile.h" 50 #include "ImfNamespace.h" 51 #include "ImfForward.h" 52 #include "ImfExport.h" 53 54 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER 55 56 57 class IMF_EXPORT OutputFile : public GenericOutputFile 58 { 59 public: 60 61 //----------------------------------------------------------- 62 // Constructor -- opens the file and writes the file header. 63 // The file header is also copied into the OutputFile object, 64 // and can later be accessed via the header() method. 65 // Destroying this OutputFile object automatically closes 66 // the file. 67 // 68 // numThreads determines the number of threads that will be 69 // used to write the file (see ImfThreading.h). 70 //----------------------------------------------------------- 71 72 OutputFile (const char fileName[], const Header &header, 73 int numThreads = globalThreadCount()); 74 75 76 //------------------------------------------------------------ 77 // Constructor -- attaches the new OutputFile object to a file 78 // that has already been opened, and writes the file header. 79 // The file header is also copied into the OutputFile object, 80 // and can later be accessed via the header() method. 81 // Destroying this OutputFile object does not automatically 82 // close the file. 83 // 84 // numThreads determines the number of threads that will be 85 // used to write the file (see ImfThreading.h). 86 //------------------------------------------------------------ 87 88 OutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const Header &header, 89 int numThreads = globalThreadCount()); 90 91 92 //------------------------------------------------- 93 // Destructor 94 // 95 // Destroying the OutputFile object before writing 96 // all scan lines within the data window results in 97 // an incomplete file. 98 //------------------------------------------------- 99 100 virtual ~OutputFile (); 101 102 103 //------------------------ 104 // Access to the file name 105 //------------------------ 106 107 const char * fileName () const; 108 109 110 //-------------------------- 111 // Access to the file header 112 //-------------------------- 113 114 const Header & header () const; 115 116 117 //------------------------------------------------------- 118 // Set the current frame buffer -- copies the FrameBuffer 119 // object into the OutputFile object. 120 // 121 // The current frame buffer is the source of the pixel 122 // data written to the file. The current frame buffer 123 // must be set at least once before writePixels() is 124 // called. The current frame buffer can be changed 125 // after each call to writePixels. 126 //------------------------------------------------------- 127 128 void setFrameBuffer (const FrameBuffer &frameBuffer); 129 130 131 //----------------------------------- 132 // Access to the current frame buffer 133 //----------------------------------- 134 135 const FrameBuffer & frameBuffer () const; 136 137 138 //------------------------------------------------------------------- 139 // Write pixel data: 140 // 141 // writePixels(n) retrieves the next n scan lines worth of data from 142 // the current frame buffer, starting with the scan line indicated by 143 // currentScanLine(), and stores the data in the output file, and 144 // progressing in the direction indicated by header.lineOrder(). 145 // 146 // To produce a complete and correct file, exactly m scan lines must 147 // be written, where m is equal to 148 // header().dataWindow().max.y - header().dataWindow().min.y + 1. 149 //------------------------------------------------------------------- 150 151 void writePixels (int numScanLines = 1); 152 153 154 //------------------------------------------------------------------ 155 // Access to the current scan line: 156 // 157 // currentScanLine() returns the y coordinate of the first scan line 158 // that will be read from the current frame buffer during the next 159 // call to writePixels(). 160 // 161 // If header.lineOrder() == INCREASING_Y: 162 // 163 // The current scan line before the first call to writePixels() 164 // is header().dataWindow().min.y. After writing each scan line, 165 // the current scan line is incremented by 1. 166 // 167 // If header.lineOrder() == DECREASING_Y: 168 // 169 // The current scan line before the first call to writePixels() 170 // is header().dataWindow().max.y. After writing each scan line, 171 // the current scan line is decremented by 1. 172 // 173 //------------------------------------------------------------------ 174 175 int currentScanLine () const; 176 177 178 //-------------------------------------------------------------- 179 // Shortcut to copy all pixels from an InputFile into this file, 180 // without uncompressing and then recompressing the pixel data. 181 // This file's header must be compatible with the InputFile's 182 // header: The two header's "dataWindow", "compression", 183 // "lineOrder" and "channels" attributes must be the same. 184 //-------------------------------------------------------------- 185 186 void copyPixels (InputFile &in); 187 188 //------------------------------------------------------------- 189 // Shortcut to copy all pixels from an InputPart into this file 190 // - equivalent to copyPixel(InputFile &in) but for multipart files 191 //--------------------------------------------------------------- 192 193 void copyPixels (InputPart &in); 194 195 196 197 //-------------------------------------------------------------- 198 // Updating the preview image: 199 // 200 // updatePreviewImage() supplies a new set of pixels for the 201 // preview image attribute in the file's header. If the header 202 // does not contain a preview image, updatePreviewImage() throws 203 // an IEX_NAMESPACE::LogicExc. 204 // 205 // Note: updatePreviewImage() is necessary because images are 206 // often stored in a file incrementally, a few scan lines at a 207 // time, while the image is being generated. Since the preview 208 // image is an attribute in the file's header, it gets stored in 209 // the file as soon as the file is opened, but we may not know 210 // what the preview image should look like until we have written 211 // the last scan line of the main image. 212 // 213 //-------------------------------------------------------------- 214 215 void updatePreviewImage (const PreviewRgba newPixels[]); 216 217 218 //--------------------------------------------------------- 219 // Break a scan line -- for testing and debugging only: 220 // 221 // breakScanLine(y,p,n,c) introduces an error into the 222 // output file by writing n copies of character c, starting 223 // p bytes from the beginning of the pixel data block that 224 // contains scan line y. 225 // 226 // Warning: Calling this function usually results in a 227 // broken image file. The file or parts of it may not 228 // be readable, or the file may contain bad data. 229 // 230 //--------------------------------------------------------- 231 232 void breakScanLine (int y, int offset, int length, char c); 233 234 235 struct Data; 236 237 private: 238 239 //------------------------------------------------------------ 240 // Constructor -- attaches the OutputStreamMutex to the 241 // given one from MultiPartOutputFile. Set the previewPosition 242 // and lineOffsetsPosition which have been acquired from 243 // the constructor of MultiPartOutputFile as well. 244 //------------------------------------------------------------ 245 OutputFile (const OutputPartData* part); 246 247 OutputFile (const OutputFile &); // not implemented 248 OutputFile & operator = (const OutputFile &); // not implemented 249 250 void initialize (const Header &header); 251 252 Data * _data; 253 254 255 friend class MultiPartOutputFile; 256 257 }; 258 259 260 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT 261 262 263 #endif 264