HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ImfSampleCountChannel.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2014, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 #ifndef INCLUDED_IMF_SAMPLE_COUNT_CHANNEL_H
36 #define INCLUDED_IMF_SAMPLE_COUNT_CHANNEL_H
37 
38 //----------------------------------------------------------------------------
39 //
40 // class SampleCountChannel
41 //
42 // For an explanation of images, levels and channels,
43 // see the comments in header file Image.h.
44 //
45 //----------------------------------------------------------------------------
46 
47 #include "ImfImageChannel.h"
48 #include "ImfExport.h"
49 
51 
52 class DeepImageLevel;
53 
54 //
55 // Sample count channel for a deep image level:
56 //
57 // Each deep image level has a number of samples channel. For each
58 // pixel location (x,y) within the data window of the level, the sample
59 // count channel stores a single integer, n(x,y). A deep channel, c,
60 // in the level as the sample count channel stores n(x,y) samples at
61 // location (x,y) if
62 //
63 // x % c.xSampling() == 0 and y % c.ySampling() == 0.
64 //
65 // The deep channel stores no samples at location (x,y) if
66 //
67 // x % c.xSampling() != 0 or y % c.ySampling() != 0,
68 //
69 
71 {
72  public:
73 
74  //
75  // The OpenEXR pixel type of this channel (HALF, FLOAT or UINT).
76  //
77 
78  virtual PixelType pixelType () const;
79 
80 
81  //
82  // Construct an OpenEXR frame buffer slice for this channel.
83  // This function is needed reading an image from an OpenEXR
84  // file and for saving an image in an OpenEXR file.
85  //
86 
87  Slice slice () const;
88 
89 
90  //
91  // Access to the image level to which this channel belongs.
92  //
93 
94  DeepImageLevel & deepLevel ();
95  const DeepImageLevel & deepLevel () const;
96 
97 
98  //
99  // Access to n(x,y), without bounds checking. Accessing a location
100  // outside the data window of the image level results in undefined
101  // behavior.
102  //
103 
104  const unsigned int & operator () (int x, int y) const;
105 
106 
107  //
108  // Access to n(x,y), with bounds checking. Accessing a location outside
109  // the data window of the image level throws an Iex::ArgExc exception.
110  //
111 
112  const unsigned int & at (int x, int y) const;
113 
114  //
115  // Faster access to n(x,y) for all pixels in a single horizontal row of
116  // the channel. Rows are numbered from 0 to pixelsPerColumn()-1, and
117  // each row contains pixelsPerRow() values.
118  // Access is not bounds checked; accessing out of bounds rows or pixels
119  // results in undefined behavior.
120  //
121 
122  const unsigned int * row (int r) const;
123 
124 
125  //
126  // Change the sample counts in one or more pixels:
127  //
128  // set(x,y,m) sets n(x,y) to m.
129  //
130  // set(r,m) sets n(x,y) for all pixels in row r according to the
131  // values in array m. The array must contain pixelsPerRow()
132  // entries, and the row number must be in the range from 0
133  // to pixelsPerColumn()-1.
134  //
135  // clear() sets n(x,y) to 0 for all pixels within the data window
136  // of the level.
137  //
138  // If the sample count for a pixel is increased, then new samples are
139  // appended at the end of the sample list of each deep channel. The
140  // new samples are initialized to zero. If the sample count in a pixel
141  // is decreased, then sample list of each deep channel is truncated by
142  // discarding samples at the end of the list.
143  //
144  // Access is bounds-checked; attempting to set the number of samples of
145  // a pixel outside the data window throws an Iex::ArgExc exception.
146  //
147  // Memory allocation for the sample lists is not particularly clever;
148  // repeatedly increasing and decreasing the number of samples in the
149  // pixels of a level is likely to result in serious memory fragmentation.
150  //
151  // Setting the number of samples for one or more pixels may cause the
152  // program to run out of memory. If this happens, the image is resized
153  // to zero by zero pixels and an exception is thrown. Note that the
154  // resizing operation deletes this sample count channel and the image
155  // level to which it belongs.
156  //
157 
158  void set(int x, int y, unsigned int newNumSamples);
159  void set(int r, unsigned int newNumSamples[]);
160  void clear();
161 
162 
163  //
164  // OpenEXR file reading support / make sample counts editable:
165  //
166  // beginEdit() frees all memory that has been allocated for samples
167  // in the deep channels, and returns a pointer to an
168  // array of pixelsPerRow() by pixelsPerColumn() sample
169  // counts in row-major order.
170  //
171  // After beginEdit() returns, application code is
172  // free to change the values in the sample count array.
173  // In particular, the application can fill the array by
174  // reading the sample counts from an OpenEXR file.
175  //
176  // However, since memory for the samples in the deep
177  // channels has been freed, attempting to access any
178  // sample in a deep channel results in undefined
179  // behavior, most likely a program crash.
180  //
181  // endEdit() allocates new memory for all samples in the deep
182  // channels of the layer, according to the current
183  // sample counts, and sets the samples to zero.
184  //
185  // Application code must take make sure that each call to beginEdit()
186  // is followed by a corresponding endEdit() call, even if an
187  // exception occurs while the sample counts are acessed. In order to
188  // do that, application code may want to create a temporary Edit
189  // object instead of calling beginEdit() and endEdit() directly.
190  //
191  // Setting the number of samples for all pixels in the image may
192  // cause the program to run out of memory. If this happens, the image
193  // is resized to zero by zero pixels and an exception is thrown.
194  // Note that the resizing operation deletes this sample count channel
195  // and the image level to which it belongs.
196  //
197 
198  unsigned int * beginEdit();
199  void endEdit();
200 
201  class Edit
202  {
203  public:
204 
205  //
206  // Constructor calls level->beginEdit(),
207  // destructor calls level->endEdit().
208  //
209 
211  ~Edit ();
212 
213  //
214  // Access to the writable sample count array.
215  //
216 
217  unsigned int * sampleCounts () const;
218 
219  private:
220 
221  SampleCountChannel & _channel;
222  unsigned int * _sampleCounts;
223  };
224 
225 
226  //
227  // Functions that support the implementation of deep image channels.
228  //
229 
230  const unsigned int * numSamples () const;
231  const unsigned int * sampleListSizes () const;
232  const size_t * sampleListPositions () const;
233  size_t sampleBufferSize () const;
234 
235 
236  private:
237 
238  friend class DeepImageLevel;
239 
240  //
241  // The constructor and destructor are not public because
242  // image channels exist only as parts of a deep image level.
243  //
244 
246  virtual ~SampleCountChannel();
247 
248  virtual void resize ();
249 
250  void resetBasePointer ();
251 
252  unsigned int * _numSamples; // Array of per-pixel sample counts
253 
254  unsigned int * _base; // Base pointer for faster access
255  // to entries in _numSamples
256 
257  unsigned int * _sampleListSizes; // Array of allocated sizes of
258  // per-pixel sample lists
259 
260  size_t * _sampleListPositions; // Array of positions of per-pixel
261  // sample lists within sample list
262  // buffer
263 
264  size_t _totalNumSamples; // Sum of all entries in the
265  // _numSamples array
266 
267  size_t _totalSamplesOccupied; // Total number of samples within
268  // sample list buffer that have
269  // either been allocated for sample
270  // lists or lost to fragmentation
271 
272  size_t _sampleBufferSize; // Size of the sample list buffer.
273 };
274 
275 
276 
277 //-----------------------------------------------------------------------------
278 // Implementation of templates and inline functions
279 //-----------------------------------------------------------------------------
280 
281 inline
283  _channel (channel),
284  _sampleCounts (channel.beginEdit())
285 {
286  // empty
287 }
288 
289 
290 inline
292 {
293  _channel.endEdit();
294 }
295 
296 
297 inline unsigned int *
299 {
300  return _sampleCounts;
301 }
302 
303 
304 inline const unsigned int *
306 {
307  return _numSamples;
308 }
309 
310 
311 inline const unsigned int *
313 {
314  return _sampleListSizes;
315 }
316 
317 
318 inline const size_t *
320 {
321  return _sampleListPositions;
322 }
323 
324 
325 inline size_t
327 {
328  return _sampleBufferSize;
329 }
330 
331 
332 inline const unsigned int &
334 {
335  return _base[y * pixelsPerRow() + x];
336 }
337 
338 
339 inline const unsigned int &
340 SampleCountChannel::at (int x, int y) const
341 {
342  boundsCheck (x, y);
343  return _base[y * pixelsPerRow() + x];
344 }
345 
346 
347 inline const unsigned int *
349 {
350  return _base + n * pixelsPerRow();
351 }
352 
353 
355 
356 #endif
const unsigned int * sampleListSizes() const
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:109
int pixelsPerRow() const
size_t sampleBufferSize() const
const unsigned int * numSamples() const
const size_t * sampleListPositions() const
virtual PixelType pixelType() const =0
GLint level
Definition: glcorearb.h:107
GLint y
Definition: glcorearb.h:102
const unsigned int * row(int r) const
virtual void resize()
const unsigned int & operator()(int x, int y) const
GLdouble n
Definition: glcorearb.h:2007
PixelType
Definition: ImfPixelType.h:51
#define IMF_EXPORT
Definition: ImfExport.h:59
png_bytepp row
Definition: png.h:1836
unsigned int * sampleCounts() const
const unsigned int & at(int x, int y) const
DeepImageChannel & channel(const std::string &name)
GLint GLenum GLint x
Definition: glcorearb.h:408
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:108
Edit(SampleCountChannel &level)
GLboolean r
Definition: glcorearb.h:1221
IMF_EXPORT int numSamples(int s, int a, int b)
void boundsCheck(int x, int y) const
friend class SampleCountChannel