PBRT
|
00001 00002 // 00003 // Copyright (c) 2002, 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_CHANNEL_LIST_H 00038 #define INCLUDED_IMF_CHANNEL_LIST_H 00039 00040 //----------------------------------------------------------------------------- 00041 // 00042 // class Channel 00043 // class ChannelList 00044 // 00045 //----------------------------------------------------------------------------- 00046 00047 #include <ImfName.h> 00048 #include <ImfPixelType.h> 00049 #include <map> 00050 #include <set> 00051 #include <string> 00052 00053 00054 namespace Imf { 00055 00056 00057 struct Channel 00058 { 00059 //------------------------------ 00060 // Data type; see ImfPixelType.h 00061 //------------------------------ 00062 00063 PixelType type; 00064 00065 00066 //-------------------------------------------- 00067 // Subsampling: pixel (x, y) is present in the 00068 // channel only if 00069 // 00070 // x % xSampling == 0 && y % ySampling == 0 00071 // 00072 //-------------------------------------------- 00073 00074 int xSampling; 00075 int ySampling; 00076 00077 00078 //-------------------------------------------------------------- 00079 // Hint to lossy compression methods that indicates whether 00080 // human perception of the quantity represented by this channel 00081 // is closer to linear or closer to logarithmic. Compression 00082 // methods may optimize image quality by adjusting pixel data 00083 // quantization acording to this hint. 00084 // For example, perception of red, green, blue and luminance is 00085 // approximately logarithmic; the difference between 0.1 and 0.2 00086 // is perceived to be roughly the same as the difference between 00087 // 1.0 and 2.0. Perception of chroma coordinates tends to be 00088 // closer to linear than logarithmic; the difference between 0.1 00089 // and 0.2 is perceived to be roughly the same as the difference 00090 // between 1.0 and 1.1. 00091 //-------------------------------------------------------------- 00092 00093 bool pLinear; 00094 00095 00096 //------------ 00097 // Constructor 00098 //------------ 00099 00100 Channel (PixelType type = HALF, 00101 int xSampling = 1, 00102 int ySampling = 1, 00103 bool pLinear = false); 00104 00105 00106 //------------ 00107 // Operator == 00108 //------------ 00109 00110 bool operator == (const Channel &other) const; 00111 }; 00112 00113 00114 class ChannelList 00115 { 00116 public: 00117 00118 //-------------- 00119 // Add a channel 00120 //-------------- 00121 00122 void insert (const char name[], 00123 const Channel &channel); 00124 00125 void insert (const std::string &name, 00126 const Channel &channel); 00127 00128 //------------------------------------------------------------------ 00129 // Access to existing channels: 00130 // 00131 // [n] Returns a reference to the channel with name n. 00132 // If no channel with name n exists, an Iex::ArgExc 00133 // is thrown. 00134 // 00135 // findChannel(n) Returns a pointer to the channel with name n, 00136 // or 0 if no channel with name n exists. 00137 // 00138 //------------------------------------------------------------------ 00139 00140 Channel & operator [] (const char name[]); 00141 const Channel & operator [] (const char name[]) const; 00142 00143 Channel & operator [] (const std::string &name); 00144 const Channel & operator [] (const std::string &name) const; 00145 00146 Channel * findChannel (const char name[]); 00147 const Channel * findChannel (const char name[]) const; 00148 00149 Channel * findChannel (const std::string &name); 00150 const Channel * findChannel (const std::string &name) const; 00151 00152 00153 //------------------------------------------- 00154 // Iterator-style access to existing channels 00155 //------------------------------------------- 00156 00157 typedef std::map <Name, Channel> ChannelMap; 00158 00159 class Iterator; 00160 class ConstIterator; 00161 00162 Iterator begin (); 00163 ConstIterator begin () const; 00164 00165 Iterator end (); 00166 ConstIterator end () const; 00167 00168 Iterator find (const char name[]); 00169 ConstIterator find (const char name[]) const; 00170 00171 Iterator find (const std::string &name); 00172 ConstIterator find (const std::string &name) const; 00173 00174 00175 //----------------------------------------------------------------- 00176 // Support for image layers: 00177 // 00178 // In an image file with many channels it is sometimes useful to 00179 // group the channels into "layers", that is, into sets of channels 00180 // that logically belong together. Grouping channels into layers 00181 // is done using a naming convention: channel C in layer L is 00182 // called "L.C". 00183 // 00184 // For example, a computer graphic image may contain separate 00185 // R, G and B channels for light that originated at each of 00186 // several different virtual light sources. The channels in 00187 // this image might be called "light1.R", "light1.G", "light1.B", 00188 // "light2.R", "light2.G", "light2.B", etc. 00189 // 00190 // Note that this naming convention allows layers to be nested; 00191 // for example, "light1.specular.R" identifies the "R" channel 00192 // in the "specular" sub-layer of layer "light1". 00193 // 00194 // Channel names that don't contain a "." or that contain a 00195 // "." only at the beginning or at the end are not considered 00196 // to be part of any layer. 00197 // 00198 // layers(lns) sorts the channels in this ChannelList 00199 // into layers and stores the names of 00200 // all layers, sorted alphabetically, 00201 // into string set lns. 00202 // 00203 // channelsInLayer(ln,f,l) stores a pair of iterators in f and l 00204 // such that the loop 00205 // 00206 // for (ConstIterator i = f; i != l; ++i) 00207 // ... 00208 // 00209 // iterates over all channels in layer ln. 00210 // channelsInLayer (ln, l, p) calls 00211 // channelsWithPrefix (ln + ".", l, p). 00212 // 00213 //----------------------------------------------------------------- 00214 00215 void layers (std::set <std::string> &layerNames) const; 00216 00217 void channelsInLayer (const std::string &layerName, 00218 Iterator &first, 00219 Iterator &last); 00220 00221 void channelsInLayer (const std::string &layerName, 00222 ConstIterator &first, 00223 ConstIterator &last) const; 00224 00225 00226 //------------------------------------------------------------------- 00227 // Find all channels whose name begins with a given prefix: 00228 // 00229 // channelsWithPrefix(p,f,l) stores a pair of iterators in f and l 00230 // such that the following loop iterates over all channels whose name 00231 // begins with string p: 00232 // 00233 // for (ConstIterator i = f; i != l; ++i) 00234 // ... 00235 // 00236 //------------------------------------------------------------------- 00237 00238 void channelsWithPrefix (const char prefix[], 00239 Iterator &first, 00240 Iterator &last); 00241 00242 void channelsWithPrefix (const char prefix[], 00243 ConstIterator &first, 00244 ConstIterator &last) const; 00245 00246 void channelsWithPrefix (const std::string &prefix, 00247 Iterator &first, 00248 Iterator &last); 00249 00250 void channelsWithPrefix (const std::string &prefix, 00251 ConstIterator &first, 00252 ConstIterator &last) const; 00253 00254 //------------ 00255 // Operator == 00256 //------------ 00257 00258 bool operator == (const ChannelList &other) const; 00259 00260 private: 00261 00262 ChannelMap _map; 00263 }; 00264 00265 00266 //---------- 00267 // Iterators 00268 //---------- 00269 00270 class ChannelList::Iterator 00271 { 00272 public: 00273 00274 Iterator (); 00275 Iterator (const ChannelList::ChannelMap::iterator &i); 00276 00277 Iterator & operator ++ (); 00278 Iterator operator ++ (int); 00279 00280 const char * name () const; 00281 Channel & channel () const; 00282 00283 private: 00284 00285 friend class ChannelList::ConstIterator; 00286 00287 ChannelList::ChannelMap::iterator _i; 00288 }; 00289 00290 00291 class ChannelList::ConstIterator 00292 { 00293 public: 00294 00295 ConstIterator (); 00296 ConstIterator (const ChannelList::ChannelMap::const_iterator &i); 00297 ConstIterator (const ChannelList::Iterator &other); 00298 00299 ConstIterator & operator ++ (); 00300 ConstIterator operator ++ (int); 00301 00302 const char * name () const; 00303 const Channel & channel () const; 00304 00305 private: 00306 00307 friend bool operator == (const ConstIterator &, const ConstIterator &); 00308 friend bool operator != (const ConstIterator &, const ConstIterator &); 00309 00310 ChannelList::ChannelMap::const_iterator _i; 00311 }; 00312 00313 00314 //----------------- 00315 // Inline Functions 00316 //----------------- 00317 00318 inline 00319 ChannelList::Iterator::Iterator (): _i() 00320 { 00321 // empty 00322 } 00323 00324 00325 inline 00326 ChannelList::Iterator::Iterator (const ChannelList::ChannelMap::iterator &i): 00327 _i (i) 00328 { 00329 // empty 00330 } 00331 00332 00333 inline ChannelList::Iterator & 00334 ChannelList::Iterator::operator ++ () 00335 { 00336 ++_i; 00337 return *this; 00338 } 00339 00340 00341 inline ChannelList::Iterator 00342 ChannelList::Iterator::operator ++ (int) 00343 { 00344 Iterator tmp = *this; 00345 ++_i; 00346 return tmp; 00347 } 00348 00349 00350 inline const char * 00351 ChannelList::Iterator::name () const 00352 { 00353 return *_i->first; 00354 } 00355 00356 00357 inline Channel & 00358 ChannelList::Iterator::channel () const 00359 { 00360 return _i->second; 00361 } 00362 00363 00364 inline 00365 ChannelList::ConstIterator::ConstIterator (): _i() 00366 { 00367 // empty 00368 } 00369 00370 inline 00371 ChannelList::ConstIterator::ConstIterator 00372 (const ChannelList::ChannelMap::const_iterator &i): _i (i) 00373 { 00374 // empty 00375 } 00376 00377 00378 inline 00379 ChannelList::ConstIterator::ConstIterator (const ChannelList::Iterator &other): 00380 _i (other._i) 00381 { 00382 // empty 00383 } 00384 00385 inline ChannelList::ConstIterator & 00386 ChannelList::ConstIterator::operator ++ () 00387 { 00388 ++_i; 00389 return *this; 00390 } 00391 00392 00393 inline ChannelList::ConstIterator 00394 ChannelList::ConstIterator::operator ++ (int) 00395 { 00396 ConstIterator tmp = *this; 00397 ++_i; 00398 return tmp; 00399 } 00400 00401 00402 inline const char * 00403 ChannelList::ConstIterator::name () const 00404 { 00405 return *_i->first; 00406 } 00407 00408 inline const Channel & 00409 ChannelList::ConstIterator::channel () const 00410 { 00411 return _i->second; 00412 } 00413 00414 00415 inline bool 00416 operator == (const ChannelList::ConstIterator &x, 00417 const ChannelList::ConstIterator &y) 00418 { 00419 return x._i == y._i; 00420 } 00421 00422 00423 inline bool 00424 operator != (const ChannelList::ConstIterator &x, 00425 const ChannelList::ConstIterator &y) 00426 { 00427 return !(x == y); 00428 } 00429 00430 00431 } // namespace Imf 00432 00433 #endif