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