Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/usr/local/include/OpenEXR/ImfArray.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_ARRAY_H
7
#define INCLUDED_IMF_ARRAY_H
8
9
#include "ImfForward.h"
10
#include "IexBaseExc.h"
11
#include "IexMathExc.h"
12
13
#include <cstddef>
14
#include <cstdint>
15
#include <limits>
16
17
//-------------------------------------------------------------------------
18
//
19
// class Array
20
// class Array2D
21
//
22
// "Arrays of T" whose sizes are not known at compile time.
23
// When an array goes out of scope, its elements are automatically
24
// deleted.
25
//
26
// Usage example:
27
//
28
//  struct C
29
//  {
30
//      C ()    {std::cout << "C::C  (" << this << ")\n";};
31
//      virtual ~C () {std::cout << "C::~C (" << this << ")\n";};
32
//  };
33
//
34
//  int
35
//  main ()
36
//  {
37
//      Array <C> a(3);
38
//
39
//      C &b = a[1];
40
//      const C &c = a[1];
41
//      C *d = a + 2;
42
//      const C *e = a;
43
//
44
//      return 0;
45
//  }
46
//
47
//-------------------------------------------------------------------------
48
49
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
50
51
template <class T> class IMF_EXPORT_TEMPLATE_TYPE Array
52
{
53
public:
54
    //-----------------------------
55
    // Constructors and destructors
56
    //-----------------------------
57
58
    Array ()
59
    {
60
        _data = 0;
61
        _size = 0;
62
    }
63
    Array (long size) : _size (0), _data (0)
64
    {
65
        if (size < 0)
66
            throw IEX_NAMESPACE::ArgExc ("Array size must be non-negative");
67
68
        _data = new T[size];
69
        _size = size;
70
    }
71
    ~Array () { delete[] _data; }
72
73
    //-----------------------------
74
    // Access to the array elements
75
    //-----------------------------
76
77
    operator T* () { return _data; }
78
48.2k
    operator const T* () const { return _data; }
79
80
    //------------------------------------------------------
81
    // Resize and clear the array (the contents of the array
82
    // are not preserved across the resize operation).
83
    //
84
    // resizeEraseUnsafe() is more memory efficient than
85
    // resizeErase() because it deletes the old memory block
86
    // before allocating a new one, but if allocating the
87
    // new block throws an exception, resizeEraseUnsafe()
88
    // leaves the array in an unusable state.
89
    //
90
    //------------------------------------------------------
91
92
    void resizeErase (long size);
93
    void resizeEraseUnsafe (long size);
94
95
    //-------------------------------
96
    // Return the size of this array.
97
    //-------------------------------
98
99
1.78k
    long size () const { return _size; }
100
101
private:
102
    Array (const Array&)            = delete;
103
    Array& operator= (const Array&) = delete;
104
    Array (Array&&)                 = delete;
105
    Array& operator= (Array&&)      = delete;
106
107
    long _size;
108
    T*   _data;
109
};
110
111
template <class T> class IMF_EXPORT_TEMPLATE_TYPE Array2D
112
{
113
public:
114
    //-----------------------------
115
    // Constructors and destructors
116
    //-----------------------------
117
118
    Array2D ();                       // empty array, 0 by 0 elements
119
    Array2D (long sizeX, long sizeY); // sizeX by sizeY elements
120
    ~Array2D ();
121
122
    //-----------------------------
123
    // Access to the array elements
124
    //-----------------------------
125
126
    T*       operator[] (long x);
127
    const T* operator[] (long x) const;
128
129
    //------------------------------------------------------
130
    // Resize and clear the array (the contents of the array
131
    // are not preserved across the resize operation).
132
    //
133
    // resizeEraseUnsafe() is more memory efficient than
134
    // resizeErase() because it deletes the old memory block
135
    // before allocating a new one, but if allocating the
136
    // new block throws an exception, resizeEraseUnsafe()
137
    // leaves the array in an unusable state.
138
    //
139
    //------------------------------------------------------
140
141
    void resizeErase (long sizeX, long sizeY);
142
    void resizeEraseUnsafe (long sizeX, long sizeY);
143
144
    //-------------------------------
145
    // Return the size of this array.
146
    //-------------------------------
147
148
0
    long height () const { return _sizeX; }
149
0
    long width () const { return _sizeY; }
150
151
private:
152
    Array2D (const Array2D&)            = delete;
153
    Array2D& operator= (const Array2D&) = delete;
154
    Array2D (Array2D&&)                 = delete;
155
    Array2D& operator= (Array2D&&)      = delete;
156
157
    long _sizeX;
158
    long _sizeY;
159
    T*   _data;
160
};
161
162
//---------------
163
// Implementation
164
//---------------
165
166
namespace {
167
168
inline size_t
169
array2DElementCount (long sizeX, long sizeY)
170
2.28k
{
171
2.28k
    const uint64_t x       = static_cast<uint64_t> (sizeX);
172
2.28k
    const uint64_t y       = static_cast<uint64_t> (sizeY);
173
2.28k
    const uint64_t maxSize = std::numeric_limits<size_t>::max ();
174
2.28k
    if (y > 0 && x > maxSize / y)
175
0
        throw IEX_NAMESPACE::OverflowExc ("Array2D dimensions too large");
176
2.28k
    return static_cast<size_t> (x * y);
177
2.28k
}
178
179
} // namespace
180
181
template <class T>
182
inline void
183
Array<T>::resizeErase (long size)
184
{
185
    if (size < 0)
186
        throw IEX_NAMESPACE::ArgExc ("Array size must be non-negative");
187
188
    T* tmp = new T[size];
189
    delete[] _data;
190
    _size = size;
191
    _data = tmp;
192
}
193
194
template <class T>
195
inline void
196
Array<T>::resizeEraseUnsafe (long size)
197
{
198
    if (size < 0)
199
        throw IEX_NAMESPACE::ArgExc ("Array size must be non-negative");
200
201
    delete[] _data;
202
    _data = 0;
203
    _size = 0;
204
    _data = new T[size];
205
    _size = size;
206
}
207
208
template <class T>
209
2.28k
inline Array2D<T>::Array2D () : _sizeX (0), _sizeY (0), _data (0)
210
2.28k
{
211
    // empty
212
2.28k
}
Imf_3_4::Array2D<Imf_3_4::Rgba>::Array2D()
Line
Count
Source
209
2.28k
inline Array2D<T>::Array2D () : _sizeX (0), _sizeY (0), _data (0)
210
2.28k
{
211
    // empty
212
2.28k
}
Unexecuted instantiation: Imf_3_4::Array2D<Imf_3_4::PreviewRgba>::Array2D()
213
214
template <class T>
215
inline Array2D<T>::Array2D (long sizeX, long sizeY)
216
    : _sizeX (0), _sizeY (0), _data (0)
