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

source code of include/OpenEXR/ImfHeader.h