1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5
6 //----------------------------------------------------------------------------
7 //
8 // class DeepImageChannel
9 //
10 //----------------------------------------------------------------------------
11 #include "ImfUtilExport.h"
12 #include <ImathExport.h>
13 #include <ImathNamespace.h>
14
15 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
16 class IMFUTIL_EXPORT_TYPE half;
17 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
18
19 #define COMPILING_IMF_DEEP_IMAGE_CHANNEL
20
21 #include "ImfDeepImageChannel.h"
22 #include "ImfDeepImageLevel.h"
23 #include <Iex.h>
24
25 using namespace IMATH_NAMESPACE;
26 using namespace IEX_NAMESPACE;
27 using namespace std;
28
29 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
30
31
DeepImageChannel(DeepImageLevel & level,bool pLinear)32 DeepImageChannel::DeepImageChannel
33 (DeepImageLevel &level,
34 bool pLinear)
35 :
36 ImageChannel (level, 1, 1, pLinear)
37 {
38 // empty
39 }
40
41
~DeepImageChannel()42 DeepImageChannel::~DeepImageChannel ()
43 {
44 // empty
45 }
46
47 DeepImageLevel &
deepLevel()48 DeepImageChannel::deepLevel ()
49 {
50 return static_cast <DeepImageLevel &> (level());
51 }
52
53
54 const DeepImageLevel &
deepLevel() const55 DeepImageChannel::deepLevel () const
56 {
57 return static_cast <const DeepImageLevel &> (level());
58 }
59
60
61 SampleCountChannel &
sampleCounts()62 DeepImageChannel::sampleCounts ()
63 {
64 return deepLevel().sampleCounts();
65 }
66
67
68 const SampleCountChannel &
sampleCounts() const69 DeepImageChannel::sampleCounts () const
70 {
71 return deepLevel().sampleCounts();
72 }
73
74
75 void
resize()76 DeepImageChannel::resize ()
77 {
78 ImageChannel::resize();
79 }
80
81 //-----------------------------------------------------------------------------
82
83 template <class T>
TypedDeepImageChannel(DeepImageLevel & level,bool pLinear)84 TypedDeepImageChannel<T>::TypedDeepImageChannel
85 (DeepImageLevel &level,
86 bool pLinear)
87 :
88 DeepImageChannel (level, pLinear),
89 _sampleListPointers (0),
90 _base (0),
91 _sampleBuffer (0)
92 {
93 resize();
94 }
95
96
97 template <class T>
~TypedDeepImageChannel()98 TypedDeepImageChannel<T>::~TypedDeepImageChannel ()
99 {
100 delete [] _sampleListPointers;
101 delete [] _sampleBuffer;
102 }
103
104
105 template <class T>
106 DeepSlice
slice() const107 TypedDeepImageChannel<T>::slice () const
108 {
109 return DeepSlice (pixelType(), // type
110 (char *) _base, // base
111 sizeof (T*), // xStride
112 pixelsPerRow() * sizeof (T*), // yStride
113 sizeof (T), // sampleStride
114 xSampling(),
115 ySampling());
116 }
117 template <class T>
118 void
setSamplesToZero(size_t i,unsigned int oldNumSamples,unsigned int newNumSamples)119 TypedDeepImageChannel<T>::setSamplesToZero
120 (size_t i,
121 unsigned int oldNumSamples,
122 unsigned int newNumSamples)
123 {
124 //
125 // Expand the size of a sample list for a single pixel and
126 // set the new samples in the list to 0.
127 //
128 // i The position of the affected pixel in
129 // the channel's _sampleListPointers.
130 //
131 // oldNumSamples Original number of samples in the sample list.
132 //
133 // newNumSamples New number of samples in the sample list.
134 //
135
136 for (unsigned int j = oldNumSamples; j < newNumSamples; ++j)
137 _sampleListPointers[i][j] = 0;
138 }
139
140
141 template <class T>
142 void
moveSampleList(size_t i,unsigned int oldNumSamples,unsigned int newNumSamples,size_t newSampleListPosition)143 TypedDeepImageChannel<T>::moveSampleList
144 (size_t i,
145 unsigned int oldNumSamples,
146 unsigned int newNumSamples,
147 size_t newSampleListPosition)
148 {
149 //
150 // Resize the sample list for a single pixel and move it to a new
151 // position in the sample buffer for this channel.
152 //
153 // i The position of the affected pixel in
154 // the channel's _sampleListPointers.
155 //
156 // oldNumSamples Original number of samples in sample list.
157 //
158 // newNumSamples New number of samples in the sample list.
159 // If the new number of samples is larger than
160 // the old number of samples for a given sample
161 // list, then the end of the new sample list
162 // is filled with zeroes. If the new number of
163 // samples is smaller than the old one, then
164 // samples at the end of the old sample list
165 // are discarded.
166 //
167 // newSampleListPosition The new position of the sample list in the
168 // sample buffer.
169 //
170
171 T * oldSampleList = _sampleListPointers[i];
172 T * newSampleList = _sampleBuffer + newSampleListPosition;
173
174 if (oldNumSamples > newNumSamples)
175 {
176 for (unsigned int j = 0; j < newNumSamples; ++j)
177 newSampleList[j] = oldSampleList[j];
178 }
179 else
180 {
181 for (unsigned int j = 0; j < oldNumSamples; ++j)
182 newSampleList[j] = oldSampleList[j];
183
184 for (unsigned int j = oldNumSamples; j < newNumSamples; ++j)
185 newSampleList[j] = 0;
186 }
187
188 _sampleListPointers[i] = newSampleList;
189 }
190
191
192 template <class T>
193 void
moveSamplesToNewBuffer(const unsigned int * oldNumSamples,const unsigned int * newNumSamples,const size_t * newSampleListPositions)194 TypedDeepImageChannel<T>::moveSamplesToNewBuffer
195 (const unsigned int * oldNumSamples,
196 const unsigned int * newNumSamples,
197 const size_t * newSampleListPositions)
198 {
199 //
200 // Allocate a new sample buffer for this channel.
201 // Copy the sample lists for all pixels into the new buffer.
202 // Then delete the old sample buffer.
203 //
204 // oldNumSamples Number of samples in each sample list in the
205 // old sample buffer.
206 //
207 // newNumSamples Number of samples in each sample list in
208 // the new sample buffer. If the new number
209 // of samples is larger than the old number of
210 // samples for a given sample list, then the
211 // end of the new sample list is filled with
212 // zeroes. If the new number of samples is
213 // smaller than the old one, then samples at
214 // the end of the old sample list are discarded.
215 //
216 // newSampleListPositions The positions of the new sample lists in the
217 // new sample buffer.
218 //
219
220 T * oldSampleBuffer = _sampleBuffer;
221 _sampleBuffer = new T [sampleCounts().sampleBufferSize()];
222
223 for (size_t i = 0; i < numPixels(); ++i)
224 {
225 T * oldSampleList = _sampleListPointers[i];
226 T * newSampleList = _sampleBuffer + newSampleListPositions[i];
227
228 if (oldNumSamples[i] > newNumSamples[i])
229 {
230 for (unsigned int j = 0; j < newNumSamples[i]; ++j)
231 newSampleList[j] = oldSampleList[j];
232 }
233 else
234 {
235 for (unsigned int j = 0; j < oldNumSamples[i]; ++j)
236 newSampleList[j] = oldSampleList[j];
237
238 for (unsigned int j = oldNumSamples[i]; j < newNumSamples[i]; ++j)
239 newSampleList[j] = 0;
240 }
241
242 _sampleListPointers[i] = newSampleList;
243 }
244
245 delete [] oldSampleBuffer;
246 }
247
248
249 template <class T>
250 void
initializeSampleLists()251 TypedDeepImageChannel<T>::initializeSampleLists ()
252 {
253 //
254 // Allocate a new set of sample lists for this channel, and
255 // construct zero-filled sample lists for the pixels.
256 //
257
258 delete [] _sampleBuffer;
259
260 _sampleBuffer = 0; // set to 0 to prevent double deletion
261 // in case of an exception
262
263 const unsigned int * numSamples = sampleCounts().numSamples();
264 const size_t * sampleListPositions = sampleCounts().sampleListPositions();
265
266 _sampleBuffer = new T [sampleCounts().sampleBufferSize()];
267
268 resetBasePointer();
269
270 for (size_t i = 0; i < numPixels(); ++i)
271 {
272 _sampleListPointers[i] = _sampleBuffer + sampleListPositions[i];
273
274 for (unsigned int j = 0; j < numSamples[i]; ++j)
275 _sampleListPointers[i][j] = T (0);
276 }
277 }
278
279 template <class T>
280 void
resize()281 TypedDeepImageChannel<T>::resize ()
282 {
283 DeepImageChannel::resize();
284
285 delete [] _sampleListPointers;
286 _sampleListPointers = 0;
287 _sampleListPointers = new T * [numPixels()];
288 initializeSampleLists();
289 }
290
291
292 template <class T>
293 void
resetBasePointer()294 TypedDeepImageChannel<T>::resetBasePointer ()
295 {
296 _base = _sampleListPointers -
297 level().dataWindow().min.y * pixelsPerRow() -
298 level().dataWindow().min.x;
299 }
300
301
302 template <>
303 PixelType
pixelType() const304 TypedDeepImageChannel<half>::pixelType () const
305 {
306 return HALF;
307 }
308
309
310 template <>
311 PixelType
pixelType() const312 TypedDeepImageChannel<float>::pixelType () const
313 {
314 return FLOAT;
315 }
316
317
318 template <>
319 PixelType
pixelType() const320 TypedDeepImageChannel<unsigned int>::pixelType () const
321 {
322 return UINT;
323 }
324
325
326 template class IMFUTIL_EXPORT_TEMPLATE_INSTANCE TypedDeepImageChannel<half>;
327 template class IMFUTIL_EXPORT_TEMPLATE_INSTANCE TypedDeepImageChannel<float>;
328 template class IMFUTIL_EXPORT_TEMPLATE_INSTANCE TypedDeepImageChannel<unsigned int>;
329
330
331 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
332