PBRT
|
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