PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/openexr-1.7.0/ImfHeader.h
00001 
00002 //
00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 
00037 #ifndef INCLUDED_IMF_HEADER_H
00038 #define INCLUDED_IMF_HEADER_H
00039 
00040 //-----------------------------------------------------------------------------
00041 //
00042 //      class Header
00043 //
00044 //-----------------------------------------------------------------------------
00045 
00046 #include <ImfLineOrder.h>
00047 #include <ImfCompression.h>
00048 #include <ImfName.h>
00049 #include <ImfTileDescription.h>
00050 #include <ImfInt64.h>
00051 #include "ImathVec.h"
00052 #include "ImathBox.h"
00053 #include "IexBaseExc.h"
00054 #include <map>
00055 #include <iosfwd>
00056 #include <string>
00057 
00058 namespace Imf {
00059 
00060 
00061 class Attribute;
00062 class ChannelList;
00063 class IStream;
00064 class OStream;
00065 class PreviewImage;
00066 
00067 
00068 class Header
00069 {
00070   public:
00071     
00072     //----------------------------------------------------------------
00073     // Default constructor -- the display window and the data window
00074     // are both set to Box2i (V2i (0, 0), V2i (width-1, height-1).
00075     //----------------------------------------------------------------
00076 
00077     Header (int width = 64,
00078             int height = 64,
00079             float pixelAspectRatio = 1,
00080             const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
00081             float screenWindowWidth = 1,
00082             LineOrder lineOrder = INCREASING_Y,
00083             Compression = ZIP_COMPRESSION);
00084 
00085 
00086     //--------------------------------------------------------------------
00087     // Constructor -- the data window is specified explicitly; the display
00088     // window is set to Box2i (V2i (0, 0), V2i (width-1, height-1).
00089     //--------------------------------------------------------------------
00090 
00091     Header (int width,
00092             int height,
00093             const Imath::Box2i &dataWindow,
00094             float pixelAspectRatio = 1,
00095             const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
00096             float screenWindowWidth = 1,
00097             LineOrder lineOrder = INCREASING_Y,
00098             Compression = ZIP_COMPRESSION);
00099 
00100 
00101     //----------------------------------------------------------
00102     // Constructor -- the display window and the data window are
00103     // both specified explicitly.
00104     //----------------------------------------------------------
00105 
00106     Header (const Imath::Box2i &displayWindow,
00107             const Imath::Box2i &dataWindow,
00108             float pixelAspectRatio = 1,
00109             const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
00110             float screenWindowWidth = 1,
00111             LineOrder lineOrder = INCREASING_Y,
00112             Compression = ZIP_COMPRESSION);
00113 
00114 
00115     //-----------------
00116     // Copy constructor
00117     //-----------------
00118 
00119     Header (const Header &other);
00120 
00121 
00122     //-----------
00123     // Destructor
00124     //-----------
00125 
00126     ~Header ();
00127 
00128 
00129     //-----------
00130     // Assignment
00131     //-----------
00132 
00133     Header &                    operator = (const Header &other);
00134 
00135 
00136     //---------------------------------------------------------------
00137     // Add an attribute:
00138     //
00139     // insert(n,attr)   If no attribute with name n exists, a new
00140     //                  attribute with name n, and the same type as
00141     //                  attr, is added, and the value of attr is
00142     //                  copied into the new attribute.
00143     //
00144     //                  If an attribute with name n exists, and its
00145     //                  type is the same as attr, the value of attr
00146     //                  is copied into this attribute.
00147     //
00148     //                  If an attribute with name n exists, and its
00149     //                  type is different from attr, an Iex::TypeExc
00150     //                  is thrown.
00151     //
00152     //---------------------------------------------------------------
00153 
00154     void                        insert (const char name[],
00155                                         const Attribute &attribute);
00156 
00157     void                        insert (const std::string &name,
00158                                         const Attribute &attribute);
00159 
00160     //------------------------------------------------------------------
00161     // Access to existing attributes:
00162     //
00163     // [n]                      Returns a reference to the attribute
00164     //                          with name n.  If no attribute with
00165     //                          name n exists, an Iex::ArgExc is thrown.
00166     //
00167     // typedAttribute<T>(n)     Returns a reference to the attribute
00168     //                          with name n and type T.  If no attribute
00169     //                          with name n exists, an Iex::ArgExc is
00170     //                          thrown.  If an attribute with name n
00171     //                          exists, but its type is not T, an
00172     //                          Iex::TypeExc is thrown.
00173     //
00174     // findTypedAttribute<T>(n) Returns a pointer to the attribute with
00175     //                          name n and type T, or 0 if no attribute
00176     //                          with name n and type T exists.
00177     //
00178     //------------------------------------------------------------------
00179 
00180     Attribute &                 operator [] (const char name[]);
00181     const Attribute &           operator [] (const char name[]) const;
00182 
00183     Attribute &                 operator [] (const std::string &name);
00184     const Attribute &           operator [] (const std::string &name) const;
00185 
00186     template <class T> T&       typedAttribute (const char name[]);
00187     template <class T> const T& typedAttribute (const char name[]) const;
00188 
00189     template <class T> T&       typedAttribute (const std::string &name);
00190     template <class T> const T& typedAttribute (const std::string &name) const;
00191 
00192     template <class T> T*       findTypedAttribute (const char name[]);
00193     template <class T> const T* findTypedAttribute (const char name[]) const;
00194 
00195     template <class T> T*       findTypedAttribute (const std::string &name);
00196     template <class T> const T* findTypedAttribute (const std::string &name)
00197                                                                        const;
00198 
00199     //---------------------------------------------
00200     // Iterator-style access to existing attributes
00201     //---------------------------------------------
00202 
00203     typedef std::map <Name, Attribute *> AttributeMap;
00204 
00205     class Iterator;
00206     class ConstIterator;
00207 
00208     Iterator                    begin ();
00209     ConstIterator               begin () const;
00210 
00211     Iterator                    end ();
00212     ConstIterator               end () const;
00213 
00214     Iterator                    find (const char name[]);
00215     ConstIterator               find (const char name[]) const;
00216 
00217     Iterator                    find (const std::string &name);
00218     ConstIterator               find (const std::string &name) const;
00219 
00220 
00221     //--------------------------------
00222     // Access to predefined attributes
00223     //--------------------------------
00224 
00225     Imath::Box2i &              displayWindow ();
00226     const Imath::Box2i &        displayWindow () const;
00227 
00228     Imath::Box2i &              dataWindow ();
00229     const Imath::Box2i &        dataWindow () const;
00230 
00231     float &                     pixelAspectRatio ();
00232     const float &               pixelAspectRatio () const;
00233 
00234     Imath::V2f &                screenWindowCenter ();
00235     const Imath::V2f &          screenWindowCenter () const;
00236 
00237     float &                     screenWindowWidth ();
00238     const float &               screenWindowWidth () const;
00239 
00240     ChannelList &               channels ();
00241     const ChannelList &         channels () const;
00242 
00243     LineOrder &                 lineOrder ();
00244     const LineOrder &           lineOrder () const;
00245 
00246     Compression &               compression ();
00247     const Compression &         compression () const;
00248 
00249 
00250     //----------------------------------------------------------------------
00251     // Tile Description:
00252     //
00253     // The tile description is a TileDescriptionAttribute whose name
00254     // is "tiles".  The "tiles" attribute must be present in any tiled
00255     // image file. When present, it describes various properties of the
00256     // tiles that make up the file.
00257     //
00258     // Convenience functions:
00259     //
00260     // setTileDescription(td)
00261     //     calls insert ("tiles", TileDescriptionAttribute (td))
00262     //
00263     // tileDescription()
00264     //     returns typedAttribute<TileDescriptionAttribute>("tiles").value()
00265     //
00266     // hasTileDescription()
00267     //     return findTypedAttribute<TileDescriptionAttribute>("tiles") != 0
00268     //
00269     //----------------------------------------------------------------------
00270 
00271     void                        setTileDescription (const TileDescription & td);
00272 
00273     TileDescription &           tileDescription ();
00274     const TileDescription &     tileDescription () const;
00275 
00276     bool                        hasTileDescription() const;
00277 
00278 
00279     //----------------------------------------------------------------------
00280     // Preview image:
00281     //
00282     // The preview image is a PreviewImageAttribute whose name is "preview".
00283     // This attribute is special -- while an image file is being written,
00284     // the pixels of the preview image can be changed repeatedly by calling
00285     // OutputFile::updatePreviewImage().
00286     //
00287     // Convenience functions:
00288     //
00289     // setPreviewImage(p)
00290     //     calls insert ("preview", PreviewImageAttribute (p))
00291     //
00292     // previewImage()
00293     //     returns typedAttribute<PreviewImageAttribute>("preview").value()
00294     //
00295     // hasPreviewImage()
00296     //     return findTypedAttribute<PreviewImageAttribute>("preview") != 0
00297     //
00298     //----------------------------------------------------------------------
00299 
00300     void                        setPreviewImage (const PreviewImage &p);
00301 
00302     PreviewImage &              previewImage ();
00303     const PreviewImage &        previewImage () const;
00304 
00305     bool                        hasPreviewImage () const;
00306 
00307 
00308     //-------------------------------------------------------------
00309     // Sanity check -- examines the header, and throws an exception
00310     // if it finds something wrong (empty display window, negative
00311     // pixel aspect ratio, unknown compression sceme etc.)
00312     //
00313     // set isTiled to true if you are checking a tiled/multi-res
00314     // header
00315     //-------------------------------------------------------------
00316 
00317     void                        sanityCheck (bool isTiled = false) const;
00318 
00319 
00320     //----------------------------------------------------------------
00321     // Maximum image size and maximim tile size:
00322     //
00323     // sanityCheck() will throw an exception if the width or height of
00324     // the data window exceeds the maximum image width or height, or
00325     // if the size of a tile exceeds the maximum tile width or height.
00326     // 
00327     // At program startup the maximum image and tile width and height
00328     // are set to zero, meaning that width and height are unlimited.
00329     //
00330     // Limiting image and tile width and height limits how much memory
00331     // will be allocated when a file is opened.  This can help protect
00332     // applications from running out of memory while trying to read
00333     // a damaged image file.
00334     //----------------------------------------------------------------
00335 
00336     static void                 setMaxImageSize (int maxWidth, int maxHeight);
00337     static void                 setMaxTileSize (int maxWidth, int maxHeight);
00338 
00339 
00340     //------------------------------------------------------------------
00341     // Input and output:
00342     //
00343     // If the header contains a preview image attribute, then writeTo()
00344     // returns the position of that attribute in the output stream; this
00345     // information is used by OutputFile::updatePreviewImage().
00346     // If the header contains no preview image attribute, then writeTo()
00347     // returns 0.
00348     //------------------------------------------------------------------
00349 
00350 
00351     Int64                       writeTo (OStream &os,
00352                                          bool isTiled = false) const;
00353 
00354     void                        readFrom (IStream &is, int &version);
00355 
00356   private:
00357 
00358     AttributeMap                _map;
00359 };
00360 
00361 
00362 //----------
00363 // Iterators
00364 //----------
00365 
00366 class Header::Iterator
00367 {
00368   public:
00369 
00370     Iterator ();
00371     Iterator (const Header::AttributeMap::iterator &i);
00372 
00373     Iterator &                  operator ++ ();
00374     Iterator                    operator ++ (int);
00375 
00376     const char *                name () const;
00377     Attribute &                 attribute () const;
00378 
00379   private:
00380 
00381     friend class Header::ConstIterator;
00382 
00383     Header::AttributeMap::iterator _i;
00384 };
00385 
00386 
00387 class Header::ConstIterator
00388 {
00389   public:
00390 
00391     ConstIterator ();
00392     ConstIterator (const Header::AttributeMap::const_iterator &i);
00393     ConstIterator (const Header::Iterator &other);
00394 
00395     ConstIterator &             operator ++ ();
00396     ConstIterator               operator ++ (int);
00397 
00398     const char *                name () const;
00399     const Attribute &           attribute () const;
00400 
00401   private:
00402 
00403     friend bool operator == (const ConstIterator &, const ConstIterator &);
00404     friend bool operator != (const ConstIterator &, const ConstIterator &);
00405 
00406     Header::AttributeMap::const_iterator _i;
00407 };
00408 
00409 
00410 //------------------------------------------------------------------------
00411 // Library initialization:
00412 //
00413 // In a multithreaded program, staticInitialize() must be called once
00414 // during startup, before the program accesses any other functions or
00415 // classes in the IlmImf library.  Calling staticInitialize() in this
00416 // way avoids races during initialization of the library's global
00417 // variables.
00418 //
00419 // Single-threaded programs are not required to call staticInitialize();
00420 // initialization of the library's global variables happens automatically.
00421 //
00422 //------------------------------------------------------------------------
00423 
00424 void staticInitialize ();
00425 
00426 
00427 //-----------------
00428 // Inline Functions
00429 //-----------------
00430 
00431 
00432 inline
00433 Header::Iterator::Iterator (): _i()
00434 {
00435     // empty
00436 }
00437 
00438 
00439 inline
00440 Header::Iterator::Iterator (const Header::AttributeMap::iterator &i): _i (i)
00441 {
00442     // empty
00443 }
00444 
00445 
00446 inline Header::Iterator &               
00447 Header::Iterator::operator ++ ()
00448 {
00449     ++_i;
00450     return *this;
00451 }
00452 
00453 
00454 inline Header::Iterator         
00455 Header::Iterator::operator ++ (int)
00456 {
00457     Iterator tmp = *this;
00458     ++_i;
00459     return tmp;
00460 }
00461 
00462 
00463 inline const char *
00464 Header::Iterator::name () const
00465 {
00466     return *_i->first;
00467 }
00468 
00469 
00470 inline Attribute &      
00471 Header::Iterator::attribute () const
00472 {
00473     return *_i->second;
00474 }
00475 
00476 
00477 inline
00478 Header::ConstIterator::ConstIterator (): _i()
00479 {
00480     // empty
00481 }
00482 
00483 inline
00484 Header::ConstIterator::ConstIterator
00485     (const Header::AttributeMap::const_iterator &i): _i (i)
00486 {
00487     // empty
00488 }
00489 
00490 
00491 inline
00492 Header::ConstIterator::ConstIterator (const Header::Iterator &other):
00493     _i (other._i)
00494 {
00495     // empty
00496 }
00497 
00498 inline Header::ConstIterator &
00499 Header::ConstIterator::operator ++ ()
00500 {
00501     ++_i;
00502     return *this;
00503 }
00504 
00505 
00506 inline Header::ConstIterator            
00507 Header::ConstIterator::operator ++ (int)
00508 {
00509     ConstIterator tmp = *this;
00510     ++_i;
00511     return tmp;
00512 }
00513 
00514 
00515 inline const char *
00516 Header::ConstIterator::name () const
00517 {
00518     return *_i->first;
00519 }
00520 
00521 
00522 inline const Attribute &        
00523 Header::ConstIterator::attribute () const
00524 {
00525     return *_i->second;
00526 }
00527 
00528 
00529 inline bool
00530 operator == (const Header::ConstIterator &x, const Header::ConstIterator &y)
00531 {
00532     return x._i == y._i;
00533 }
00534 
00535 
00536 inline bool
00537 operator != (const Header::ConstIterator &x, const Header::ConstIterator &y)
00538 {
00539     return !(x == y);
00540 }
00541 
00542 
00543 //---------------------
00544 // Template definitions
00545 //---------------------
00546 
00547 template <class T>
00548 T &
00549 Header::typedAttribute (const char name[])
00550 {
00551     Attribute *attr = &(*this)[name];
00552     T *tattr = dynamic_cast <T*> (attr);
00553 
00554     if (tattr == 0)
00555         throw Iex::TypeExc ("Unexpected attribute type.");
00556 
00557     return *tattr;
00558 }
00559 
00560 
00561 template <class T>
00562 const T &
00563 Header::typedAttribute (const char name[]) const
00564 {
00565     const Attribute *attr = &(*this)[name];
00566     const T *tattr = dynamic_cast <const T*> (attr);
00567 
00568     if (tattr == 0)
00569         throw Iex::TypeExc ("Unexpected attribute type.");
00570 
00571     return *tattr;
00572 }
00573 
00574 
00575 template <class T>
00576 T &
00577 Header::typedAttribute (const std::string &name)
00578 {
00579     return typedAttribute<T> (name.c_str());
00580 }
00581 
00582 
00583 template <class T>
00584 const T &
00585 Header::typedAttribute (const std::string &name) const
00586 {
00587     return typedAttribute<T> (name.c_str());
00588 }
00589 
00590 
00591 template <class T>
00592 T *
00593 Header::findTypedAttribute (const char name[])
00594 {
00595     AttributeMap::iterator i = _map.find (name);
00596     return (i == _map.end())? 0: dynamic_cast <T*> (i->second);
00597 }
00598 
00599 
00600 template <class T>
00601 const T *
00602 Header::findTypedAttribute (const char name[]) const
00603 {
00604     AttributeMap::const_iterator i = _map.find (name);
00605     return (i == _map.end())? 0: dynamic_cast <const T*> (i->second);
00606 }
00607 
00608 
00609 template <class T>
00610 T *
00611 Header::findTypedAttribute (const std::string &name)
00612 {
00613     return findTypedAttribute<T> (name.c_str());
00614 }
00615 
00616 
00617 template <class T>
00618 const T *
00619 Header::findTypedAttribute (const std::string &name) const
00620 {
00621     return findTypedAttribute<T> (name.c_str());
00622 }
00623 
00624 
00625 } // namespace Imf
00626 
00627 #endif