Coverage Report

Created: 2025-07-16 07:53

/usr/local/include/OpenEXR/ImfFrameBuffer.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// SPDX-License-Identifier: BSD-3-Clause
3
// Copyright (c) Contributors to the OpenEXR Project.
4
//
5
6
#ifndef INCLUDED_IMF_FRAME_BUFFER_H
7
#define INCLUDED_IMF_FRAME_BUFFER_H
8
9
//-----------------------------------------------------------------------------
10
//
11
//      class Slice
12
//      class FrameBuffer
13
//
14
//-----------------------------------------------------------------------------
15
16
#include "ImfForward.h"
17
18
#include "ImfName.h"
19
#include "ImfPixelType.h"
20
21
#include <ImathBox.h>
22
23
#include <cstdint>
24
#include <map>
25
#include <string>
26
27
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
28
29
//-------------------------------------------------------
30
// Description of a single slice of the frame buffer:
31
//
32
// Note -- terminology: as part of a file, a component of
33
// an image (e.g. red, green, blue, depth etc.) is called
34
// a "channel".  As part of a frame buffer, an image
35
// component is called a "slice".
36
//-------------------------------------------------------
37
38
struct IMF_EXPORT_TYPE Slice
39
{
40
    //------------------------------
41
    // Data type; see ImfPixelType.h
42
    //------------------------------
43
44
    PixelType type;
45
46
    //---------------------------------------------------------------------
47
    // Memory layout:  The address of pixel (x, y) is
48
    //
49
    //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
50
    //
51
    // where xp and yp are computed as follows:
52
    //
53
    //  * If we are reading or writing a scanline-based file:
54
    //
55
    //      xp = x
56
    //      yp = y
57
    //
58
    //  * If we are reading a tile whose upper left coorner is at (xt, yt):
59
    //
60
    //      if xTileCoords is true then xp = x - xt, else xp = x
61
    //      if yTileCoords is true then yp = y - yt, else yp = y
62
    //
63
    //---------------------------------------------------------------------
64
65
    char*  base;
66
    size_t xStride;
67
    size_t yStride;
68
69
    //--------------------------------------------
70
    // Subsampling: pixel (x, y) is present in the
71
    // slice only if
72
    //
73
    //  x % xSampling == 0 && y % ySampling == 0
74
    //
75
    //--------------------------------------------
76
77
    int xSampling;
78
    int ySampling;
79
80
    //----------------------------------------------------------
81
    // Default value, used to fill the slice when a file without
82
    // a channel that corresponds to this slice is read.
83
    //----------------------------------------------------------
84
85
    double fillValue;
86
87
    //-------------------------------------------------------
88
    // For tiled files, the xTileCoords and yTileCoords flags
89
    // determine whether pixel addressing is performed using
90
    // absolute coordinates or coordinates relative to a
91
    // tile's upper left corner.  (See the comment on base,
92
    // xStride and yStride, above.)
93
    //
94
    // For scanline-based files these flags have no effect;
95
    // pixel addressing is always done using absolute
96
    // coordinates.
97
    //-------------------------------------------------------
98
99
    bool xTileCoords;
100
    bool yTileCoords;
101
102
    //------------
103
    // Constructor
104
    //------------
105
106
    IMF_EXPORT
107
    Slice (
108
        PixelType type        = HALF,
109
        char*     base        = 0,
110
        size_t    xStride     = 0,
111
        size_t    yStride     = 0,
112
        int       xSampling   = 1,
113
        int       ySampling   = 1,
114
        double    fillValue   = 0.0,
115
        bool      xTileCoords = false,
116
        bool      yTileCoords = false);
117
118
    // Does the heavy lifting of computing the base pointer for a slice,
119
    // avoiding overflow issues with large origin offsets
120
    //
121
    // if xStride == 0, assumes sizeof(pixeltype)
122
    // if yStride == 0, assumes xStride * ( w / xSampling )
123
    IMF_EXPORT
124
    static Slice Make (
125
        PixelType                   type,
126
        const void*                 ptr,
127
        const IMATH_NAMESPACE::V2i& origin,
128
        int64_t                     w,
129
        int64_t                     h,
130
        size_t                      xStride     = 0,
131
        size_t                      yStride     = 0,
132
        int                         xSampling   = 1,
133
        int                         ySampling   = 1,
134
        double                      fillValue   = 0.0,
135
        bool                        xTileCoords = false,
136
        bool                        yTileCoords = false);
137
    // same as above, just computes w and h for you
138
    // from a data window
139
    IMF_EXPORT
140
    static Slice Make (
141
        PixelType                     type,
142
        const void*                   ptr,
143
        const IMATH_NAMESPACE::Box2i& dataWindow,
144
        size_t                        xStride     = 0,
145
        size_t                        yStride     = 0,
146
        int                           xSampling   = 1,
147
        int                           ySampling   = 1,
148
        double                        fillValue   = 0.0,
149
        bool                          xTileCoords = false,
150
        bool                          yTileCoords = false);
151
};
152
153
class IMF_EXPORT_TYPE FrameBuffer
154
{
155
public:
156
    //------------
157
    // Add a slice
158
    //------------
159
160
    IMF_EXPORT
161
    void insert (const char name[], const Slice& slice);
162
163
    IMF_EXPORT
164
    void insert (const std::string& name, const Slice& slice);
165
166
    //----------------------------------------------------------------
167
    // Access to existing slices:
168
    //
169
    // [n]              Returns a reference to the slice with name n.
170
    //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
171
    //                  is thrown.
172
    //
173
    // findSlice(n)     Returns a pointer to the slice with name n,
174
    //                  or 0 if no slice with name n exists.
175
    //
176
    //----------------------------------------------------------------
177
178
    IMF_EXPORT
179
    Slice& operator[] (const char name[]);
180
    IMF_EXPORT
181
    const Slice& operator[] (const char name[]) const;
182
183
    IMF_EXPORT
184
    Slice& operator[] (const std::string& name);
185
    IMF_EXPORT
186
    const Slice& operator[] (const std::string& name) const;
187
188
    IMF_EXPORT
189
    Slice* findSlice (const char name[]);
190
    IMF_EXPORT
191
    const Slice* findSlice (const char name[]) const;
192
193
    IMF_EXPORT
194
    Slice* findSlice (const std::string& name);
195
    IMF_EXPORT
196
    const Slice* findSlice (const std::string& name) const;
197
198
    //-----------------------------------------
199
    // Iterator-style access to existing slices
200
    //-----------------------------------------
201
202
    typedef std::map<Name, Slice> SliceMap;
203
204
    class Iterator;
205
    class ConstIterator;
206
207
    IMF_EXPORT
208
    Iterator begin ();
209
    IMF_EXPORT
210
    ConstIterator begin () const;
211
212
    IMF_EXPORT
213
    Iterator end ();
214
    IMF_EXPORT
215
    ConstIterator end () const;
216
217
    IMF_EXPORT
218
    Iterator find (const char name[]);
219
    IMF_EXPORT
220
    ConstIterator find (const char name[]) const;
221
222
    IMF_EXPORT
223
    Iterator find (const std::string& name);
224
    IMF_EXPORT
225
    ConstIterator find (const std::string& name) const;
226
227
private:
228
    SliceMap _map;
229
};
230
231
//----------
232
// Iterators
233
//----------
234
235
class IMF_EXPORT_TYPE FrameBuffer::Iterator
236
{
237
public:
238
    IMF_EXPORT
239
    Iterator ();
240
    IMF_EXPORT
241
    Iterator (const FrameBuffer::SliceMap::iterator& i);
242
243
    IMF_EXPORT
244
    Iterator& operator++ ();
245
    IMF_EXPORT
246
    Iterator operator++ (int);
247
248
    IMF_EXPORT
249
    const char* name () const;
250
    IMF_EXPORT
251
    Slice& slice () const;
252
253
private:
254
    friend class FrameBuffer::ConstIterator;
255
256
    FrameBuffer::SliceMap::iterator _i;
257
};
258
259
class IMF_EXPORT_TYPE FrameBuffer::ConstIterator
260
{
261
public:
262
    IMF_EXPORT
263
    ConstIterator ();
264
    IMF_EXPORT
265
    ConstIterator (const FrameBuffer::SliceMap::const_iterator& i);
266
    IMF_EXPORT
267
    ConstIterator (const FrameBuffer::Iterator& other);
268
269
    IMF_EXPORT
270
    ConstIterator& operator++ ();
271
    IMF_EXPORT
272
    ConstIterator operator++ (int);
273
274
    IMF_EXPORT
275
    const char* name () const;
276
    IMF_EXPORT
277
    const Slice& slice () const;
278
279
private:
280
    friend bool operator== (const ConstIterator&, const ConstIterator&);
281
    friend bool operator!= (const ConstIterator&, const ConstIterator&);
282
283
    FrameBuffer::SliceMap::const_iterator _i;
284
};
285
286
//-----------------
287
// Inline Functions
288
//-----------------
289
290
inline FrameBuffer::Iterator::Iterator () : _i ()
291
{
292
    // empty
293
}
294
295
inline FrameBuffer::Iterator::Iterator (
296
    const FrameBuffer::SliceMap::iterator& i)
