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 //
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 "ImfUtilExport.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 
79  virtual PixelType pixelType () const;
80 
81 
82  //
83  // Construct an OpenEXR frame buffer slice for this channel.
84  // This function is needed reading an image from an OpenEXR
85  // file and for saving an image in an OpenEXR file.
86  //
87 
89  Slice slice () const;
90 
91 
92  //
93  // Access to the image level to which this channel belongs.
94  //
95 
99  const DeepImageLevel & deepLevel () const;
100 
101 
102  //
103  // Access to n(x,y), without bounds checking. Accessing a location
104  // outside the data window of the image level results in undefined
105  // behavior.
106  //
107 
109  const unsigned int & operator () (int x, int y) const;
110 
111 
112  //
113  // Access to n(x,y), with bounds checking. Accessing a location outside
114  // the data window of the image level throws an Iex::ArgExc exception.
115  //
116 
118  const unsigned int & at (int x, int y) const;
119 
120  //
121  // Faster access to n(x,y) for all pixels in a single horizontal row of
122  // the channel. Rows are numbered from 0 to pixelsPerColumn()-1, and
123  // each row contains pixelsPerRow() values.
124  // Access is not bounds checked; accessing out of bounds rows or pixels
125  // results in undefined behavior.
126  //
127 
129  const unsigned int * row (int r) const;
130 
131 
132  //
133  // Change the sample counts in one or more pixels:
134  //
135  // set(x,y,m) sets n(x,y) to m.
136  //
137  // set(r,m) sets n(x,y) for all pixels in row r according to the
138  // values in array m. The array must contain pixelsPerRow()
139  // entries, and the row number must be in the range from 0
140  // to pixelsPerColumn()-1.
141  //
142  // clear() sets n(x,y) to 0 for all pixels within the data window
143  // of the level.
144  //
145  // If the sample count for a pixel is increased, then new samples are
146  // appended at the end of the sample list of each deep channel. The
147  // new samples are initialized to zero. If the sample count in a pixel
148  // is decreased, then sample list of each deep channel is truncated by
149  // discarding samples at the end of the list.
150  //
151  // Access is bounds-checked; attempting to set the number of samples of
152  // a pixel outside the data window throws an Iex::ArgExc exception.
153  //
154  // Memory allocation for the sample lists is not particularly clever;
155  // repeatedly increasing and decreasing the number of samples in the
156  // pixels of a level is likely to result in serious memory fragmentation.
157  //
158  // Setting the number of samples for one or more pixels may cause the
159  // program to run out of memory. If this happens, the image is resized
160  // to zero by zero pixels and an exception is thrown. Note that the
161  // resizing operation deletes this sample count channel and the image
162  // level to which it belongs.
163  //
164 
166  void set(int x, int y, unsigned int newNumSamples);
168  void set(int r, unsigned int newNumSamples[]);
170  void clear();
171 
172 
173  //
174  // OpenEXR file reading support / make sample counts editable:
175  //
176  // beginEdit() frees all memory that has been allocated for samples
177  // in the deep channels, and returns a pointer to an
178  // array of pixelsPerRow() by pixelsPerColumn() sample
179  // counts in row-major order.
180  //
181  // After beginEdit() returns, application code is
182  // free to change the values in the sample count array.
183  // In particular, the application can fill the array by
184  // reading the sample counts from an OpenEXR file.
185  //
186  // However, since memory for the samples in the deep
187  // channels has been freed, attempting to access any
188  // sample in a deep channel results in undefined
189  // behavior, most likely a program crash.
190  //
191  // endEdit() allocates new memory for all samples in the deep
192  // channels of the layer, according to the current
193  // sample counts, and sets the samples to zero.
194  //
195  // Application code must take make sure that each call to beginEdit()
196  // is followed by a corresponding endEdit() call, even if an
197  // exception occurs while the sample counts are acessed. In order to
198  // do that, application code may want to create a temporary Edit
199  // object instead of calling beginEdit() and endEdit() directly.
200  //
201  // Setting the number of samples for all pixels in the image may
202  // cause the program to run out of memory. If this happens, the image
203  // is resized to zero by zero pixels and an exception is thrown.
204  // Note that the resizing operation deletes this sample count channel
205  // and the image level to which it belongs.
206  //
207 
209  unsigned int * beginEdit();
211  void endEdit();
212 
213  class Edit
214  {
215  public:
216 
217  //
218  // Constructor calls level->beginEdit(),
219  // destructor calls level->endEdit().
220  //
221 
225  ~Edit ();
226 
227  //
228  // Access to the writable sample count array.
229  //
230 
232  unsigned int * sampleCounts () const;
233 
234  private:
235 
236  SampleCountChannel & _channel;
237  unsigned int * _sampleCounts;
238  };
239 
240 
241  //
242  // Functions that support the implementation of deep image channels.
243  //
244 
246  const unsigned int * numSamples () const;
248  const unsigned int * sampleListSizes () const;
250  const size_t * sampleListPositions () const;
252  size_t sampleBufferSize () const;
253 
254 
255  private:
256 
257  friend class DeepImageLevel;
258 
259  //
260  // The constructor and destructor are not public because
261  // image channels exist only as parts of a deep image level.
262  //
263 
265  virtual ~SampleCountChannel();
266 
267  virtual void resize ();
268 
269  void resetBasePointer ();
270 
271  unsigned int * _numSamples; // Array of per-pixel sample counts
272 
273  unsigned int * _base; // Base pointer for faster access
274  // to entries in _numSamples
275 
276  unsigned int * _sampleListSizes; // Array of allocated sizes of
277  // per-pixel sample lists
278 
279  size_t * _sampleListPositions; // Array of positions of per-pixel
280  // sample lists within sample list
281  // buffer
282 
283  size_t _totalNumSamples; // Sum of all entries in the
284  // _numSamples array
285 
286  size_t _totalSamplesOccupied; // Total number of samples within
287  // sample list buffer that have
288  // either been allocated for sample
289  // lists or lost to fragmentation
290 
291  size_t _sampleBufferSize; // Size of the sample list buffer.
292 };
293 
294 
295 
296 //-----------------------------------------------------------------------------
297 // Implementation of templates and inline functions
298 //-----------------------------------------------------------------------------
299 
300 inline
302  _channel (channel),
303  _sampleCounts (channel.beginEdit())
304 {
305  // empty
306 }
307 
308 
309 inline
311 {
312  _channel.endEdit();
313 }
314 
315 
316 inline unsigned int *
318 {
319  return _sampleCounts;
320 }
321 
322 
323 inline const unsigned int *
325 {
326  return _numSamples;
327 }
328 
329 
330 inline const unsigned int *
332 {
333  return _sampleListSizes;
334 }
335 
336 
337 inline const size_t *
339 {
340  return _sampleListPositions;
341 }
342 
343 
344 inline size_t
346 {
347  return _sampleBufferSize;
348 }
349 
350 
351 inline const unsigned int &
353 {
354  return _base[y * pixelsPerRow() + x];
355 }
356 
357 
358 inline const unsigned int &
359 SampleCountChannel::at (int x, int y) const
360 {
361  boundsCheck (x, y);
362  return _base[y * pixelsPerRow() + x];
363 }
364 
365 
366 inline const unsigned int *
368 {
369  return _base + n * pixelsPerRow();
370 }
371 
372 
374 
375 #endif
IMFUTIL_EXPORT const unsigned int * sampleListSizes() const
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:109
IMFUTIL_EXPORT DeepImageChannel & channel(const std::string &name)
int pixelsPerRow() const
IMFUTIL_EXPORT size_t sampleBufferSize() const
IMFUTIL_EXPORT const unsigned int * numSamples() const
IMFUTIL_EXPORT const size_t * sampleListPositions() const
IMFUTIL_EXPORT void endEdit()
GLint level
Definition: glcorearb.h:107
IMFUTIL_EXPORT void set(int x, int y, unsigned int newNumSamples)
IMFUTIL_EXPORT const unsigned int * row(int r) const
IMFUTIL_EXPORT const unsigned int & operator()(int x, int y) const
GLint GLenum GLint x
Definition: glcorearb.h:408
#define IMFUTIL_EXPORT
Definition: ImfUtilExport.h:44
PixelType
Definition: ImfPixelType.h:51
IMFUTIL_EXPORT unsigned int * beginEdit()
virtual IMFUTIL_EXPORT PixelType pixelType() const
IMFUTIL_EXPORT unsigned int * sampleCounts() const
GLdouble n
Definition: glcorearb.h:2007
IMFUTIL_EXPORT void clear()
IMFUTIL_EXPORT const unsigned int & at(int x, int y) const
IMFUTIL_EXPORT Slice slice() const
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:108
IMFUTIL_EXPORT Edit(SampleCountChannel &level)
IMFUTIL_EXPORT void boundsCheck(int x, int y) const
GLboolean r
Definition: glcorearb.h:1221
IMFUTIL_EXPORT DeepImageLevel & deepLevel()
GLint y
Definition: glcorearb.h:102
friend class SampleCountChannel