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