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