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 "ImfImageChannel.h"
19 #include "ImfUtilExport.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  // The OpenEXR pixel type of this channel (HALF, FLOAT or UINT).
46  //
47 
49  virtual PixelType pixelType () const;
50 
51  //
52  // Construct an OpenEXR frame buffer slice for this channel.
53  // This function is needed reading an image from an OpenEXR
54  // file and for saving an image in an OpenEXR file.
55  //
56 
58  Slice slice () const;
59 
60  //
61  // Access to the image level to which this channel belongs.
62  //
63 
65  DeepImageLevel& deepLevel ();
67  const DeepImageLevel& deepLevel () const;
68 
69  //
70  // Access to n(x,y), without bounds checking. Accessing a location
71  // outside the data window of the image level results in undefined
72  // behavior.
73  //
74 
76  const unsigned int& operator() (int x, int y) const;
77 
78  //
79  // Access to n(x,y), with bounds checking. Accessing a location outside
80  // the data window of the image level throws an Iex::ArgExc exception.
81  //
82 
84  const unsigned int& at (int x, int y) const;
85 
86  //
87  // Faster access to n(x,y) for all pixels in a single horizontal row of
88  // the channel. Rows are numbered from 0 to pixelsPerColumn()-1, and
89  // each row contains pixelsPerRow() values.
90  // Access is not bounds checked; accessing out of bounds rows or pixels
91  // results in undefined behavior.
92  //
93 
95  const unsigned int* row (int r) const;
96 
97  //
98  // Change the sample counts in one or more pixels:
99  //
100  // set(x,y,m) sets n(x,y) to m.
101  //
102  // set(r,m) sets n(x,y) for all pixels in row r according to the
103  // values in array m. The array must contain pixelsPerRow()
104  // entries, and the row number must be in the range from 0
105  // to pixelsPerColumn()-1.
106  //
107  // clear() sets n(x,y) to 0 for all pixels within the data window
108  // of the level.
109  //
110  // If the sample count for a pixel is increased, then new samples are
111  // appended at the end of the sample list of each deep channel. The
112  // new samples are initialized to zero. If the sample count in a pixel
113  // is decreased, then sample list of each deep channel is truncated by
114  // discarding samples at the end of the list.
115  //
116  // Access is bounds-checked; attempting to set the number of samples of
117  // a pixel outside the data window throws an Iex::ArgExc exception.
118  //
119  // Memory allocation for the sample lists is not particularly clever;
120  // repeatedly increasing and decreasing the number of samples in the
121  // pixels of a level is likely to result in serious memory fragmentation.
122  //
123  // Setting the number of samples for one or more pixels may cause the
124  // program to run out of memory. If this happens, the image is resized
125  // to zero by zero pixels and an exception is thrown. Note that the
126  // resizing operation deletes this sample count channel and the image
127  // level to which it belongs.
128  //
129 
131  void set (int x, int y, unsigned int newNumSamples);
133  void set (int r, unsigned int newNumSamples[]);
135  void clear ();
136 
137  //
138  // OpenEXR file reading support / make sample counts editable:
139  //
140  // beginEdit() frees all memory that has been allocated for samples
141  // in the deep channels, and returns a pointer to an
142  // array of pixelsPerRow() by pixelsPerColumn() sample
143  // counts in row-major order.
144  //
145  // After beginEdit() returns, application code is
146  // free to change the values in the sample count array.
147  // In particular, the application can fill the array by
148  // reading the sample counts from an OpenEXR file.
149  //
150  // However, since memory for the samples in the deep
151  // channels has been freed, attempting to access any
152  // sample in a deep channel results in undefined
153  // behavior, most likely a program crash.
154  //
155  // endEdit() allocates new memory for all samples in the deep
156  // channels of the layer, according to the current
157  // sample counts, and sets the samples to zero.
158  //
159  // Application code must take make sure that each call to beginEdit()
160  // is followed by a corresponding endEdit() call, even if an
161  // exception occurs while the sample counts are accessed. In order to
162  // do that, application code may want to create a temporary Edit
163  // object instead of calling beginEdit() and endEdit() directly.
164  //
165  // Setting the number of samples for all pixels in the image may
166  // cause the program to run out of memory. If this happens, the image
167  // is resized to zero by zero pixels and an exception is thrown.
168  // Note that the resizing operation deletes this sample count channel
169  // and the image level to which it belongs.
170  //
171 
173  unsigned int* beginEdit ();
175  void endEdit ();
176 
177  class Edit
178  {
179  public:
180  //
181  // Constructor calls level->beginEdit(),
182  // destructor calls level->endEdit().
183  //
184 
188  ~Edit ();
189 
190  Edit (const Edit& other) = delete;
191  Edit& operator= (const Edit& other) = delete;
192  Edit (Edit&& other) = delete;
193  Edit& operator= (Edit&& other) = delete;
194 
195  //
196  // Access to the writable sample count array.
197  //
198 
200  unsigned int* sampleCounts () const;
201 
202  private:
203  SampleCountChannel& _channel;
204  unsigned int* _sampleCounts;
205  };
206 
207  //
208  // Functions that support the implementation of deep image channels.
209  //
210 
212  const unsigned int* numSamples () const;
214  const unsigned int* sampleListSizes () const;
216  const size_t* sampleListPositions () const;
218  size_t sampleBufferSize () const;
219 
220 private:
221  friend class DeepImageLevel;
222 
223  //
224  // The constructor and destructor are not public because
225  // image channels exist only as parts of a deep image level.
226  //
227 
229  virtual ~SampleCountChannel ();
230 
231  virtual void resize ();
232 
233  void resetBasePointer ();
234 
235  unsigned int* _numSamples; // Array of per-pixel sample counts
236 
237  unsigned int* _base; // Base pointer for faster access
238  // to entries in _numSamples
239 
240  unsigned int* _sampleListSizes; // Array of allocated sizes of
241  // per-pixel sample lists
242 
243  size_t* _sampleListPositions; // Array of positions of per-pixel
244  // sample lists within sample list
245  // buffer
246 
247  size_t _totalNumSamples; // Sum of all entries in the
248  // _numSamples array
249 
250  size_t _totalSamplesOccupied; // Total number of samples within
251  // sample list buffer that have
252  // either been allocated for sample
253  // lists or lost to fragmentation
254 
255  size_t _sampleBufferSize; // Size of the sample list buffer.
256 };
257 
258 //-----------------------------------------------------------------------------
259 // Implementation of templates and inline functions
260 //-----------------------------------------------------------------------------
261 
263  : _channel (channel), _sampleCounts (channel.beginEdit ())
264 {
265  // empty
266 }
267 
269 {
270  _channel.endEdit ();
271 }
272 
273 inline unsigned int*
275 {
276  return _sampleCounts;
277 }
278 
279 inline const unsigned int*
281 {
282  return _numSamples;
283 }
284 
285 inline const unsigned int*
287 {
288  return _sampleListSizes;
289 }
290 
291 inline const size_t*
293 {
294  return _sampleListPositions;
295 }
296 
297 inline size_t
299 {
300  return _sampleBufferSize;
301 }
302 
303 inline const unsigned int&
305 {
306  return _base[y * pixelsPerRow () + x];
307 }
308 
309 inline const unsigned int&
310 SampleCountChannel::at (int x, int y) const
311 {
312  boundsCheck (x, y);
313  return _base[y * pixelsPerRow () + x];
314 }
315 
316 inline const unsigned int*
318 {
319  return _base + n * pixelsPerRow ();
320 }
321 
323 
324 #endif
IMFUTIL_EXPORT const unsigned int * sampleListSizes() const
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:83
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:20
#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()
LeafData & operator=(const LeafData &)=delete
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:80
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
IMF_EXPORT int numSamples(int s, int a, int b)
friend class SampleCountChannel