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