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