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 50 namespace Imf { 51 52 class InputFile; 53 struct PreviewRgba; 54 55 56 class OutputFile 57 { 58 public: 59 60 //----------------------------------------------------------- 61 // Constructor -- opens the file and writes the file header. 62 // The file header is also copied into the OutputFile object, 63 // and can later be accessed via the header() method. 64 // Destroying this OutputFile object automatically closes 65 // the file. 66 // 67 // numThreads determines the number of threads that will be 68 // used to write the file (see ImfThreading.h). 69 //----------------------------------------------------------- 70 71 OutputFile (const char fileName[], const Header &header, 72 int numThreads = globalThreadCount()); 73 74 75 //------------------------------------------------------------ 76 // Constructor -- attaches the new OutputFile object to a file 77 // that has already been opened, and writes the file header. 78 // The file header is also copied into the OutputFile object, 79 // and can later be accessed via the header() method. 80 // Destroying this OutputFile object does not automatically 81 // close the file. 82 // 83 // numThreads determines the number of threads that will be 84 // used to write the file (see ImfThreading.h). 85 //------------------------------------------------------------ 86 87 OutputFile (OStream &os, const Header &header, 88 int numThreads = globalThreadCount()); 89 90 91 //------------------------------------------------- 92 // Destructor 93 // 94 // Destroying the OutputFile object before writing 95 // all scan lines within the data window results in 96 // an incomplete file. 97 //------------------------------------------------- 98 99 virtual ~OutputFile (); 100 101 102 //------------------------ 103 // Access to the file name 104 //------------------------ 105 106 const char * fileName () const; 107 108 109 //-------------------------- 110 // Access to the file header 111 //-------------------------- 112 113 const Header & header () const; 114 115 116 //------------------------------------------------------- 117 // Set the current frame buffer -- copies the FrameBuffer 118 // object into the OutputFile object. 119 // 120 // The current frame buffer is the source of the pixel 121 // data written to the file. The current frame buffer 122 // must be set at least once before writePixels() is 123 // called. The current frame buffer can be changed 124 // after each call to writePixels. 125 //------------------------------------------------------- 126 127 void setFrameBuffer (const FrameBuffer &frameBuffer); 128 129 130 //----------------------------------- 131 // Access to the current frame buffer 132 //----------------------------------- 133 134 const FrameBuffer & frameBuffer () const; 135 136 137 //------------------------------------------------------------------- 138 // Write pixel data: 139 // 140 // writePixels(n) retrieves the next n scan lines worth of data from 141 // the current frame buffer, starting with the scan line indicated by 142 // currentScanLine(), and stores the data in the output file, and 143 // progressing in the direction indicated by header.lineOrder(). 144 // 145 // To produce a complete and correct file, exactly m scan lines must 146 // be written, where m is equal to 147 // header().dataWindow().max.y - header().dataWindow().min.y + 1. 148 //------------------------------------------------------------------- 149 150 void writePixels (int numScanLines = 1); 151 152 153 //------------------------------------------------------------------ 154 // Access to the current scan line: 155 // 156 // currentScanLine() returns the y coordinate of the first scan line 157 // that will be read from the current frame buffer during the next 158 // call to writePixels(). 159 // 160 // If header.lineOrder() == INCREASING_Y: 161 // 162 // The current scan line before the first call to writePixels() 163 // is header().dataWindow().min.y. After writing each scan line, 164 // the current scan line is incremented by 1. 165 // 166 // If header.lineOrder() == DECREASING_Y: 167 // 168 // The current scan line before the first call to writePixels() 169 // is header().dataWindow().max.y. After writing each scan line, 170 // the current scan line is decremented by 1. 171 // 172 //------------------------------------------------------------------ 173 174 int currentScanLine () const; 175 176 177 //-------------------------------------------------------------- 178 // Shortcut to copy all pixels from an InputFile into this file, 179 // without uncompressing and then recompressing the pixel data. 180 // This file's header must be compatible with the InputFile's 181 // header: The two header's "dataWindow", "compression", 182 // "lineOrder" and "channels" attributes must be the same. 183 //-------------------------------------------------------------- 184 185 void copyPixels (InputFile &in); 186 187 188 //-------------------------------------------------------------- 189 // Updating the preview image: 190 // 191 // updatePreviewImage() supplies a new set of pixels for the 192 // preview image attribute in the file's header. If the header 193 // does not contain a preview image, updatePreviewImage() throws 194 // an Iex::LogicExc. 195 // 196 // Note: updatePreviewImage() is necessary because images are 197 // often stored in a file incrementally, a few scan lines at a 198 // time, while the image is being generated. Since the preview 199 // image is an attribute in the file's header, it gets stored in 200 // the file as soon as the file is opened, but we may not know 201 // what the preview image should look like until we have written 202 // the last scan line of the main image. 203 // 204 //-------------------------------------------------------------- 205 206 void updatePreviewImage (const PreviewRgba newPixels[]); 207 208 209 //--------------------------------------------------------- 210 // Break a scan line -- for testing and debugging only: 211 // 212 // breakScanLine(y,p,n,c) introduces an error into the 213 // output file by writing n copies of character c, starting 214 // p bytes from the beginning of the pixel data block that 215 // contains scan line y. 216 // 217 // Warning: Calling this function usually results in a 218 // broken image file. The file or parts of it may not 219 // be readable, or the file may contain bad data. 220 // 221 //--------------------------------------------------------- 222 223 void breakScanLine (int y, int offset, int length, char c); 224 225 226 struct Data; 227 228 private: 229 230 OutputFile (const OutputFile &); // not implemented 231 OutputFile & operator = (const OutputFile &); // not implemented 232 233 void initialize (const Header &header); 234 235 Data * _data; 236 }; 237 238 239 } // namespace Imf 240 241 #endif 242