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