ImfHeader.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright (c) Contributors to the OpenEXR Project.
  4. //
  5. #ifndef INCLUDED_IMF_HEADER_H
  6. #define INCLUDED_IMF_HEADER_H
  7. //-----------------------------------------------------------------------------
  8. //
  9. // class Header
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "ImfForward.h"
  13. #include "ImfLineOrder.h"
  14. #include "ImfCompression.h"
  15. #include "ImfName.h"
  16. #include "ImfTileDescription.h"
  17. #include "ImathVec.h"
  18. #include "ImathBox.h"
  19. #include "IexBaseExc.h"
  20. #include "ImfAttribute.h"
  21. #include <map>
  22. #include <iosfwd>
  23. #include <string>
  24. #include <cstdint>
  25. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
  26. using std::string;
  27. class IMF_EXPORT_TYPE Header
  28. {
  29. public:
  30. //----------------------------------------------------------------
  31. // Default constructor -- the display window and the data window
  32. // are both set to Box2i (V2i (0, 0), V2i (width-1, height-1).
  33. //----------------------------------------------------------------
  34. IMF_EXPORT
  35. Header (int width = 64,
  36. int height = 64,
  37. float pixelAspectRatio = 1,
  38. const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
  39. float screenWindowWidth = 1,
  40. LineOrder lineOrder = INCREASING_Y,
  41. Compression = ZIP_COMPRESSION);
  42. //--------------------------------------------------------------------
  43. // Constructor -- the data window is specified explicitly; the display
  44. // window is set to Box2i (V2i (0, 0), V2i (width-1, height-1).
  45. //--------------------------------------------------------------------
  46. IMF_EXPORT
  47. Header (int width,
  48. int height,
  49. const IMATH_NAMESPACE::Box2i &dataWindow,
  50. float pixelAspectRatio = 1,
  51. const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
  52. float screenWindowWidth = 1,
  53. LineOrder lineOrder = INCREASING_Y,
  54. Compression = ZIP_COMPRESSION);
  55. //----------------------------------------------------------
  56. // Constructor -- the display window and the data window are
  57. // both specified explicitly.
  58. //----------------------------------------------------------
  59. IMF_EXPORT
  60. Header (const IMATH_NAMESPACE::Box2i &displayWindow,
  61. const IMATH_NAMESPACE::Box2i &dataWindow,
  62. float pixelAspectRatio = 1,
  63. const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
  64. float screenWindowWidth = 1,
  65. LineOrder lineOrder = INCREASING_Y,
  66. Compression = ZIP_COMPRESSION);
  67. //-----------------
  68. // Copy constructor
  69. //-----------------
  70. IMF_EXPORT
  71. Header (const Header& other);
  72. IMF_EXPORT
  73. Header (Header&& other);
  74. //-----------
  75. // Destructor
  76. //-----------
  77. IMF_EXPORT
  78. ~Header ();
  79. //-----------
  80. // Assignment
  81. //-----------
  82. IMF_EXPORT
  83. Header& operator= (const Header& other);
  84. IMF_EXPORT
  85. Header& operator= (Header&& other);
  86. //---------------------------------------------------------------
  87. // Add an attribute:
  88. //
  89. // insert(n,attr) If no attribute with name n exists, a new
  90. // attribute with name n, and the same type as
  91. // attr, is added, and the value of attr is
  92. // copied into the new attribute.
  93. //
  94. // If an attribute with name n exists, and its
  95. // type is the same as attr, the value of attr
  96. // is copied into this attribute.
  97. //
  98. // If an attribute with name n exists, and its
  99. // type is different from attr, an IEX_NAMESPACE::TypeExc
  100. // is thrown.
  101. //
  102. //---------------------------------------------------------------
  103. IMF_EXPORT
  104. void insert (const char name[],
  105. const Attribute &attribute);
  106. IMF_EXPORT
  107. void insert (const std::string &name,
  108. const Attribute &attribute);
  109. //---------------------------------------------------------------
  110. // Remove an attribute:
  111. //
  112. // remove(n) If an attribute with name n exists, then it
  113. // is removed from the map of present attributes.
  114. //
  115. // If no attribute with name n exists, then this
  116. // functions becomes a 'no-op'
  117. //
  118. //---------------------------------------------------------------
  119. IMF_EXPORT
  120. void erase (const char name[]);
  121. IMF_EXPORT
  122. void erase (const std::string &name);
  123. //------------------------------------------------------------------
  124. // Access to existing attributes:
  125. //
  126. // [n] Returns a reference to the attribute
  127. // with name n. If no attribute with
  128. // name n exists, an IEX_NAMESPACE::ArgExc is thrown.
  129. //
  130. // typedAttribute<T>(n) Returns a reference to the attribute
  131. // with name n and type T. If no attribute
  132. // with name n exists, an IEX_NAMESPACE::ArgExc is
  133. // thrown. If an attribute with name n
  134. // exists, but its type is not T, an
  135. // IEX_NAMESPACE::TypeExc is thrown.
  136. //
  137. // findTypedAttribute<T>(n) Returns a pointer to the attribute with
  138. // name n and type T, or 0 if no attribute
  139. // with name n and type T exists.
  140. //
  141. //------------------------------------------------------------------
  142. IMF_EXPORT
  143. Attribute & operator [] (const char name[]);
  144. IMF_EXPORT
  145. const Attribute & operator [] (const char name[]) const;
  146. IMF_EXPORT
  147. Attribute & operator [] (const std::string &name);
  148. IMF_EXPORT
  149. const Attribute & operator [] (const std::string &name) const;
  150. template <class T> T& typedAttribute (const char name[]);
  151. template <class T> const T& typedAttribute (const char name[]) const;
  152. template <class T> T& typedAttribute (const std::string &name);
  153. template <class T> const T& typedAttribute (const std::string &name) const;
  154. template <class T> T* findTypedAttribute (const char name[]);
  155. template <class T> const T* findTypedAttribute (const char name[]) const;
  156. template <class T> T* findTypedAttribute (const std::string &name);
  157. template <class T> const T* findTypedAttribute (const std::string &name)
  158. const;
  159. //---------------------------------------------
  160. // Iterator-style access to existing attributes
  161. //---------------------------------------------
  162. typedef std::map <Name, Attribute *> AttributeMap;
  163. class Iterator;
  164. class ConstIterator;
  165. IMF_EXPORT
  166. Iterator begin ();
  167. IMF_EXPORT
  168. ConstIterator begin () const;
  169. IMF_EXPORT
  170. Iterator end ();
  171. IMF_EXPORT
  172. ConstIterator end () const;
  173. IMF_EXPORT
  174. Iterator find (const char name[]);
  175. IMF_EXPORT
  176. ConstIterator find (const char name[]) const;
  177. IMF_EXPORT
  178. Iterator find (const std::string &name);
  179. IMF_EXPORT
  180. ConstIterator find (const std::string &name) const;
  181. //--------------------------------
  182. // Access to predefined attributes
  183. //--------------------------------
  184. IMF_EXPORT
  185. IMATH_NAMESPACE::Box2i & displayWindow ();
  186. IMF_EXPORT
  187. const IMATH_NAMESPACE::Box2i & displayWindow () const;
  188. IMF_EXPORT
  189. IMATH_NAMESPACE::Box2i & dataWindow ();
  190. IMF_EXPORT
  191. const IMATH_NAMESPACE::Box2i & dataWindow () const;
  192. IMF_EXPORT
  193. float & pixelAspectRatio ();
  194. IMF_EXPORT
  195. const float & pixelAspectRatio () const;
  196. IMF_EXPORT
  197. IMATH_NAMESPACE::V2f & screenWindowCenter ();
  198. IMF_EXPORT
  199. const IMATH_NAMESPACE::V2f & screenWindowCenter () const;
  200. IMF_EXPORT
  201. float & screenWindowWidth ();
  202. IMF_EXPORT
  203. const float & screenWindowWidth () const;
  204. IMF_EXPORT
  205. ChannelList & channels ();
  206. IMF_EXPORT
  207. const ChannelList & channels () const;
  208. IMF_EXPORT
  209. LineOrder & lineOrder ();
  210. IMF_EXPORT
  211. const LineOrder & lineOrder () const;
  212. IMF_EXPORT
  213. Compression & compression ();
  214. IMF_EXPORT
  215. const Compression & compression () const;
  216. //-----------------------------------------------------
  217. // The header object allows one to store a compression level to be
  218. // used when writing a file.
  219. //
  220. // NB: These are NOT attributes, and will not be written to the
  221. // file, but are instead ephemeral settings to be used for this
  222. // instance of the header object.
  223. //
  224. // -----------------------------------------------------
  225. IMF_EXPORT
  226. void resetDefaultCompressionLevels ();
  227. IMF_EXPORT
  228. int& zipCompressionLevel ();
  229. IMF_EXPORT
  230. int zipCompressionLevel () const;
  231. IMF_EXPORT
  232. float& dwaCompressionLevel ();
  233. IMF_EXPORT
  234. float dwaCompressionLevel () const;
  235. //-----------------------------------------------------
  236. // Access to required attributes for multipart files
  237. // They are optional to non-multipart files and mandatory
  238. // for multipart files.
  239. //-----------------------------------------------------
  240. IMF_EXPORT
  241. void setName (const string& name);
  242. IMF_EXPORT
  243. string& name();
  244. IMF_EXPORT
  245. const string& name() const;
  246. IMF_EXPORT
  247. bool hasName() const;
  248. IMF_EXPORT
  249. void setType (const string& Type);
  250. IMF_EXPORT
  251. string& type();
  252. IMF_EXPORT
  253. const string& type() const;
  254. IMF_EXPORT
  255. bool hasType() const;
  256. IMF_EXPORT
  257. void setVersion (const int version);
  258. IMF_EXPORT
  259. int& version();
  260. IMF_EXPORT
  261. const int& version() const;
  262. IMF_EXPORT
  263. bool hasVersion() const;
  264. //
  265. // the chunkCount attribute is set automatically when a file is written.
  266. // There is no need to set it manually
  267. //
  268. IMF_EXPORT
  269. void setChunkCount(int chunks);
  270. IMF_EXPORT
  271. bool hasChunkCount() const;
  272. IMF_EXPORT
  273. const int & chunkCount() const;
  274. IMF_EXPORT
  275. int & chunkCount();
  276. //
  277. // for multipart files, return whether the file has a view string attribute
  278. // (for the deprecated single part multiview format EXR, see ImfMultiView.h)
  279. //
  280. IMF_EXPORT
  281. void setView(const string & view);
  282. IMF_EXPORT
  283. bool hasView() const;
  284. IMF_EXPORT
  285. string & view();
  286. IMF_EXPORT
  287. const string & view() const;
  288. //----------------------------------------------------------------------
  289. // Tile Description:
  290. //
  291. // The tile description is a TileDescriptionAttribute whose name
  292. // is "tiles". The "tiles" attribute must be present in any tiled
  293. // image file. When present, it describes various properties of the
  294. // tiles that make up the file.
  295. //
  296. // Convenience functions:
  297. //
  298. // setTileDescription(td)
  299. // calls insert ("tiles", TileDescriptionAttribute (td))
  300. //
  301. // tileDescription()
  302. // returns typedAttribute<TileDescriptionAttribute>("tiles").value()
  303. //
  304. // hasTileDescription()
  305. // return findTypedAttribute<TileDescriptionAttribute>("tiles") != 0
  306. //
  307. //----------------------------------------------------------------------
  308. IMF_EXPORT
  309. void setTileDescription (const TileDescription & td);
  310. IMF_EXPORT
  311. TileDescription & tileDescription ();
  312. IMF_EXPORT
  313. const TileDescription & tileDescription () const;
  314. IMF_EXPORT
  315. bool hasTileDescription() const;
  316. //----------------------------------------------------------------------
  317. // Preview image:
  318. //
  319. // The preview image is a PreviewImageAttribute whose name is "preview".
  320. // This attribute is special -- while an image file is being written,
  321. // the pixels of the preview image can be changed repeatedly by calling
  322. // OutputFile::updatePreviewImage().
  323. //
  324. // Convenience functions:
  325. //
  326. // setPreviewImage(p)
  327. // calls insert ("preview", PreviewImageAttribute (p))
  328. //
  329. // previewImage()
  330. // returns typedAttribute<PreviewImageAttribute>("preview").value()
  331. //
  332. // hasPreviewImage()
  333. // return findTypedAttribute<PreviewImageAttribute>("preview") != 0
  334. //
  335. //----------------------------------------------------------------------
  336. IMF_EXPORT
  337. void setPreviewImage (const PreviewImage &p);
  338. IMF_EXPORT
  339. PreviewImage & previewImage ();
  340. IMF_EXPORT
  341. const PreviewImage & previewImage () const;
  342. IMF_EXPORT
  343. bool hasPreviewImage () const;
  344. //-------------------------------------------------------------
  345. // Sanity check -- examines the header, and throws an exception
  346. // if it finds something wrong (empty display window, negative
  347. // pixel aspect ratio, unknown compression scheme etc...)
  348. //
  349. // set isTiled to true if you are checking a tiled/multi-res
  350. // header
  351. //-------------------------------------------------------------
  352. IMF_EXPORT
  353. void sanityCheck (bool isTiled = false,
  354. bool isMultipartFile = false) const;
  355. //----------------------------------------------------------------
  356. // Maximum image size and maximum tile size:
  357. //
  358. // sanityCheck() will throw an exception if the width or height of
  359. // the data window exceeds the maximum image width or height, or
  360. // if the size of a tile exceeds the maximum tile width or height.
  361. //
  362. // At program startup the maximum image and tile width and height
  363. // are set to zero, meaning that width and height are unlimited.
  364. //
  365. // Limiting image and tile width and height limits how much memory
  366. // will be allocated when a file is opened. This can help protect
  367. // applications from running out of memory while trying to read
  368. // a damaged image file.
  369. //----------------------------------------------------------------
  370. IMF_EXPORT
  371. static void setMaxImageSize (int maxWidth, int maxHeight);
  372. IMF_EXPORT
  373. static void setMaxTileSize (int maxWidth, int maxHeight);
  374. //
  375. // Check if the header reads nothing.
  376. //
  377. IMF_EXPORT
  378. bool readsNothing();
  379. //------------------------------------------------------------------
  380. // Input and output:
  381. //
  382. // If the header contains a preview image attribute, then writeTo()
  383. // returns the position of that attribute in the output stream; this
  384. // information is used by OutputFile::updatePreviewImage().
  385. // If the header contains no preview image attribute, then writeTo()
  386. // returns 0.
  387. //------------------------------------------------------------------
  388. IMF_EXPORT
  389. uint64_t writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
  390. bool isTiled = false) const;
  391. IMF_EXPORT
  392. void readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
  393. int &version);
  394. private:
  395. AttributeMap _map;
  396. bool _readsNothing;
  397. };
  398. //----------
  399. // Iterators
  400. //----------
  401. class IMF_EXPORT_TYPE Header::Iterator
  402. {
  403. public:
  404. IMF_EXPORT
  405. Iterator ();
  406. IMF_EXPORT
  407. Iterator (const Header::AttributeMap::iterator &i);
  408. IMF_EXPORT
  409. Iterator & operator ++ ();
  410. IMF_EXPORT
  411. Iterator operator ++ (int);
  412. IMF_EXPORT
  413. const char * name () const;
  414. IMF_EXPORT
  415. Attribute & attribute () const;
  416. private:
  417. friend class Header::ConstIterator;
  418. Header::AttributeMap::iterator _i;
  419. };
  420. class IMF_EXPORT_TYPE Header::ConstIterator
  421. {
  422. public:
  423. IMF_EXPORT
  424. ConstIterator ();
  425. IMF_EXPORT
  426. ConstIterator (const Header::AttributeMap::const_iterator &i);
  427. IMF_EXPORT
  428. ConstIterator (const Header::Iterator &other);
  429. IMF_EXPORT
  430. ConstIterator & operator ++ ();
  431. IMF_EXPORT
  432. ConstIterator operator ++ (int);
  433. IMF_EXPORT
  434. const char * name () const;
  435. IMF_EXPORT
  436. const Attribute & attribute () const;
  437. private:
  438. friend bool operator == (const ConstIterator &, const ConstIterator &);
  439. friend bool operator != (const ConstIterator &, const ConstIterator &);
  440. Header::AttributeMap::const_iterator _i;
  441. };
  442. //------------------------------------------------------------------------
  443. // Library initialization:
  444. //
  445. // In a multithreaded program, staticInitialize() must be called once
  446. // during startup, before the program accesses any other functions or
  447. // classes in the OpenEXR library. Calling staticInitialize() in this
  448. // way avoids races during initialization of the library's global
  449. // variables.
  450. //
  451. // Single-threaded programs are not required to call staticInitialize();
  452. // initialization of the library's global variables happens automatically.
  453. //
  454. //------------------------------------------------------------------------
  455. IMF_EXPORT void staticInitialize ();
  456. //-----------------
  457. // Inline Functions
  458. //-----------------
  459. inline
  460. Header::Iterator::Iterator (): _i()
  461. {
  462. // empty
  463. }
  464. inline
  465. Header::Iterator::Iterator (const Header::AttributeMap::iterator &i): _i (i)
  466. {
  467. // empty
  468. }
  469. inline Header::Iterator &
  470. Header::Iterator::operator ++ ()
  471. {
  472. ++_i;
  473. return *this;
  474. }
  475. inline Header::Iterator
  476. Header::Iterator::operator ++ (int)
  477. {
  478. Iterator tmp = *this;
  479. ++_i;
  480. return tmp;
  481. }
  482. inline const char *
  483. Header::Iterator::name () const
  484. {
  485. return *_i->first;
  486. }
  487. inline Attribute &
  488. Header::Iterator::attribute () const
  489. {
  490. return *_i->second;
  491. }
  492. inline
  493. Header::ConstIterator::ConstIterator (): _i()
  494. {
  495. // empty
  496. }
  497. inline
  498. Header::ConstIterator::ConstIterator
  499. (const Header::AttributeMap::const_iterator &i): _i (i)
  500. {
  501. // empty
  502. }
  503. inline
  504. Header::ConstIterator::ConstIterator (const Header::Iterator &other):
  505. _i (other._i)
  506. {
  507. // empty
  508. }
  509. inline Header::ConstIterator &
  510. Header::ConstIterator::operator ++ ()
  511. {
  512. ++_i;
  513. return *this;
  514. }
  515. inline Header::ConstIterator
  516. Header::ConstIterator::operator ++ (int)
  517. {
  518. ConstIterator tmp = *this;
  519. ++_i;
  520. return tmp;
  521. }
  522. inline const char *
  523. Header::ConstIterator::name () const
  524. {
  525. return *_i->first;
  526. }
  527. inline const Attribute &
  528. Header::ConstIterator::attribute () const
  529. {
  530. return *_i->second;
  531. }
  532. inline bool
  533. operator == (const Header::ConstIterator &x, const Header::ConstIterator &y)
  534. {
  535. return x._i == y._i;
  536. }
  537. inline bool
  538. operator != (const Header::ConstIterator &x, const Header::ConstIterator &y)
  539. {
  540. return !(x == y);
  541. }
  542. //---------------------
  543. // Template definitions
  544. //---------------------
  545. template <class T>
  546. T &
  547. Header::typedAttribute (const char name[])
  548. {
  549. Attribute *attr = &(*this)[name];
  550. T *tattr = dynamic_cast <T *> (attr);
  551. if (tattr == 0)
  552. throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
  553. return *tattr;
  554. }
  555. template <class T>
  556. const T &
  557. Header::typedAttribute (const char name[]) const
  558. {
  559. const Attribute *attr = &(*this)[name];
  560. const T *tattr = dynamic_cast <const T *> (attr);
  561. if (tattr == 0)
  562. throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
  563. return *tattr;
  564. }
  565. template <class T>
  566. T &
  567. Header::typedAttribute (const std::string &name)
  568. {
  569. return typedAttribute<T> (name.c_str());
  570. }
  571. template <class T>
  572. const T &
  573. Header::typedAttribute (const std::string &name) const
  574. {
  575. return typedAttribute<T> (name.c_str());
  576. }
  577. template <class T>
  578. T *
  579. Header::findTypedAttribute (const char name[])
  580. {
  581. AttributeMap::iterator i = _map.find (name);
  582. return (i == _map.end())? 0: dynamic_cast <T *> (i->second);
  583. }
  584. template <class T>
  585. const T *
  586. Header::findTypedAttribute (const char name[]) const
  587. {
  588. AttributeMap::const_iterator i = _map.find (name);
  589. return (i == _map.end())? 0: dynamic_cast <const T *> (i->second);
  590. }
  591. template <class T>
  592. T *
  593. Header::findTypedAttribute (const std::string &name)
  594. {
  595. return findTypedAttribute<T> (name.c_str());
  596. }
  597. template <class T>
  598. const T *
  599. Header::findTypedAttribute (const std::string &name) const
  600. {
  601. return findTypedAttribute<T> (name.c_str());
  602. }
  603. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
  604. #endif