ImfTiledOutputFile.h 17 KB

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