HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfSampleCountChannel.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifndef INCLUDED_IMF_SAMPLE_COUNT_CHANNEL_H
7 #define INCLUDED_IMF_SAMPLE_COUNT_CHANNEL_H
8 
9 //----------------------------------------------------------------------------
10 //
11 // class SampleCountChannel
12 //
13 // For an explanation of images, levels and channels,
14 // see the comments in header file Image.h.
15 //
16 //----------------------------------------------------------------------------
17 
18 #include "ImfUtilExport.h"
19 #include "ImfImageChannel.h"
20 
22 
23 class DeepImageLevel;
24 
25 //
26 // Sample count channel for a deep image level:
27 //
28 // Each deep image level has a number of samples channel. For each
29 // pixel location (x,y) within the data window of the level, the sample
30 // count channel stores a single integer, n(x,y). A deep channel, c,
31 // in the level as the sample count channel stores n(x,y) samples at
32 // location (x,y) if
33 //
34 // x % c.xSampling() == 0 and y % c.ySampling() == 0.
35 //
36 // The deep channel stores no samples at location (x,y) if
37 //
38 // x % c.xSampling() != 0 or y % c.ySampling() != 0,
39 //
40 
42 {
43  public:
44 
45  //
46  // The OpenEXR pixel type of this channel (HALF, FLOAT or UINT).
47  //
48 
50  virtual PixelType pixelType () const;
51 
52 
53  //
54  // Construct an OpenEXR frame buffer slice for this channel.
55  // This function is needed reading an image from an OpenEXR
56  // file and for saving an image in an OpenEXR file.
57  //
58 
60  Slice slice () const;
61 
62 
63  //
64  // Access to the image level to which this channel belongs.
65  //
66 
68  DeepImageLevel & deepLevel ();
70  const DeepImageLevel & deepLevel () const;
71 
72 
73  //
74  // Access to n(x,y), without bounds checking. Accessing a location
75  // outside the data window of the image level results in undefined
76  // behavior.
77  //
78 
80  const unsigned int & operator () (int x, int y) const;
81 
82 
83  //
84  // Access to n(x,y), with bounds checking. Accessing a location outside
85  // the data window of the image level throws an Iex::ArgExc exception.
86  //
87 
89  const unsigned int & at (int x, int y) const;
90 
91  //
92  // Faster access to n(x,y) for all pixels in a single horizontal row of
93  // the channel. Rows are numbered from 0 to pixelsPerColumn()-1, and
94  // each row contains pixelsPerRow() values.
95  // Access is not bounds checked; accessing out of bounds rows or pixels
96  // results in undefined behavior.
97  //
98 
100  const unsigned int * row (int r) const;
101 
102 
103  //
104  // Change the sample counts in one or more pixels:
105  //
106  // set(x,y,m) sets n(x,y) to m.
107  //
108  // set(r,m) sets n(x,y) for all pixels in row r according to the
109  // values in array m. The array must contain pixelsPerRow()
110  // entries, and the row number must be in the range from 0
111  // to pixelsPerColumn()-1.
112  //
113  // clear() sets n(x,y) to 0 for all pixels within the data window
114  // of the level.
115  //
116  // If the sample count for a pixel is increased, then new samples are
117  // appended at the end of the sample list of each deep channel. The
118  // new samples are initialized to zero. If the sample count in a pixel
119  // is decreased, then sample list of each deep channel is truncated by
120  // discarding samples at the end of the list.
121  //
122  // Access is bounds-checked; attempting to set the number of samples of
123  // a pixel outside the data window throws an Iex::ArgExc exception.
124  //
125  // Memory allocation for the sample lists is not particularly clever;
126  // repeatedly increasing and decreasing the number of samples in the
127  // pixels of a level is likely to result in serious memory fragmentation.
128  //
129  // Setting the number of samples for one or more pixels may cause the
130  // program to run out of memory. If this happens, the image is resized
131  // to zero by zero pixels and an exception is thrown. Note that the
132  // resizing operation deletes this sample count channel and the image
133  // level to which it belongs.
134  //
135 
137  void set(int x, int y, unsigned int newNumSamples);
139  void set(int r, unsigned int newNumSamples[]);
141  void clear();
142 
143 
144  //
145  // OpenEXR file reading support / make sample counts editable:
146  //
147  // beginEdit() frees all memory that has been allocated for samples
148  // in the deep channels, and returns a pointer to an
149  // array of pixelsPerRow() by pixelsPerColumn() sample
150  // counts in row-major order.
151  //
152  // After beginEdit() returns, application code is
153  // free to change the values in the sample count array.
154  // In particular, the application can fill the array by
155  // reading the sample counts from an OpenEXR file.
156  //
157  // However, since memory for the samples in the deep
158  // channels has been freed, attempting to access any
159  // sample in a deep channel results in undefined
160  // behavior, most likely a program crash.
161  //
162  // endEdit() allocates new memory for all samples in the deep
163  // channels of the layer, according to the current
164  // sample counts, and sets the samples to zero.
165  //
166  // Application code must take make sure that each call to beginEdit()
167  // is followed by a corresponding endEdit() call, even if an
168  // exception occurs while the sample counts are accessed. In order to
169  // do that, application code may want to create a temporary Edit
170  // object instead of calling beginEdit() and endEdit() directly.
171  //
172  // Setting the number of samples for all pixels in the image may
173  // cause the program to run out of memory. If this happens, the image
174  // is resized to zero by zero pixels and an exception is thrown.
175  // Note that the resizing operation deletes this sample count channel
176  // and the image level to which it belongs.
177  //
178 
180  unsigned int * beginEdit();
182  void endEdit();
183 
184  class Edit
185  {
186  public:
187 
188  //
189  // Constructor calls level->beginEdit(),
190  // destructor calls level->endEdit().
191  //
192 
196  ~Edit ();
197 
198  Edit (const Edit& other) = delete;
199  Edit& operator = (const Edit& other) = delete;
200  Edit (Edit&& other) = delete;
201  Edit& operator = (Edit&& other) = delete;
202 
203  //
204  // Access to the writable sample count array.
205  //
206 
208  unsigned int * sampleCounts () const;
209 
210  private:
211 
212  SampleCountChannel & _channel;
213  unsigned int * _sampleCounts;
214  };
215 
216 
217  //
218  // Functions that support the implementation of deep image channels.
219  //
220 
222  const unsigned int * numSamples () const;
224  const unsigned int * sampleListSizes () const;
226  const size_t * sampleListPositions () const;
228  size_t sampleBufferSize () const;
229 
230 
231  private:
232 
233  friend class DeepImageLevel;
234 
235  //
236  // The constructor and destructor are not public because
237  // image channels exist only as parts of a deep image level.
238  //
239 
241  virtual ~SampleCountChannel();
242 
243  virtual void resize ();
244 
245  void resetBasePointer ();
246 
247  unsigned int * _numSamples; // Array of per-pixel sample counts
248 
249  unsigned int * _base; // Base pointer for faster access
250  // to entries in _numSamples
251 
252  unsigned int * _sampleListSizes; // Array of allocated sizes of
253  // per-pixel sample lists
254 
255  size_t * _sampleListPositions; // Array of positions of per-pixel
256  // sample lists within sample list
257  // buffer
258 
259  size_t _totalNumSamples; // Sum of all entries in the
260  // _numSamples array
261 
262  size_t _totalSamplesOccupied; // Total number of samples within
263  // sample list buffer that have
264  // either been allocated for sample
265  // lists or lost to fragmentation
266 
267  size_t _sampleBufferSize; // Size of the sample list buffer.
268 };
269 
270 
271 
272 //-----------------------------------------------------------------------------
273 // Implementation of templates and inline functions
274 //-----------------------------------------------------------------------------
275 
276 inline
278  _channel (channel),
279  _sampleCounts (channel.beginEdit())
280 {
281  // empty
282 }
283 
284 
285 inline
287 {
288  _channel.endEdit();
289 }
290 
291 
292 inline unsigned int *
294 {
295  return _sampleCounts;
296 }
297 
298 
299 inline const unsigned int *
301 {
302  return _numSamples;
303 }
304 
305 
306 inline const unsigned int *
308 {
309  return _sampleListSizes;
310 }
311 
312 
313 inline const size_t *
315 {
316  return _sampleListPositions;
317 }
318 
319 
320 inline size_t
322 {
323  return _sampleBufferSize;
324 }
325 
326 
327 inline const unsigned int &
329 {
330  return _base[y * pixelsPerRow() + x];
331 }
332 
333 
334 inline const unsigned int &
335 SampleCountChannel::at (int x, int y) const
336 {
337  boundsCheck (x, y);
338  return _base[y * pixelsPerRow() + x];
339 }
340 
341 
342 inline const unsigned int *
344 {
345  return _base + n * pixelsPerRow();
346 }
347 
348 
350 
351 #endif
IMFUTIL_EXPORT const unsigned int * sampleListSizes() const
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:80
int pixelsPerRow() const
IMFUTIL_EXPORT size_t sampleBufferSize() const
IMFUTIL_EXPORT const unsigned int * numSamples() const
IMFUTIL_EXPORT const size_t * sampleListPositions() const
virtual PixelType pixelType() const =0
GLint level
Definition: glcorearb.h:108
GLint y
Definition: glcorearb.h:103
IMFUTIL_EXPORT const unsigned int * row(int r) const
IMFUTIL_EXPORT const unsigned int & operator()(int x, int y) const
IMFUTIL_EXPORT DeepImageChannel & channel() const
GLdouble n
Definition: glcorearb.h:2008
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER enum IMF_EXPORT_ENUM PixelType
Definition: ImfPixelType.h:22
#define IMFUTIL_EXPORT_TYPE
Definition: ImfUtilExport.h:54
#define IMFUTIL_EXPORT
Definition: ImfUtilExport.h:51
GLint GLenum GLint x
Definition: glcorearb.h:409
IMFUTIL_EXPORT unsigned int * sampleCounts() const
IMFUTIL_EXPORT const unsigned int & at(int x, int y) const
virtual IMFUTIL_EXPORT void resize()
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:79
GLenum GLenum GLsizei void * row
Definition: glad.h:5135
IMFUTIL_EXPORT Edit(SampleCountChannel &level)
GLboolean r
Definition: glcorearb.h:1222
IMFUTIL_EXPORT void boundsCheck(int x, int y) const
friend class SampleCountChannel