HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfTiledOutputFile.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifndef INCLUDED_IMF_TILED_OUTPUT_FILE_H
7 #define INCLUDED_IMF_TILED_OUTPUT_FILE_H
8 
9 //-----------------------------------------------------------------------------
10 //
11 // class TiledOutputFile
12 //
13 //-----------------------------------------------------------------------------
14 
15 #include "ImfForward.h"
16 
17 #include "ImfGenericOutputFile.h"
18 #include "ImfThreading.h"
19 #include "ImfTileDescription.h"
20 
21 #include <ImathBox.h>
22 
24 
25 struct PreviewRgba;
26 
28 {
29 public:
30  //-------------------------------------------------------------------
31  // A constructor that opens the file with the specified name, and
32  // writes the file header. The file header is also copied into the
33  // TiledOutputFile object, and can later be accessed via the header()
34  // method.
35  //
36  // Destroying TiledOutputFile constructed with this constructor
37  // automatically closes the corresponding files.
38  //
39  // The header must contain a TileDescriptionAttribute called "tiles".
40  //
41  // The x and y subsampling factors for all image channels must be 1;
42  // subsampling is not supported.
43  //
44  // Tiles can be written to the file in arbitrary order. The line
45  // order attribute can be used to cause the tiles to be sorted in
46  // the file. When the file is read later, reading the tiles in the
47  // same order as they are in the file tends to be significantly
48  // faster than reading the tiles in random order (see writeTile,
49  // below).
50  //-------------------------------------------------------------------
51 
54  const char fileName[],
55  const Header& header,
56  int numThreads = globalThreadCount ());
57 
58  // ----------------------------------------------------------------
59  // A constructor that attaches the new TiledOutputFile object to
60  // a file that has already been opened. Destroying TiledOutputFile
61  // objects constructed with this constructor does not automatically
62  // close the corresponding files.
63  // ----------------------------------------------------------------
64 
68  const Header& header,
69  int numThreads = globalThreadCount ());
70 
71  //-----------------------------------------------------
72  // Destructor
73  //
74  // Destroying a TiledOutputFile object before all tiles
75  // have been written results in an incomplete file.
76  //-----------------------------------------------------
77 
79  virtual ~TiledOutputFile ();
80 
81  //------------------------
82  // Access to the file name
83  //------------------------
84 
86  const char* fileName () const;
87 
88  //--------------------------
89  // Access to the file header
90  //--------------------------
91 
93  const Header& header () const;
94 
95  //-------------------------------------------------------
96  // Set the current frame buffer -- copies the FrameBuffer
97  // object into the TiledOutputFile object.
98  //
99  // The current frame buffer is the source of the pixel
100  // data written to the file. The current frame buffer
101  // must be set at least once before writeTile() is
102  // called. The current frame buffer can be changed
103  // after each call to writeTile().
104  //-------------------------------------------------------
105 
106  IMF_EXPORT
107  void setFrameBuffer (const FrameBuffer& frameBuffer);
108 
109  //-----------------------------------
110  // Access to the current frame buffer
111  //-----------------------------------
112 
113  IMF_EXPORT
114  const FrameBuffer& frameBuffer () const;
115 
116  //-------------------
117  // Utility functions:
118  //-------------------
119 
120  //---------------------------------------------------------
121  // Multiresolution mode and tile size:
122  // The following functions return the xSize, ySize and mode
123  // fields of the file header's TileDescriptionAttribute.
124  //---------------------------------------------------------
125 
126  IMF_EXPORT
127  unsigned int tileXSize () const;
128  IMF_EXPORT
129  unsigned int tileYSize () const;
130  IMF_EXPORT
131  LevelMode levelMode () const;
132  IMF_EXPORT
133  LevelRoundingMode levelRoundingMode () const;
134 
135  //--------------------------------------------------------------------
136  // Number of levels:
137  //
138  // numXLevels() returns the file's number of levels in x direction.
139  //
140  // if levelMode() == ONE_LEVEL:
141  // return value is: 1
142  //
143  // if levelMode() == MIPMAP_LEVELS:
144  // return value is: rfunc (log (max (w, h)) / log (2)) + 1
145  //
146  // if levelMode() == RIPMAP_LEVELS:
147  // return value is: rfunc (log (w) / log (2)) + 1
148  //
149  // where
150  // w is the width of the image's data window, max.x - min.x + 1,
151  // y is the height of the image's data window, max.y - min.y + 1,
152  // and rfunc(x) is either floor(x), or ceil(x), depending on
153  // whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
154  //
155  // numYLevels() returns the file's number of levels in y direction.
156  //
157  // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
158  // return value is the same as for numXLevels()
159  //
160  // if levelMode() == RIPMAP_LEVELS:
161  // return value is: rfunc (log (h) / log (2)) + 1
162  //
163  //
164  // numLevels() is a convenience function for use with MIPMAP_LEVELS
165  // files.
166  //
167  // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
168  // return value is the same as for numXLevels()
169  //
170  // if levelMode() == RIPMAP_LEVELS:
171  // an IEX_NAMESPACE::LogicExc exception is thrown
172  //
173  // isValidLevel(lx, ly) returns true if the file contains
174  // a level with level number (lx, ly), false if not.
175  //
176  //--------------------------------------------------------------------
177 
178  IMF_EXPORT
179  int numLevels () const;
180  IMF_EXPORT
181  int numXLevels () const;
182  IMF_EXPORT
183  int numYLevels () const;
184  IMF_EXPORT
185  bool isValidLevel (int lx, int ly) const;
186 
187  //---------------------------------------------------------
188  // Dimensions of a level:
189  //
190  // levelWidth(lx) returns the width of a level with level
191  // number (lx, *), where * is any number.
192  //
193  // return value is:
194  // max (1, rfunc (w / pow (2, lx)))
195  //
196  //
197  // levelHeight(ly) returns the height of a level with level
198  // number (*, ly), where * is any number.
199  //
200  // return value is:
201  // max (1, rfunc (h / pow (2, ly)))
202  //
203  //---------------------------------------------------------
204 
205  IMF_EXPORT
206  int levelWidth (int lx) const;
207  IMF_EXPORT
208  int levelHeight (int ly) const;
209 
210  //----------------------------------------------------------
211  // Number of tiles:
212  //
213  // numXTiles(lx) returns the number of tiles in x direction
214  // that cover a level with level number (lx, *), where * is
215  // any number.
216  //
217  // return value is:
218  // (levelWidth(lx) + tileXSize() - 1) / tileXSize()
219  //
220  //
221  // numYTiles(ly) returns the number of tiles in y direction
222  // that cover a level with level number (*, ly), where * is
223  // any number.
224  //
225  // return value is:
226  // (levelHeight(ly) + tileXSize() - 1) / tileXSize()
227  //
228  //----------------------------------------------------------
229 
230  IMF_EXPORT
231  int numXTiles (int lx = 0) const;
232  IMF_EXPORT
233  int numYTiles (int ly = 0) const;
234 
235  //---------------------------------------------------------
236  // Level pixel ranges:
237  //
238  // dataWindowForLevel(lx, ly) returns a 2-dimensional
239  // region of valid pixel coordinates for a level with
240  // level number (lx, ly)
241  //
242  // return value is a Box2i with min value:
243  // (dataWindow.min.x, dataWindow.min.y)
244  //
245  // and max value:
246  // (dataWindow.min.x + levelWidth(lx) - 1,
247  // dataWindow.min.y + levelHeight(ly) - 1)
248  //
249  // dataWindowForLevel(level) is a convenience function used
250  // for ONE_LEVEL and MIPMAP_LEVELS files. It returns
251  // dataWindowForLevel(level, level).
252  //
253  //---------------------------------------------------------
254 
255  IMF_EXPORT
256  IMATH_NAMESPACE::Box2i dataWindowForLevel (int l = 0) const;
257  IMF_EXPORT
258  IMATH_NAMESPACE::Box2i dataWindowForLevel (int lx, int ly) const;
259 
260  //-------------------------------------------------------------------
261  // Tile pixel ranges:
262  //
263  // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
264  // region of valid pixel coordinates for a tile with tile coordinates
265  // (dx,dy) and level number (lx, ly).
266  //
267  // return value is a Box2i with min value:
268  // (dataWindow.min.x + dx * tileXSize(),
269  // dataWindow.min.y + dy * tileYSize())
270  //
271  // and max value:
272  // (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
273  // dataWindow.min.y + (dy + 1) * tileYSize() - 1)
274  //
275  // dataWindowForTile(dx, dy, level) is a convenience function
276  // used for ONE_LEVEL and MIPMAP_LEVELS files. It returns
277  // dataWindowForTile(dx, dy, level, level).
278  //
279  //-------------------------------------------------------------------
280 
281  IMF_EXPORT
282  IMATH_NAMESPACE::Box2i dataWindowForTile (int dx, int dy, int l = 0) const;
283 
284  IMF_EXPORT
286  dataWindowForTile (int dx, int dy, int lx, int ly) const;
287 
288  //------------------------------------------------------------------
289  // Write pixel data:
290  //
291  // writeTile(dx, dy, lx, ly) writes the tile with tile
292  // coordinates (dx, dy), and level number (lx, ly) to
293  // the file.
294  //
295  // dx must lie in the interval [0, numXTiles(lx) - 1]
296  // dy must lie in the interval [0, numYTiles(ly) - 1]
297  //
298  // lx must lie in the interval [0, numXLevels() - 1]
299  // ly must lie in the interval [0, numYLevels() - 1]
300  //
301  // writeTile(dx, dy, level) is a convenience function
302  // used for ONE_LEVEL and MIPMAP_LEVEL files. It calls
303  // writeTile(dx, dy, level, level).
304  //
305  // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
306  // writing multiple tiles at once. If multi-threading is used
307  // multiple tiles are written concurrently. The tile coordinates,
308  // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile
309  // coordinates. It is valid for dx1 < dx2 or dy1 < dy2; the
310  // tiles are always written in the order specified by the line
311  // order attribute. Hence, it is not possible to specify an
312  // "invalid" or empty tile range.
313  //
314  // Pixels that are outside the pixel coordinate range for the tile's
315  // level, are never accessed by writeTile().
316  //
317  // Each tile in the file must be written exactly once.
318  //
319  // The file's line order attribute determines the order of the tiles
320  // in the file:
321  //
322  // INCREASING_Y In the file, the tiles for each level are stored
323  // in a contiguous block. The levels are ordered
324  // like this:
325  //
326  // (0, 0) (1, 0) ... (nx-1, 0)
327  // (0, 1) (1, 1) ... (nx-1, 1)
328  // ...
329  // (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
330  //
331  // where nx = numXLevels(), and ny = numYLevels().
332  // In an individual level, (lx, ly), the tiles
333  // are stored in the following order:
334  //
335  // (0, 0) (1, 0) ... (tx-1, 0)
336  // (0, 1) (1, 1) ... (tx-1, 1)
337  // ...
338  // (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
339  //
340  // where tx = numXTiles(lx),
341  // and ty = numYTiles(ly).
342  //
343  // DECREASING_Y As for INCREASING_Y, the tiles for each level
344  // are stored in a contiguous block. The levels
345  // are ordered the same way as for INCREASING_Y,
346  // but within an individual level, the tiles
347  // are stored in this order:
348  //
349  // (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
350  // ...
351  // (0, 1) (1, 1) ... (tx-1, 1)
352  // (0, 0) (1, 0) ... (tx-1, 0)
353  //
354  //
355  // RANDOM_Y The order of the calls to writeTile() determines
356  // the order of the tiles in the file.
357  //
358  //------------------------------------------------------------------
359 
360  IMF_EXPORT
361  void writeTile (int dx, int dy, int l = 0);
362  IMF_EXPORT
363  void writeTile (int dx, int dy, int lx, int ly);
364 
365  IMF_EXPORT
366  void writeTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly);
367 
368  IMF_EXPORT
369  void writeTiles (int dx1, int dx2, int dy1, int dy2, int l = 0);
370 
371  //------------------------------------------------------------------
372  // Shortcut to copy all pixels from a TiledInputFile into this file,
373  // without uncompressing and then recompressing the pixel data.
374  // This file's header must be compatible with the TiledInputFile's
375  // header: The two header's "dataWindow", "compression",
376  // "lineOrder", "channels", and "tiles" attributes must be the same.
377  //------------------------------------------------------------------
378 
379  IMF_EXPORT
380  void copyPixels (TiledInputFile& in);
381  IMF_EXPORT
382  void copyPixels (TiledInputPart& in);
383 
384  //------------------------------------------------------------------
385  // Shortcut to copy all pixels from an InputFile into this file,
386  // without uncompressing and then recompressing the pixel data.
387  // This file's header must be compatible with the InputFile's
388  // header: The two header's "dataWindow", "compression",
389  // "lineOrder", "channels", and "tiles" attributes must be the same.
390  //
391  // To use this function, the InputFile must be tiled.
392  //------------------------------------------------------------------
393 
394  IMF_EXPORT
395  void copyPixels (InputFile& in);
396  IMF_EXPORT
397  void copyPixels (InputPart& in);
398 
399  //--------------------------------------------------------------
400  // Updating the preview image:
401  //
402  // updatePreviewImage() supplies a new set of pixels for the
403  // preview image attribute in the file's header. If the header
404  // does not contain a preview image, updatePreviewImage() throws
405  // an IEX_NAMESPACE::LogicExc.
406  //
407  // Note: updatePreviewImage() is necessary because images are
408  // often stored in a file incrementally, a few tiles at a time,
409  // while the image is being generated. Since the preview image
410  // is an attribute in the file's header, it gets stored in the
411  // file as soon as the file is opened, but we may not know what
412  // the preview image should look like until we have written the
413  // last tile of the main image.
414  //
415  //--------------------------------------------------------------
416 
417  IMF_EXPORT
418  void updatePreviewImage (const PreviewRgba newPixels[]);
419 
420  //-------------------------------------------------------------
421  // Break a tile -- for testing and debugging only:
422  //
423  // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
424  // output file by writing n copies of character c, starting
425  // p bytes from the beginning of the tile with tile coordinates
426  // (dx, dy) and level number (lx, ly).
427  //
428  // Warning: Calling this function usually results in a broken
429  // image file. The file or parts of it may not be readable,
430  // or the file may contain bad data.
431  //
432  //-------------------------------------------------------------
433 
434  IMF_EXPORT
435  void
436  breakTile (int dx, int dy, int lx, int ly, int offset, int length, char c);
437  struct IMF_HIDDEN Data;
438 
439 private:
440  // ----------------------------------------------------------------
441  // A constructor attaches the OutputStreamMutex to the
442  // given one from MultiPartOutputFile. Set the previewPosition
443  // and lineOffsetsPosition which have been acquired from
444  // the constructor of MultiPartOutputFile as well.
445  // ----------------------------------------------------------------
446  IMF_HIDDEN
447  TiledOutputFile (const OutputPartData* part);
448 
449  TiledOutputFile (const TiledOutputFile&) = delete;
450  TiledOutputFile& operator= (const TiledOutputFile&) = delete;
451  TiledOutputFile (TiledOutputFile&&) = delete;
452  TiledOutputFile& operator= (TiledOutputFile&&) = delete;
453 
454  IMF_HIDDEN
455  void initialize (const Header& header);
456 
457  IMF_HIDDEN
458  bool isValidTile (int dx, int dy, int lx, int ly) const;
459 
460  IMF_HIDDEN
461  size_t bytesPerLineForTile (int dx, int dy, int lx, int ly) const;
462 
463  Data* _data;
464 
465  OutputStreamMutex* _streamData;
466  bool _deleteStream;
467 
468  friend class MultiPartOutputFile;
469 };
470 
472 
473 #endif
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:83
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
#define IMF_HIDDEN
Definition: ImfExport.h:55
enum IMF_EXPORT_ENUM LevelRoundingMode
GLintptr offset
Definition: glcorearb.h:665
Box< V2i > Box2i
2D box of base type int.
Definition: ImathBox.h:143
#define IMF_EXPORT
Definition: ImfExport.h:54
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
class IMF_EXPORT_TYPE OStream
Definition: ImfForward.h:86
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER IMF_EXPORT int globalThreadCount()
LeafData & operator=(const LeafData &)=delete
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:80
class IMF_EXPORT_TYPE TiledOutputFile
Definition: ImfForward.h:37
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER enum IMF_EXPORT_ENUM LevelMode
#define IMF_EXPORT_TYPE
Definition: ImfExport.h:57