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