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