Coverage Report

Created: 2026-07-14 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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