| /*****************************************************************************/ |
| // Copyright 2006-2008 Adobe Systems Incorporated |
| // All Rights Reserved. |
| // |
| // NOTICE: Adobe permits you to use, modify, and distribute this file in |
| // accordance with the terms of the Adobe license agreement accompanying it. |
| /*****************************************************************************/ |
| |
| /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_pixel_buffer.h#1 $ */ |
| /* $DateTime: 2012/05/30 13:28:51 $ */ |
| /* $Change: 832332 $ */ |
| /* $Author: tknoll $ */ |
| |
| /** \file |
| * Support for holding buffers of sample data. |
| */ |
| |
| /*****************************************************************************/ |
| |
| #ifndef __dng_pixel_buffer__ |
| #define __dng_pixel_buffer__ |
| |
| /*****************************************************************************/ |
| |
| #include "dng_assertions.h" |
| #include "dng_rect.h" |
| #include "dng_safe_arithmetic.h" |
| #include "dng_tag_types.h" |
| |
| /*****************************************************************************/ |
| |
| /// Compute best set of step values for a given source and destination area and stride. |
| |
| void OptimizeOrder (const void *&sPtr, |
| void *&dPtr, |
| uint32 sPixelSize, |
| uint32 dPixelSize, |
| uint32 &count0, |
| uint32 &count1, |
| uint32 &count2, |
| int32 &sStep0, |
| int32 &sStep1, |
| int32 &sStep2, |
| int32 &dStep0, |
| int32 &dStep1, |
| int32 &dStep2); |
| |
| void OptimizeOrder (const void *&sPtr, |
| uint32 sPixelSize, |
| uint32 &count0, |
| uint32 &count1, |
| uint32 &count2, |
| int32 &sStep0, |
| int32 &sStep1, |
| int32 &sStep2); |
| |
| void OptimizeOrder (void *&dPtr, |
| uint32 dPixelSize, |
| uint32 &count0, |
| uint32 &count1, |
| uint32 &count2, |
| int32 &dStep0, |
| int32 &dStep1, |
| int32 &dStep2); |
| |
| /*****************************************************************************/ |
| |
| #define qDebugPixelType 0 |
| |
| #if qDebugPixelType |
| |
| #define ASSERT_PIXEL_TYPE(typeVal) CheckPixelType (typeVal) |
| |
| #else |
| |
| #define ASSERT_PIXEL_TYPE(typeVal) DNG_ASSERT (fPixelType == typeVal, "Pixel type access mismatch") |
| |
| #endif |
| |
| /*****************************************************************************/ |
| |
| /// \brief Holds a buffer of pixel data with "pixel geometry" metadata. |
| /// |
| /// The pixel geometry describes the layout in terms of how many planes, rows and columns |
| /// plus the steps (in bytes) between each column, row and plane. |
| |
| class dng_pixel_buffer |
| { |
| |
| public: |
| |
| // Area this buffer holds. |
| |
| dng_rect fArea; |
| |
| // Range of planes this buffer holds. |
| |
| uint32 fPlane; |
| uint32 fPlanes; |
| |
| // Steps between pixels. |
| |
| int32 fRowStep; |
| int32 fColStep; |
| int32 fPlaneStep; |
| |
| // Basic pixel type (TIFF tag type code). |
| |
| uint32 fPixelType; |
| |
| // Size of pixel type in bytes. |
| |
| uint32 fPixelSize; |
| |
| // Pointer to buffer's data. |
| |
| void *fData; |
| |
| // Do we have write-access to this data? |
| |
| bool fDirty; |
| |
| private: |
| |
| void * InternalPixel (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| // Ensure pixel to be accessed lies inside valid area. |
| if (row < fArea.t || row >= fArea.b || |
| col < fArea.l || col >= fArea.r || |
| plane < fPlane || (plane - fPlane) >= fPlanes) |
| { |
| ThrowProgramError ("Out-of-range pixel access"); |
| } |
| |
| // Compute offset of pixel. |
| const int64 rowOffset = SafeInt64Mult(fRowStep, |
| static_cast<int64> (row) - static_cast<int64> (fArea.t)); |
| const int64 colOffset = SafeInt64Mult(fColStep, |
| static_cast<int64> (col) - static_cast<int64> (fArea.l)); |
| const int64 planeOffset = SafeInt64Mult(fPlaneStep, |
| static_cast<int64> (plane - fPlane)); |
| const int64 offset = SafeInt64Mult(static_cast<int64>(fPixelSize), |
| SafeInt64Add(SafeInt64Add(rowOffset, colOffset), planeOffset)); |
| |
| // Add offset to buffer base address. |
| return static_cast<void *> (static_cast<uint8 *> (fData) + offset); |
| |
| } |
| |
| #if qDebugPixelType |
| |
| void CheckPixelType (uint32 pixelType) const; |
| |
| #endif |
| |
| public: |
| |
| dng_pixel_buffer (); |
| |
| /// Note: This constructor is for internal use only and should not be |
| /// considered part of the DNG SDK API. |
| /// |
| /// Initialize the pixel buffer according to the given parameters (see |
| /// below). May throw an error if arithmetic overflow occurs when |
| /// computing the row, column or plane step, or if an invalid value was |
| /// passed for planarConfiguration. |
| /// |
| /// \param size Area covered by the pixel buffer |
| /// \param plane Index of the first plane |
| /// \param planes Number of planes |
| /// \param pixelType Pixel data type (one of the values defined in |
| /// dng_tag_types.h) |
| /// \param planarConfiguration Layout of the pixel planes in memory: One |
| /// of pcInterleaved, pcPlanar, or pcRowInterleaved (defined in |
| /// dng_tag_values.h) |
| /// \param data Pointer to the pixel data |
| dng_pixel_buffer (const dng_rect &area, uint32 plane, uint32 planes, |
| uint32 pixelType, uint32 planarConfiguration, |
| void *data); |
| |
| dng_pixel_buffer (const dng_pixel_buffer &buffer); |
| |
| dng_pixel_buffer & operator= (const dng_pixel_buffer &buffer); |
| |
| virtual ~dng_pixel_buffer (); |
| |
| /// Get the range of pixel values. |
| /// \retval Range of value a pixel can take. (Meaning [0, max] for unsigned case. Signed case is biased so [-32768, max - 32768].) |
| |
| uint32 PixelRange () const; |
| |
| /// Get extent of pixels in buffer |
| /// \retval Rectangle giving valid extent of buffer. |
| |
| const dng_rect & Area () const |
| { |
| return fArea; |
| } |
| |
| /// Number of planes of image data. |
| /// \retval Number of planes held in buffer. |
| |
| uint32 Planes () const |
| { |
| return fPlanes; |
| } |
| |
| /// Step, in pixels not bytes, between rows of data in buffer. |
| /// \retval row step in pixels. May be negative. |
| |
| int32 RowStep () const |
| { |
| return fRowStep; |
| } |
| |
| /// Step, in pixels not bytes, between planes of data in buffer. |
| /// \retval plane step in pixels. May be negative. |
| |
| int32 PlaneStep () const |
| { |
| return fPlaneStep; |
| } |
| |
| /// Get read-only untyped (void *) pointer to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as void *. |
| |
| const void * ConstPixel (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| return InternalPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable untyped (void *) pointer to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as void *. |
| |
| void * DirtyPixel (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| DNG_ASSERT (fDirty, "Dirty access to const pixel buffer"); |
| |
| return InternalPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only uint8 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint8 *. |
| |
| const uint8 * ConstPixel_uint8 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttByte); |
| |
| return (const uint8 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable uint8 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint8 *. |
| |
| uint8 * DirtyPixel_uint8 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttByte); |
| |
| return (uint8 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only int8 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int8 *. |
| |
| const int8 * ConstPixel_int8 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSByte); |
| |
| return (const int8 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable int8 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int8 *. |
| |
| int8 * DirtyPixel_int8 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSByte); |
| |
| return (int8 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only uint16 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint16 *. |
| |
| const uint16 * ConstPixel_uint16 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttShort); |
| |
| return (const uint16 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable uint16 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint16 *. |
| |
| uint16 * DirtyPixel_uint16 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttShort); |
| |
| return (uint16 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only int16 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int16 *. |
| |
| const int16 * ConstPixel_int16 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSShort); |
| |
| return (const int16 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable int16 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int16 *. |
| |
| int16 * DirtyPixel_int16 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSShort); |
| |
| return (int16 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only uint32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint32 *. |
| |
| const uint32 * ConstPixel_uint32 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttLong); |
| |
| return (const uint32 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable uint32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as uint32 *. |
| |
| uint32 * DirtyPixel_uint32 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttLong); |
| |
| return (uint32 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only int32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int32 *. |
| |
| const int32 * ConstPixel_int32 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSLong); |
| |
| return (const int32 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable int32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as int32 *. |
| |
| int32 * DirtyPixel_int32 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttSLong); |
| |
| return (int32 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Get read-only real32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as real32 *. |
| |
| const real32 * ConstPixel_real32 (int32 row, |
| int32 col, |
| uint32 plane = 0) const |
| { |
| |
| ASSERT_PIXEL_TYPE (ttFloat); |
| |
| return (const real32 *) ConstPixel (row, col, plane); |
| |
| } |
| |
| /// Get a writable real32 * to pixel data starting at a specific pixel in the buffer. |
| /// \param row Start row for buffer pointer. |
| /// \param col Start column for buffer pointer. |
| /// \param plane Start plane for buffer pointer. |
| /// \retval Pointer to pixel data as real32 *. |
| |
| real32 * DirtyPixel_real32 (int32 row, |
| int32 col, |
| uint32 plane = 0) |
| { |
| |
| ASSERT_PIXEL_TYPE (ttFloat); |
| |
| return (real32 *) DirtyPixel (row, col, plane); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to a constant. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant value to set pixels to. |
| |
| void SetConstant (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| uint32 value); |
| |
| /// Initialize a rectangular area of pixel buffer to a constant unsigned 8-bit value. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant uint8 value to set pixels to. |
| |
| void SetConstant_uint8 (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| uint8 value) |
| { |
| |
| DNG_ASSERT (fPixelType == ttByte, "Mismatched pixel type"); |
| |
| SetConstant (area, plane, planes, (uint32) value); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to a constant unsigned 16-bit value. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant uint16 value to set pixels to. |
| |
| void SetConstant_uint16 (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| uint16 value) |
| { |
| |
| DNG_ASSERT (fPixelType == ttShort, "Mismatched pixel type"); |
| |
| SetConstant (area, plane, planes, (uint32) value); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to a constant signed 16-bit value. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant int16 value to set pixels to. |
| |
| void SetConstant_int16 (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| int16 value) |
| { |
| |
| DNG_ASSERT (fPixelType == ttSShort, "Mismatched pixel type"); |
| |
| SetConstant (area, plane, planes, (uint32) (uint16) value); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to a constant unsigned 32-bit value. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant uint32 value to set pixels to. |
| |
| void SetConstant_uint32 (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| uint32 value) |
| { |
| |
| DNG_ASSERT (fPixelType == ttLong, "Mismatched pixel type"); |
| |
| SetConstant (area, plane, planes, value); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to a constant real 32-bit value. |
| /// \param area Rectangle of pixel buffer to set. |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| /// \param value Constant real32 value to set pixels to. |
| |
| void SetConstant_real32 (const dng_rect &area, |
| uint32 plane, |
| uint32 planes, |
| real32 value) |
| { |
| |
| DNG_ASSERT (fPixelType == ttFloat, "Mismatched pixel type"); |
| |
| union |
| { |
| uint32 i; |
| real32 f; |
| } x; |
| |
| x.f = value; |
| |
| SetConstant (area, plane, planes, x.i); |
| |
| } |
| |
| /// Initialize a rectangular area of pixel buffer to zeros. |
| /// \param area Rectangle of pixel buffer to zero. |
| /// \param area Area to zero |
| /// \param plane Plane to start filling on. |
| /// \param planes Number of planes to fill. |
| |
| void SetZero (const dng_rect &area, |
| uint32 plane, |
| uint32 planes); |
| |
| /// Copy image data from an area of one pixel buffer to same area of another. |
| /// \param src Buffer to copy from. |
| /// \param area Rectangle of pixel buffer to copy. |
| /// \param srcPlane Plane to start copy in src. |
| /// \param dstPlane Plane to start copy in dst. |
| /// \param planes Number of planes to copy. |
| |
| void CopyArea (const dng_pixel_buffer &src, |
| const dng_rect &area, |
| uint32 srcPlane, |
| uint32 dstPlane, |
| uint32 planes); |
| |
| /// Copy image data from an area of one pixel buffer to same area of another. |
| /// \param src Buffer to copy from. |
| /// \param area Rectangle of pixel buffer to copy. |
| /// \param plane Plane to start copy in src and this. |
| /// \param planes Number of planes to copy. |
| |
| void CopyArea (const dng_pixel_buffer &src, |
| const dng_rect &area, |
| uint32 plane, |
| uint32 planes) |
| { |
| |
| CopyArea (src, area, plane, plane, planes); |
| |
| } |
| |
| /// Calculate the offset phase of destination rectangle relative to source rectangle. |
| /// Phase is based on a 0,0 origin and the notion of repeating srcArea across dstArea. |
| /// It is the number of pixels into srcArea to start repeating from when tiling dstArea. |
| /// \retval dng_point containing horizontal and vertical phase. |
| |
| static dng_point RepeatPhase (const dng_rect &srcArea, |
| const dng_rect &dstArea); |
| |
| /// Repeat the image data in srcArea across dstArea. |
| /// (Generally used for padding operations.) |
| /// \param srcArea Area to repeat from. |
| /// \param dstArea Area to fill with data from srcArea. |
| |
| void RepeatArea (const dng_rect &srcArea, |
| const dng_rect &dstArea); |
| |
| /// Replicates a sub-area of a buffer to fill the entire buffer. |
| |
| void RepeatSubArea (const dng_rect subArea, |
| uint32 repeatV = 1, |
| uint32 repeatH = 1); |
| |
| /// Apply a right shift (C++ oerpator >>) to all pixel values. Only implemented for 16-bit (signed or unsigned) pixel buffers. |
| /// \param shift Number of bits by which to right shift each pixel value. |
| |
| void ShiftRight (uint32 shift); |
| |
| /// Change metadata so pixels are iterated in opposite horizontal order. |
| /// This operation does not require movement of actual pixel data. |
| |
| void FlipH (); |
| |
| /// Change metadata so pixels are iterated in opposite vertical order. |
| /// This operation does not require movement of actual pixel data. |
| |
| void FlipV (); |
| |
| /// Change metadata so pixels are iterated in opposite plane order. |
| /// This operation does not require movement of actual pixel data. |
| |
| void FlipZ (); // Flip planes |
| |
| /// Return true if the contents of an area of the pixel buffer area are the same as those of another. |
| /// \param rhs Buffer to compare against. |
| /// \param area Rectangle of pixel buffer to test. |
| /// \param plane Plane to start comparing. |
| /// \param planes Number of planes to compare. |
| /// \retval bool true if areas are equal, false otherwise. |
| |
| bool EqualArea (const dng_pixel_buffer &rhs, |
| const dng_rect &area, |
| uint32 plane, |
| uint32 planes) const; |
| |
| /// Return the absolute value of the maximum difference between two pixel buffers. Used for comparison testing with tolerance |
| /// \param rhs Buffer to compare against. |
| /// \param area Rectangle of pixel buffer to test. |
| /// \param plane Plane to start comparing. |
| /// \param planes Number of planes to compare. |
| /// \retval larges absolute value difference between the corresponding pixels each buffer across area. |
| |
| real64 MaximumDifference (const dng_pixel_buffer &rhs, |
| const dng_rect &area, |
| uint32 plane, |
| uint32 planes) const; |
| |
| }; |
| |
| /*****************************************************************************/ |
| |
| #endif |
| |
| /*****************************************************************************/ |