217
{
218
    if (sizeX < 0 || sizeY < 0)
219
        throw IEX_NAMESPACE::ArgExc ("Array2D dimensions must be non-negative");
220
221
    _sizeX = sizeX;
222
    _sizeY = sizeY;
223
    _data  = new T[array2DElementCount (sizeX, sizeY)];
224
}
225
226
template <class T> inline Array2D<T>::~Array2D ()
227
2.28k
{
228
2.28k
    delete[] _data;
229
2.28k
}
Imf_3_4::Array2D<Imf_3_4::Rgba>::~Array2D()
Line
Count
Source
227
2.28k
{
228
2.28k
    delete[] _data;
229
2.28k
}
Unexecuted instantiation: Imf_3_4::Array2D<Imf_3_4::PreviewRgba>::~Array2D()
230
231
template <class T>
232
inline T*
233
Array2D<T>::operator[] (long x)
234
486M
{
235
486M
    return _data + x * _sizeY;
236
486M
}
Imf_3_4::Array2D<Imf_3_4::Rgba>::operator[](long)
Line
Count
Source
234
486M
{
235
486M
    return _data + x * _sizeY;
236
486M
}
Unexecuted instantiation: Imf_3_4::Array2D<Imf_3_4::PreviewRgba>::operator[](long)
237
238
template <class T>
239
inline const T*
240
Array2D<T>::operator[] (long x) const
241
{
242
    return _data + x * _sizeY;
243
}
244
245
template <class T>
246
inline void
247
Array2D<T>::resizeErase (long sizeX, long sizeY)
248
2.28k
{
249
2.28k
    if (sizeX < 0 || sizeY < 0)
250
0
        throw IEX_NAMESPACE::ArgExc ("Array2D dimensions must be non-negative");
251
252
2.28k
    T* tmp = new T[array2DElementCount (sizeX, sizeY)];
253
2.28k
    delete[] _data;
254
2.28k
    _sizeX = sizeX;
255
2.28k
    _sizeY = sizeY;
256
2.28k
    _data  = tmp;
257
2.28k
}
Imf_3_4::Array2D<Imf_3_4::Rgba>::resizeErase(long, long)
Line
Count
Source
248
2.28k
{
249
2.28k
    if (sizeX < 0 || sizeY < 0)
250
0
        throw IEX_NAMESPACE::ArgExc ("Array2D dimensions must be non-negative");
251
252
2.28k
    T* tmp = new T[array2DElementCount (sizeX, sizeY)];
253
2.28k
    delete[] _data;
254
2.28k
    _sizeX = sizeX;
255
2.28k
    _sizeY = sizeY;
256
2.28k
    _data  = tmp;
257
2.28k
}
Unexecuted instantiation: Imf_3_4::Array2D<Imf_3_4::PreviewRgba>::resizeErase(long, long)
258
259
template <class T>
260
inline void
261
Array2D<T>::resizeEraseUnsafe (long sizeX, long sizeY)
262
{
263
    if (sizeX < 0 || sizeY < 0)
264
        throw IEX_NAMESPACE::ArgExc ("Array2D dimensions must be non-negative");
265
266
    delete[] _data;
267
    _data  = 0;
268
    _sizeX = 0;
269
    _sizeY = 0;
270
    _data  = new T[array2DElementCount (sizeX, sizeY)];
271
    _sizeX = sizeX;
272
    _sizeY = sizeY;
273
}
274
275
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
276
277
#endif