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 #ifndef INCLUDED_IMF_TILED_RGBA_FILE_H
37 #define INCLUDED_IMF_TILED_RGBA_FILE_H
38 
39 //-----------------------------------------------------------------------------
40 //
41 //	Simplified RGBA image I/O for tiled files
42 //
43 //	class TiledRgbaOutputFile
44 //	class TiledRgbaInputFile
45 //
46 //-----------------------------------------------------------------------------
47 
48 #include "ImfHeader.h"
49 #include "ImfFrameBuffer.h"
50 #include "ImathVec.h"
51 #include "ImathBox.h"
52 #include "half.h"
53 #include "ImfTileDescription.h"
54 #include "ImfRgba.h"
55 #include "ImfThreading.h"
56 #include <string>
57 #include "ImfNamespace.h"
58 #include "ImfForward.h"
59 
60 
61 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
62 
63 
64 //
65 // Tiled RGBA output file.
66 //
67 
68 class IMF_EXPORT TiledRgbaOutputFile
69 {
70   public:
71 
72     //---------------------------------------------------
73     // Constructor -- rgbaChannels, tileXSize, tileYSize,
74     // levelMode, and levelRoundingMode overwrite the
75     // channel list and tile description attribute in the
76     // header that is passed as an argument to the
77     // constructor.
78     //---------------------------------------------------
79 
80     TiledRgbaOutputFile (const char name[],
81 			 const Header &header,
82 			 RgbaChannels rgbaChannels,
83 			 int tileXSize,
84 			 int tileYSize,
85 			 LevelMode mode,
86 			 LevelRoundingMode rmode = ROUND_DOWN,
87                          int numThreads = globalThreadCount ());
88 
89 
90     //---------------------------------------------------
91     // Constructor -- like the previous one, but the new
92     // TiledRgbaOutputFile is attached to a file that has
93     // already been opened by the caller.  Destroying
94     // TiledRgbaOutputFileObjects constructed with this
95     // constructor does not automatically close the
96     // corresponding files.
97     //---------------------------------------------------
98 
99     TiledRgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
100 			 const Header &header,
101 			 RgbaChannels rgbaChannels,
102 			 int tileXSize,
103 			 int tileYSize,
104 			 LevelMode mode,
105 			 LevelRoundingMode rmode = ROUND_DOWN,
106                          int numThreads = globalThreadCount ());
107 
108 
109     //------------------------------------------------------
110     // Constructor -- header data are explicitly specified
111     // as function call arguments (an empty dataWindow means
112     // "same as displayWindow")
113     //------------------------------------------------------
114 
115     TiledRgbaOutputFile (const char name[],
116 			 int tileXSize,
117 			 int tileYSize,
118 			 LevelMode mode,
119 			 LevelRoundingMode rmode,
120 			 const IMATH_NAMESPACE::Box2i &displayWindow,
121 			 const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
122 			 RgbaChannels rgbaChannels = WRITE_RGBA,
123 			 float pixelAspectRatio = 1,
124 			 const IMATH_NAMESPACE::V2f screenWindowCenter =
125 						    IMATH_NAMESPACE::V2f (0, 0),
126 			 float screenWindowWidth = 1,
127 			 LineOrder lineOrder = INCREASING_Y,
128 			 Compression compression = ZIP_COMPRESSION,
129                          int numThreads = globalThreadCount ());
130 
131 
132     //-----------------------------------------------
133     // Constructor -- like the previous one, but both
134     // the display window and the data window are
135     // Box2i (V2i (0, 0), V2i (width - 1, height -1))
136     //-----------------------------------------------
137 
138     TiledRgbaOutputFile (const char name[],
139 			 int width,
140 			 int height,
141 			 int tileXSize,
142 			 int tileYSize,
143 			 LevelMode mode,
144 			 LevelRoundingMode rmode = ROUND_DOWN,
145 			 RgbaChannels rgbaChannels = WRITE_RGBA,
146 			 float pixelAspectRatio = 1,
147 			 const IMATH_NAMESPACE::V2f screenWindowCenter =
148 						    IMATH_NAMESPACE::V2f (0, 0),
149 			 float screenWindowWidth = 1,
150 			 LineOrder lineOrder = INCREASING_Y,
151 			 Compression compression = ZIP_COMPRESSION,
152                          int numThreads = globalThreadCount ());
153 
154 
155     virtual ~TiledRgbaOutputFile ();
156 
157 
158     //------------------------------------------------
159     // Define a frame buffer as the pixel data source:
160     // Pixel (x, y) is at address
161     //
162     //  base + x * xStride + y * yStride
163     //
164     //------------------------------------------------
165 
166     void		setFrameBuffer (const Rgba *base,
167 					size_t xStride,
168 					size_t yStride);
169 
170     //--------------------------
171     // Access to the file header
172     //--------------------------
173 
174     const Header &		header () const;
175     const FrameBuffer &		frameBuffer () const;
176     const IMATH_NAMESPACE::Box2i &	displayWindow () const;
177     const IMATH_NAMESPACE::Box2i &	dataWindow () const;
178     float			pixelAspectRatio () const;
179     const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
180     float			screenWindowWidth () const;
181     LineOrder			lineOrder () const;
182     Compression			compression () const;
183     RgbaChannels		channels () const;
184 
185 
186     //----------------------------------------------------
187     // Utility functions (same as in Imf::TiledOutputFile)
188     //----------------------------------------------------
189 
190     unsigned int	tileXSize () const;
191     unsigned int	tileYSize () const;
192     LevelMode		levelMode () const;
193     LevelRoundingMode	levelRoundingMode () const;
194 
195     int			numLevels () const;
196     int			numXLevels () const;
197     int			numYLevels () const;
198     bool		isValidLevel (int lx, int ly) const;
199 
200     int			levelWidth  (int lx) const;
201     int			levelHeight (int ly) const;
202 
203     int			numXTiles (int lx = 0) const;
204     int			numYTiles (int ly = 0) const;
205 
206     IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
207     IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
208 
209     IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
210 					   int l = 0) const;
211 
212     IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
213 					   int lx, int ly) const;
214 
215     //------------------------------------------------------------------
216     // Write pixel data:
217     //
218     // writeTile(dx, dy, lx, ly) writes the tile with tile
219     // coordinates (dx, dy), and level number (lx, ly) to
220     // the file.
221     //
222     //   dx must lie in the interval [0, numXTiles(lx)-1]
223     //   dy must lie in the interval [0, numYTiles(ly)-1]
224     //
225     //   lx must lie in the interval [0, numXLevels()-1]
226     //   ly must lie in the inverval [0, numYLevels()-1]
227     //
228     // writeTile(dx, dy, level) is a convenience function
229     // used for ONE_LEVEL and MIPMAP_LEVEL files.  It calls
230     // writeTile(dx, dy, level, level).
231     //
232     // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
233     // writing multiple tiles at once.  If multi-threading is used
234     // multiple tiles are written concurrently.
235     //
236     // Pixels that are outside the pixel coordinate range for the tile's
237     // level, are never accessed by writeTile().
238     //
239     // Each tile in the file must be written exactly once.
240     //
241     //------------------------------------------------------------------
242 
243     void		writeTile (int dx, int dy, int l = 0);
244     void		writeTile (int dx, int dy, int lx, int ly);
245 
246     void		writeTiles (int dxMin, int dxMax, int dyMin, int dyMax,
247                                     int lx, int ly);
248 
249     void		writeTiles (int dxMin, int dxMax, int dyMin, int dyMax,
250                                     int l = 0);
251 
252 
253     // -------------------------------------------------------------------------
254     // Update the preview image (see Imf::TiledOutputFile::updatePreviewImage())
255     // -------------------------------------------------------------------------
256 
257     void		updatePreviewImage (const PreviewRgba[]);
258 
259 
260     //------------------------------------------------
261     // Break a tile -- for testing and debugging only
262     // (see Imf::TiledOutputFile::breakTile())
263     //
264     // Warning: Calling this function usually results
265     // in a broken image file.  The file or parts of
266     // it may not be readable, or the file may contain
267     // bad data.
268     //
269     //------------------------------------------------
270 
271     void		breakTile  (int dx, int dy,
272 				    int lx, int ly,
273 				    int offset,
274 				    int length,
275 				    char c);
276   private:
277 
278     //
279     // Copy constructor and assignment are not implemented
280     //
281 
282     TiledRgbaOutputFile (const TiledRgbaOutputFile &);
283     TiledRgbaOutputFile & operator = (const TiledRgbaOutputFile &);
284 
285     class ToYa;
286 
287     TiledOutputFile *            _outputFile;
288     ToYa *			_toYa;
289 };
290 
291 
292 
293 //
294 // Tiled RGBA input file
295 //
296 
297 class IMF_EXPORT TiledRgbaInputFile
298 {
299   public:
300 
301     //--------------------------------------------------------
302     // Constructor -- opens the file with the specified name.
303     // Destroying TiledRgbaInputFile objects constructed with
304     // this constructor automatically closes the corresponding
305     // files.
306     //--------------------------------------------------------
307 
308     TiledRgbaInputFile (const char name[],
309                         int numThreads = globalThreadCount ());
310 
311 
312     //-------------------------------------------------------
313     // Constructor -- attaches the new TiledRgbaInputFile
314     // object to a file that has already been opened by the
315     // caller.
316     // Destroying TiledRgbaInputFile objects constructed with
317     // this constructor does not automatically close the
318     // corresponding files.
319     //-------------------------------------------------------
320 
321     TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
322 
323 
324     //------------------------------------------------------------
325     // Constructors -- the same as the previous two, but the names
326     // of the red, green, blue, alpha, and luminance channels are
327     // expected to be layerName.R, layerName.G, etc.
328     //------------------------------------------------------------
329 
330     TiledRgbaInputFile (const char name[],
331 		        const std::string &layerName,
332 		        int numThreads = globalThreadCount());
333 
334     TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
335 		        const std::string &layerName,
336 		        int numThreads = globalThreadCount());
337 
338     //-----------
339     // Destructor
340     //-----------
341 
342     virtual ~TiledRgbaInputFile ();
343 
344 
345     //-----------------------------------------------------
346     // Define a frame buffer as the pixel data destination:
347     // Pixel (x, y) is at address
348     //
349     //  base + x * xStride + y * yStride
350     //
351     //-----------------------------------------------------
352 
353     void			setFrameBuffer (Rgba *base,
354 						size_t xStride,
355 						size_t yStride);
356 
357     //-------------------------------------------------------------------
358     // Switch to a different layer -- subsequent calls to readTile()
359     // and readTiles() will read channels layerName.R, layerName.G, etc.
360     // After each call to setLayerName(), setFrameBuffer() must be called
361     // at least once before the next call to readTile() or readTiles().
362     //-------------------------------------------------------------------
363 
364     void			setLayerName (const std::string &layerName);
365 
366 
367     //--------------------------
368     // Access to the file header
369     //--------------------------
370 
371     const Header &		header () const;
372     const FrameBuffer &		frameBuffer () const;
373     const IMATH_NAMESPACE::Box2i &	displayWindow () const;
374     const IMATH_NAMESPACE::Box2i &	dataWindow () const;
375     float			pixelAspectRatio () const;
376     const IMATH_NAMESPACE::V2f		screenWindowCenter () const;
377     float			screenWindowWidth () const;
378     LineOrder			lineOrder () const;
379     Compression			compression () const;
380     RgbaChannels		channels () const;
381     const char *                fileName () const;
382     bool			isComplete () const;
383 
384     //----------------------------------
385     // Access to the file format version
386     //----------------------------------
387 
388     int				version () const;
389 
390 
391     //---------------------------------------------------
392     // Utility functions (same as in Imf::TiledInputFile)
393     //---------------------------------------------------
394 
395     unsigned int	tileXSize () const;
396     unsigned int	tileYSize () const;
397     LevelMode		levelMode () const;
398     LevelRoundingMode	levelRoundingMode () const;
399 
400     int			numLevels () const;
401     int			numXLevels () const;
402     int			numYLevels () const;
403     bool		isValidLevel (int lx, int ly) const;
404 
405     int			levelWidth  (int lx) const;
406     int			levelHeight (int ly) const;
407 
408     int			numXTiles (int lx = 0) const;
409     int			numYTiles (int ly = 0) const;
410 
411     IMATH_NAMESPACE::Box2i	dataWindowForLevel (int l = 0) const;
412     IMATH_NAMESPACE::Box2i	dataWindowForLevel (int lx, int ly) const;
413 
414     IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
415 					   int l = 0) const;
416 
417     IMATH_NAMESPACE::Box2i	dataWindowForTile (int dx, int dy,
418 					   int lx, int ly) const;
419 
420 
421     //----------------------------------------------------------------
422     // Read pixel data:
423     //
424     // readTile(dx, dy, lx, ly) reads the tile with tile
425     // coordinates (dx, dy), and level number (lx, ly),
426     // and stores it in the current frame buffer.
427     //
428     //   dx must lie in the interval [0, numXTiles(lx)-1]
429     //   dy must lie in the interval [0, numYTiles(ly)-1]
430     //
431     //   lx must lie in the interval [0, numXLevels()-1]
432     //   ly must lie in the inverval [0, numYLevels()-1]
433     //
434     // readTile(dx, dy, level) is a convenience function used
435     // for ONE_LEVEL and MIPMAP_LEVELS files.  It calls
436     // readTile(dx, dy, level, level).
437     //
438     // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow
439     // reading multiple tiles at once.  If multi-threading is used
440     // multiple tiles are read concurrently.
441     //
442     // Pixels that are outside the pixel coordinate range for the
443     // tile's level, are never accessed by readTile().
444     //
445     // Attempting to access a tile that is not present in the file
446     // throws an InputExc exception.
447     //
448     //----------------------------------------------------------------
449 
450     void           	readTile (int dx, int dy, int l = 0);
451     void           	readTile (int dx, int dy, int lx, int ly);
452 
453     void		readTiles (int dxMin, int dxMax,
454                                    int dyMin, int dyMax, int lx, int ly);
455 
456     void		readTiles (int dxMin, int dxMax,
457                                    int dyMin, int dyMax, int l = 0);
458 
459   private:
460 
461     //
462     // Copy constructor and assignment are not implemented
463     //
464 
465     TiledRgbaInputFile (const TiledRgbaInputFile &);
466     TiledRgbaInputFile & operator = (const TiledRgbaInputFile &);
467 
468     class FromYa;
469 
470     TiledInputFile *	_inputFile;
471     FromYa *		_fromYa;
472     std::string		_channelNamePrefix;
473 };
474 
475 
476 OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
477 
478 
479 
480 
481 
482 #endif
483