HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfDeepImageChannel.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_DEEP_IMAGE_CHANNEL_H
36 #define INCLUDED_IMF_DEEP_IMAGE_CHANNEL_H
37 
38 //----------------------------------------------------------------------------
39 //
40 // class DeepImageChannel,
41 // template class TypedDeepImageChannel<T>
42 //
43 // For an explanation of images, levels and channels,
44 // see the comments in header file Image.h.
45 //
46 //----------------------------------------------------------------------------
47 
48 #include "ImfImageChannel.h"
49 #include "ImfDeepFrameBuffer.h"
50 #include "ImfExport.h"
51 
53 
54 class DeepImageLevel;
55 class SampleCountChannel;
56 
57 //
58 // Image channels:
59 //
60 // A TypedDeepImageChannel<T> holds the pixel data for a single channel
61 // of one level of a deep image. Each pixel in the channel contains an
62 // array of n samples of type T, where T is either half, float or
63 // unsigned int, and n is stored in a separate sample count channel.
64 // Sample storage is allocated only for pixels within the data window
65 // of the level.
66 //
67 
69 {
70  public:
71 
72  //
73  // Construct an OpenEXR frame buffer slice for this channel.
74  // This function is needed reading an image from an OpenEXR
75  // file and for saving an image in an OpenEXR file.
76  //
77 
78  virtual DeepSlice slice () const = 0;
79 
80  //
81  // Access to the image level to which this channel belongs.
82  //
83 
84  DeepImageLevel & deepLevel();
85  const DeepImageLevel & deepLevel() const;
86 
87 
88  //
89  // Access to the sample count channel for this deep channel.
90  //
91 
92  SampleCountChannel & sampleCounts();
93  const SampleCountChannel & sampleCounts() const;
94 
95 
96  protected:
97 
98  friend class DeepImageLevel;
99 
100  DeepImageChannel (DeepImageLevel &level, bool pLinear);
101  virtual ~DeepImageChannel();
102 
103  virtual void setSamplesToZero
104  (size_t i,
105  unsigned int oldNumSamples,
106  unsigned int newNumSamples) = 0;
107 
108  virtual void moveSampleList
109  (size_t i,
110  unsigned int oldNumSamples,
111  unsigned int newNumSamples,
112  size_t newSampleListPosition) = 0;
113 
114  virtual void moveSamplesToNewBuffer
115  (const unsigned int * oldNumSamples,
116  const unsigned int * newNumSamples,
117  const size_t * newSampleListPositions) = 0;
118 
119  virtual void initializeSampleLists () = 0;
120 
121  virtual void resize ();
122 
123  virtual void resetBasePointer () = 0;
124 };
125 
126 
127 template <class T>
129 {
130  public:
131 
132  //
133  // The OpenEXR pixel type of this channel (HALF, FLOAT or UINT).
134  //
135 
136  virtual PixelType pixelType () const;
137 
138 
139  //
140  // Construct an OpenEXR frame buffer slice for this channel.
141  // This function is needed reading an image from an OpenEXR
142  // file and for saving an image in an OpenEXR file.
143  //
144 
145  virtual DeepSlice slice () const;
146 
147 
148  //
149  // Access to the pixel at pixel space location (x, y), without bounds
150  // checking. Accessing a location outside the data window of the image
151  // level results in undefined behavior.
152  //
153  // The pixel contains a pointer to an array of samples to type T. The
154  // number of samples in this array is sampleCounts().at(x,y).
155  //
156 
157  T * operator () (int x, int y);
158  const T * operator () (int x, int y) const;
159 
160 
161  //
162  // Access to the pixel at pixel space location (x, y), with bounds
163  // checking. Accessing a location outside the data window of the
164  // image level throws an Iex::ArgExc exception.
165  //
166 
167  T * at (int x, int y);
168  const T * at (int x, int y) const;
169 
170  //
171  // Faster access to all pixels in a single horizontal row of the
172  // channel. Access is not bounds checked; accessing out of bounds
173  // rows or pixels results in undefined behavior.
174  //
175  // Rows are numbered from 0 to pixelsPerColumn()-1, and each row
176  // contains pixelsPerRow() values. The number of samples in
177  // row(r)[i] is sampleCounts().row(r)[i].
178  //
179 
180  T * const * row (int r);
181  const T * const * row (int r) const;
182 
183  private:
184 
185  friend class DeepImageLevel;
186 
188  virtual ~TypedDeepImageChannel ();
189 
190  virtual void setSamplesToZero
191  (size_t i,
192  unsigned int oldNumSamples,
193  unsigned int newNumSamples);
194 
195  virtual void moveSampleList
196  (size_t i,
197  unsigned int oldNumSamples,
198  unsigned int newNumSamples,
199  size_t newSampleListPosition);
200 
201  virtual void moveSamplesToNewBuffer
202  (const unsigned int * oldNumSamples,
203  const unsigned int * newNumSamples,
204  const size_t * newSampleListPositions);
205 
206  virtual void initializeSampleLists ();
207 
208  virtual void resize ();
209 
210  virtual void resetBasePointer ();
211 
212  T ** _sampleListPointers; // Array of pointers to per-pixel
213  //sample lists
214 
215  T ** _base; // Base pointer for faster access
216  // to entries in _sampleListPointers
217 
218  T * _sampleBuffer; // Contiguous memory block that
219  // contains all sample lists for
220  // this channel
221 };
222 
223 
224 //
225 // Channel typedefs for the pixel data types supported by OpenEXR.
226 //
227 
231 
232 
233 //-----------------------------------------------------------------------------
234 // Implementation of templates and inline functions
235 //-----------------------------------------------------------------------------
236 
237 template <class T>
240  bool pLinear)
241 :
242  DeepImageChannel (level, pLinear),
243  _sampleListPointers (0),
244  _base (0),
245  _sampleBuffer (0)
246 {
247  resize();
248 }
249 
250 
251 template <class T>
253 {
254  delete [] _sampleListPointers;
255  delete [] _sampleBuffer;
256 }
257 
258 
259 template <>
260 inline PixelType
262 {
263  return HALF;
264 }
265 
266 
267 template <>
268 inline PixelType
270 {
271  return FLOAT;
272 }
273 
274 
275 template <>
276 inline PixelType
278 {
279  return UINT;
280 }
281 
282 
283 template <class T>
284 DeepSlice
286 {
287  return DeepSlice (pixelType(), // type
288  (char *) _base, // base
289  sizeof (T*), // xStride
290  pixelsPerRow() * sizeof (T*), // yStride
291  sizeof (T), // sampleStride
292  xSampling(),
293  ySampling());
294 }
295 
296 
297 template <class T>
298 inline T *
300 {
301  return _base[y * pixelsPerRow() + x];
302 }
303 
304 
305 template <class T>
306 inline const T *
308 {
309  return _base[y * pixelsPerRow() + x];
310 }
311 
312 
313 template <class T>
314 inline T *
316 {
317  boundsCheck (x, y);
318  return _base[y * pixelsPerRow() + x];
319 }
320 
321 
322 template <class T>
323 inline const T *
325 {
326  boundsCheck (x, y);
327  return _base[y * pixelsPerRow() + x];
328 }
329 
330 
331 template <class T>
332 inline T * const *
334 {
335  return _base + r * pixelsPerRow();
336 }
337 
338 
339 template <class T>
340 inline const T * const *
342 {
343  return _base + r * pixelsPerRow();
344 }
345 
346 
347 template <class T>
348 void
350  (size_t i,
351  unsigned int oldNumSamples,
352  unsigned int newNumSamples)
353 {
354  //
355  // Expand the size of a sample list for a single pixel and
356  // set the new samples in the list to 0.
357  //
358  // i The position of the affected pixel in
359  // the channel's _sampleListPointers.
360  //
361  // oldNumSamples Original number of samples in the sample list.
362  //
363  // newNumSamples New number of samples in the sample list.
364  //
365 
366  for (int j = oldNumSamples; j < newNumSamples; ++j)
367  _sampleListPointers[i][j] = 0;
368 }
369 
370 
371 template <class T>
372 void
374  (size_t i,
375  unsigned int oldNumSamples,
376  unsigned int newNumSamples,
377  size_t newSampleListPosition)
378 {
379  //
380  // Resize the sample list for a single pixel and move it to a new
381  // position in the sample buffer for this channel.
382  //
383  // i The position of the affected pixel in
384  // the channel's _sampleListPointers.
385  //
386  // oldNumSamples Original number of samples in sample list.
387  //
388  // newNumSamples New number of samples in the sample list.
389  // If the new number of samples is larger than
390  // the old number of samples for a given sample
391  // list, then the end of the new sample list
392  // is filled with zeroes. If the new number of
393  // samples is smaller than the old one, then
394  // samples at the end of the old sample list
395  // are discarded.
396  //
397  // newSampleListPosition The new position of the sample list in the
398  // sample buffer.
399  //
400 
401  T * oldSampleList = _sampleListPointers[i];
402  T * newSampleList = _sampleBuffer + newSampleListPosition;
403 
404  if (oldNumSamples > newNumSamples)
405  {
406  for (int j = 0; j < newNumSamples; ++j)
407  newSampleList[j] = oldSampleList[j];
408  }
409  else
410  {
411  for (int j = 0; j < oldNumSamples; ++j)
412  newSampleList[j] = oldSampleList[j];
413 
414  for (int j = oldNumSamples; j < newNumSamples; ++j)
415  newSampleList[j] = 0;
416  }
417 
418  _sampleListPointers[i] = newSampleList;
419 }
420 
421 
422 template <class T>
423 void
425  (const unsigned int * oldNumSamples,
426  const unsigned int * newNumSamples,
427  const size_t * newSampleListPositions)
428 {
429  //
430  // Allocate a new sample buffer for this channel.
431  // Copy the sample lists for all pixels into the new buffer.
432  // Then delete the old sample buffer.
433  //
434  // oldNumSamples Number of samples in each sample list in the
435  // old sample buffer.
436  //
437  // newNumSamples Number of samples in each sample list in
438  // the new sample buffer. If the new number
439  // of samples is larger than the old number of
440  // samples for a given sample list, then the
441  // end of the new sample list is filled with
442  // zeroes. If the new number of samples is
443  // smaller than the old one, then samples at
444  // the end of the old sample list are discarded.
445  //
446  // newSampleListPositions The positions of the new sample lists in the
447  // new sample buffer.
448  //
449 
450  T * oldSampleBuffer = _sampleBuffer;
451  _sampleBuffer = new T [sampleCounts().sampleBufferSize()];
452 
453  for (size_t i = 0; i < numPixels(); ++i)
454  {
455  T * oldSampleList = _sampleListPointers[i];
456  T * newSampleList = _sampleBuffer + newSampleListPositions[i];
457 
458  if (oldNumSamples[i] > newNumSamples[i])
459  {
460  for (int j = 0; j < newNumSamples[i]; ++j)
461  newSampleList[j] = oldSampleList[j];
462  }
463  else
464  {
465  for (int j = 0; j < oldNumSamples[i]; ++j)
466  newSampleList[j] = oldSampleList[j];
467 
468  for (int j = oldNumSamples[i]; j < newNumSamples[i]; ++j)
469  newSampleList[j] = 0;
470  }
471 
472  _sampleListPointers[i] = newSampleList;
473  }
474 
475  delete [] oldSampleBuffer;
476 }
477 
478 
479 template <class T>
480 void
482 {
483  //
484  // Allocate a new set of sample lists for this channel, and
485  // construct zero-filled sample lists for the pixels.
486  //
487 
488  delete [] _sampleBuffer;
489 
490  _sampleBuffer = 0; // set to 0 to prevent double deletion
491  // in case of an exception
492 
493  const unsigned int * numSamples = sampleCounts().numSamples();
494  const size_t * sampleListPositions = sampleCounts().sampleListPositions();
495 
496  _sampleBuffer = new T [sampleCounts().sampleBufferSize()];
497 
498  resetBasePointer();
499 
500  for (size_t i = 0; i < numPixels(); ++i)
501  {
502  _sampleListPointers[i] = _sampleBuffer + sampleListPositions[i];
503 
504  for (unsigned int j = 0; j < numSamples[i]; ++j)
505  _sampleListPointers[i][j] = T (0);
506  }
507 }
508 
509 template <class T>
510 void
512 {
514 
515  delete [] _sampleListPointers;
516  _sampleListPointers = 0;
517  _sampleListPointers = new T * [numPixels()];
518  initializeSampleLists();
519 }
520 
521 
522 template <class T>
523 void
525 {
526  _base = _sampleListPointers -
527  level().dataWindow().min.y * pixelsPerRow() -
528  level().dataWindow().min.x;
529 }
530 
532 
533 #endif
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:109
size_t sampleBufferSize() const
const unsigned int * numSamples() const
T * operator()(int x, int y)
const size_t * sampleListPositions() const
GLint level
Definition: glcorearb.h:107
GLint y
Definition: glcorearb.h:102
virtual DeepSlice slice() const
virtual void resize()
png_uint_32 i
Definition: png.h:2877
virtual void resize()
TypedDeepImageChannel< half > DeepHalfChannel
virtual PixelType pixelType() const
PixelType
Definition: ImfPixelType.h:51
bool pLinear() const
#define IMF_EXPORT
Definition: ImfExport.h:59
TypedDeepImageChannel< unsigned int > DeepUIntChannel
GLint GLenum GLint x
Definition: glcorearb.h:408
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:108
TypedDeepImageChannel< float > DeepFloatChannel
GLboolean r
Definition: glcorearb.h:1221
SampleCountChannel & sampleCounts()
IMF_EXPORT int numSamples(int s, int a, int b)