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
Iterator()319 ChannelList::Iterator::Iterator (): _i()
320 {
321 // empty
322 }
323
324
325 inline
Iterator(const ChannelList::ChannelMap::iterator & i)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 *
name()351 ChannelList::Iterator::name () const
352 {
353 return *_i->first;
354 }
355
356
357 inline Channel &
channel()358 ChannelList::Iterator::channel () const
359 {
360 return _i->second;
361 }
362
363
364 inline
ConstIterator()365 ChannelList::ConstIterator::ConstIterator (): _i()
366 {
367 // empty
368 }
369
370 inline
ConstIterator(const ChannelList::ChannelMap::const_iterator & i)371 ChannelList::ConstIterator::ConstIterator
372 (const ChannelList::ChannelMap::const_iterator &i): _i (i)
373 {
374 // empty
375 }
376
377
378 inline
ConstIterator(const ChannelList::Iterator & other)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 *
name()403 ChannelList::ConstIterator::name () const
404 {
405 return *_i->first;
406 }
407
408 inline const Channel &
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