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