1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2002, 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_CHANNEL_LIST_H 38 #define INCLUDED_IMF_CHANNEL_LIST_H 39 40 //----------------------------------------------------------------------------- 41 // 42 // class Channel 43 // class ChannelList 44 // 45 //----------------------------------------------------------------------------- 46 47 #include <ImfName.h> 48 #include <ImfPixelType.h> 49 #include <map> 50 #include <set> 51 #include <string> 52 53 54 namespace Imf { 55 56 57 struct Channel 58 { 59 //------------------------------ 60 // Data type; see ImfPixelType.h 61 //------------------------------ 62 63 PixelType type; 64 65 66 //-------------------------------------------- 67 // Subsampling: pixel (x, y) is present in the 68 // channel only if 69 // 70 // x % xSampling == 0 && y % ySampling == 0 71 // 72 //-------------------------------------------- 73 74 int xSampling; 75 int ySampling; 76 77 78 //-------------------------------------------------------------- 79 // Hint to lossy compression methods that indicates whether 80 // human perception of the quantity represented by this channel 81 // is closer to linear or closer to logarithmic. Compression 82 // methods may optimize image quality by adjusting pixel data 83 // quantization acording to this hint. 84 // For example, perception of red, green, blue and luminance is 85 // approximately logarithmic; the difference between 0.1 and 0.2 86 // is perceived to be roughly the same as the difference between 87 // 1.0 and 2.0. Perception of chroma coordinates tends to be 88 // closer to linear than logarithmic; the difference between 0.1 89 // and 0.2 is perceived to be roughly the same as the difference 90 // between 1.0 and 1.1. 91 //-------------------------------------------------------------- 92 93 bool pLinear; 94 95 96 //------------ 97 // Constructor 98 //------------ 99 100 Channel (PixelType type = HALF, 101 int xSampling = 1, 102 int ySampling = 1, 103 bool pLinear = false); 104 105 106 //------------ 107 // Operator == 108 //------------ 109 110 bool operator == (const Channel &other) const; 111 }; 112 113 114 class ChannelList 115 { 116 public: 117 118 //-------------- 119 // Add a channel 120 //-------------- 121 122 void insert (const char name[], 123 const Channel &channel); 124 125 void insert (const std::string &name, 126 const Channel &channel); 127 128 //------------------------------------------------------------------ 129 // Access to existing channels: 130 // 131 // [n] Returns a reference to the channel with name n. 132 // If no channel with name n exists, an Iex::ArgExc 133 // is thrown. 134 // 135 // findChannel(n) Returns a pointer to the channel with name n, 136 // or 0 if no channel with name n exists. 137 // 138 //------------------------------------------------------------------ 139 140 Channel & operator [] (const char name[]); 141 const Channel & operator [] (const char name[]) const; 142 143 Channel & operator [] (const std::string &name); 144 const Channel & operator [] (const std::string &name) const; 145 146 Channel * findChannel (const char name[]); 147 const Channel * findChannel (const char name[]) const; 148 149 Channel * findChannel (const std::string &name); 150 const Channel * findChannel (const std::string &name) const; 151 152 153 //------------------------------------------- 154 // Iterator-style access to existing channels 155 //------------------------------------------- 156 157 typedef std::map <Name, Channel> ChannelMap; 158 159 class Iterator; 160 class ConstIterator; 161 162 Iterator begin (); 163 ConstIterator begin () const; 164 165 Iterator end (); 166 ConstIterator end () const; 167 168 Iterator find (const char name[]); 169 ConstIterator find (const char name[]) const; 170 171 Iterator find (const std::string &name); 172 ConstIterator find (const std::string &name) const; 173 174 175 //----------------------------------------------------------------- 176 // Support for image layers: 177 // 178 // In an image file with many channels it is sometimes useful to 179 // group the channels into "layers", that is, into sets of channels 180 // that logically belong together. Grouping channels into layers 181 // is done using a naming convention: channel C in layer L is 182 // called "L.C". 183 // 184 // For example, a computer graphic image may contain separate 185 // R, G and B channels for light that originated at each of 186 // several different virtual light sources. The channels in 187 // this image might be called "light1.R", "light1.G", "light1.B", 188 // "light2.R", "light2.G", "light2.B", etc. 189 // 190 // Note that this naming convention allows layers to be nested; 191 // for example, "light1.specular.R" identifies the "R" channel 192 // in the "specular" sub-layer of layer "light1". 193 // 194 // Channel names that don't contain a "." or that contain a 195 // "." only at the beginning or at the end are not considered 196 // to be part of any layer. 197 // 198 // layers(lns) sorts the channels in this ChannelList 199 // into layers and stores the names of 200 // all layers, sorted alphabetically, 201 // into string set lns. 202 // 203 // channelsInLayer(ln,f,l) stores a pair of iterators in f and l 204 // such that the loop 205 // 206 // for (ConstIterator i = f; i != l; ++i) 207 // ... 208 // 209 // iterates over all channels in layer ln. 210 // channelsInLayer (ln, l, p) calls 211 // channelsWithPrefix (ln + ".", l, p). 212 // 213 //----------------------------------------------------------------- 214 215 void layers (std::set <std::string> &layerNames) const; 216 217 void channelsInLayer (const std::string &layerName, 218 Iterator &first, 219 Iterator &last); 220 221 void channelsInLayer (const std::string &layerName, 222 ConstIterator &first, 223 ConstIterator &last) const; 224 225 226 //------------------------------------------------------------------- 227 // Find all channels whose name begins with a given prefix: 228 // 229 // channelsWithPrefix(p,f,l) stores a pair of iterators in f and l 230 // such that the following loop iterates over all channels whose name 231 // begins with string p: 232 // 233 // for (ConstIterator i = f; i != l; ++i) 234 // ... 235 // 236 //------------------------------------------------------------------- 237 238 void channelsWithPrefix (const char prefix[], 239 Iterator &first, 240 Iterator &last); 241 242 void channelsWithPrefix (const char prefix[], 243 ConstIterator &first, 244 ConstIterator &last) const; 245 246 void channelsWithPrefix (const std::string &prefix, 247 Iterator &first, 248 Iterator &last); 249 250 void channelsWithPrefix (const std::string &prefix, 251 ConstIterator &first, 252 ConstIterator &last) const; 253 254 //------------ 255 // Operator == 256 //------------ 257 258 bool operator == (const ChannelList &other) const; 259 260 private: 261 262 ChannelMap _map; 263 }; 264 265 266 //---------- 267 // Iterators 268 //---------- 269 270 class ChannelList::Iterator 271 { 272 public: 273 274 Iterator (); 275 Iterator (const ChannelList::ChannelMap::iterator &i); 276 277 Iterator & operator ++ (); 278 Iterator operator ++ (int); 279 280 const char * name () const; 281 Channel & channel () const; 282 283 private: 284 285 friend class ChannelList::ConstIterator; 286 287 ChannelList::ChannelMap::iterator _i; 288 }; 289 290 291 class ChannelList::ConstIterator 292 { 293 public: 294 295 ConstIterator (); 296 ConstIterator (const ChannelList::ChannelMap::const_iterator &i); 297 ConstIterator (const ChannelList::Iterator &other); 298 299 ConstIterator & operator ++ (); 300 ConstIterator operator ++ (int); 301 302 const char * name () const; 303 const Channel & channel () const; 304 305 private: 306 307 friend bool operator == (const ConstIterator &, const ConstIterator &); 308 friend bool operator != (const ConstIterator &, const ConstIterator &); 309 310 ChannelList::ChannelMap::const_iterator _i; 311 }; 312 313 314 //----------------- 315 // Inline Functions 316 //----------------- 317 318 inline 319 ChannelList::Iterator::Iterator (): _i() 320 { 321 // empty 322 } 323 324 325 inline 326 ChannelList::Iterator::Iterator (const ChannelList::ChannelMap::iterator &i): 327 _i (i) 328 { 329 // empty 330 } 331 332 333 inline ChannelList::Iterator & 334 ChannelList::Iterator::operator ++ () 335 { 336 ++_i; 337 return *this; 338 } 339 340 341 inline ChannelList::Iterator 342 ChannelList::Iterator::operator ++ (int) 343 { 344 Iterator tmp = *this; 345 ++_i; 346 return tmp; 347 } 348 349 350 inline const char * 351 ChannelList::Iterator::name () const 352 { 353 return *_i->first; 354 } 355 356 357 inline Channel & 358 ChannelList::Iterator::channel () const 359 { 360 return _i->second; 361 } 362 363 364 inline 365 ChannelList::ConstIterator::ConstIterator (): _i() 366 { 367 // empty 368 } 369 370 inline 371 ChannelList::ConstIterator::ConstIterator 372 (const ChannelList::ChannelMap::const_iterator &i): _i (i) 373 { 374 // empty 375 } 376 377 378 inline 379 ChannelList::ConstIterator::ConstIterator (const ChannelList::Iterator &other): 380 _i (other._i) 381 { 382 // empty 383 } 384 385 inline ChannelList::ConstIterator & 386 ChannelList::ConstIterator::operator ++ () 387 { 388 ++_i; 389 return *this; 390 } 391 392 393 inline ChannelList::ConstIterator 394 ChannelList::ConstIterator::operator ++ (int) 395 { 396 ConstIterator tmp = *this; 397 ++_i; 398 return tmp; 399 } 400 401 402 inline const char * 403 ChannelList::ConstIterator::name () const 404 { 405 return *_i->first; 406 } 407 408 inline const Channel & 409 ChannelList::ConstIterator::channel () const 410 { 411 return _i->second; 412 } 413 414 415 inline bool 416 operator == (const ChannelList::ConstIterator &x, 417 const ChannelList::ConstIterator &y) 418 { 419 return x._i == y._i; 420 } 421 422 423 inline bool 424 operator != (const ChannelList::ConstIterator &x, 425 const ChannelList::ConstIterator &y) 426 { 427 return !(x == y); 428 } 429 430 431 } // namespace Imf 432 433 #endif 434