297
    : _i (i)
298
{
299
    // empty
300
}
301
302
inline FrameBuffer::Iterator&
303
FrameBuffer::Iterator::operator++ ()
304
0
{
305
0
    ++_i;
306
0
    return *this;
307
0
}
308
309
inline FrameBuffer::Iterator
310
FrameBuffer::Iterator::operator++ (int)
311
{
312
    Iterator tmp = *this;
313
    ++_i;
314
    return tmp;
315
}
316
317
inline const char*
318
FrameBuffer::Iterator::name () const
319
0
{
320
0
    return *_i->first;
321
0
}
322
323
inline Slice&
324
FrameBuffer::Iterator::slice () const
325
{
326
    return _i->second;
327
}
328
329
inline FrameBuffer::ConstIterator::ConstIterator () : _i ()
330
{
331
    // empty
332
}
333
334
inline FrameBuffer::ConstIterator::ConstIterator (
335
    const FrameBuffer::SliceMap::const_iterator& i)
336
    : _i (i)
337
{
338
    // empty
339
}
340
341
inline FrameBuffer::ConstIterator::ConstIterator (
342
    const FrameBuffer::Iterator& other)
343
    : _i (other._i)
344
{
345
    // empty
346
}
347
348
inline FrameBuffer::ConstIterator&
349
FrameBuffer::ConstIterator::operator++ ()
350
{
351
    ++_i;
352
    return *this;
353
}
354
355
inline FrameBuffer::ConstIterator
356
FrameBuffer::ConstIterator::operator++ (int)
357
{
358
    ConstIterator tmp = *this;
359
    ++_i;
360
    return tmp;
361
}
362
363
inline const char*
364
FrameBuffer::ConstIterator::name () const
365
{
366
    return *_i->first;
367
}
368
369
inline const Slice&
370
FrameBuffer::ConstIterator::slice () const
371
{
372
    return _i->second;
373
}
374
375
inline bool
376
operator== (
377
    const FrameBuffer::ConstIterator& x, const FrameBuffer::ConstIterator& y)
378
{
379
    return x._i == y._i;
380
}
381
382
inline bool
383
operator!= (
384
    const FrameBuffer::ConstIterator& x, const FrameBuffer::ConstIterator& y)
385
{
386
    return !(x == y);
387
}
388
389
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
390
391
#endif