Home | History | Annotate | Download | only in IlmImf
      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
    433 Header::Iterator::Iterator (): _i()
    434 {
    435     // empty
    436 }
    437 
    438 
    439 inline
    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 *
    464 Header::Iterator::name () const
    465 {
    466     return *_i->first;
    467 }
    468 
    469 
    470 inline Attribute &
    471 Header::Iterator::attribute () const
    472 {
    473     return *_i->second;
    474 }
    475 
    476 
    477 inline
    478 Header::ConstIterator::ConstIterator (): _i()
    479 {
    480     // empty
    481 }
    482 
    483 inline
    484 Header::ConstIterator::ConstIterator
    485     (const Header::AttributeMap::const_iterator &i): _i (i)
    486 {
    487     // empty
    488 }
    489 
    490 
    491 inline
    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 *
    516 Header::ConstIterator::name () const
    517 {
    518     return *_i->first;
    519 }
    520 
    521 
    522 inline const 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 &
    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 &
    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 &
    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 &
    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 *
    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 *
    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 *
    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 *
    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