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