# Cinder

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# include/cinder/Surface.h

Go to the documentation of this file.

    00001 /*
    00002  Copyright (c) 2010, The Barbarian Group
    00003  All rights reserved.
    00004
    00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
    00006  the following conditions are met:
    00007
    00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
    00009     the following disclaimer.
    00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
    00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
    00012
    00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
    00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
    00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
    00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    00020  POSSIBILITY OF SUCH DAMAGE.
    00021 */
    00022
    00023 #pragma once
    00024
    00025 #include "cinder/Cinder.h"
    00026 #include "cinder/Area.h"
    00027 #include "cinder/Channel.h"
    00028 #include "cinder/ChanTraits.h"
    00029 #include "cinder/Color.h"
    00030
    00031 #include <boost/logic/tribool.hpp>
    00032
    00033 namespace cinder {
    00034
    00035 class SurfaceChannelOrder {
    00036   public:
    00037     SurfaceChannelOrder() : mCode( UNSPECIFIED ), mRed( INVALID ), mGreen( INVALID ), mBlue( INVALID ), mAlpha( INVALID ), mPixelInc( INVALID ) {}
    00038     SurfaceChannelOrder( int aCode );
    00039     SurfaceChannelOrder( const SurfaceChannelOrder &aOrder );
    00040
    00041 //  static ChannelOrder GetPlatformNativeChannelOrder( bool includeAlpha );
    00042
    00043     uint8_t     getRedOffset() const { return mRed; }
    00044     uint8_t     getGreenOffset() const { return mGreen; }
    00045     uint8_t     getBlueOffset() const { return mBlue; }
    00046     uint8_t     getAlphaOffset() const { return mAlpha; }
    00047     bool        hasAlpha() const { return ( mAlpha != INVALID ) ? true : false; }
    00048     uint8_t     getPixelInc() const { return mPixelInc; }
    00049     int         getCode() const { return mCode; }
    00050
    00051     bool operator==( const SurfaceChannelOrder& sco ) const
    00052     {
    00053         return mCode == sco.mCode;
    00054     }
    00055
    00056     enum { CHAN_RED, CHAN_GREEN, CHAN_BLUE, CHAN_ALPHA, INVALID = 255 };
    00057     enum { RGBA, BGRA, ARGB, ABGR, RGBX, BGRX, XRGB, XBGR, RGB, BGR, UNSPECIFIED }; // Codes
    00058
    00059     int         getImageIoChannelOrder() const;
    00060
    00061   private:
    00062     void        set( uint8_t aRed, uint8_t aGreen, uint8_t aBlue, uint8_t aAlpha, uint8_t aPixelInc );
    00063     int         mCode; // the enum
    00064     uint8_t     mRed, mGreen, mBlue, mAlpha, mPixelInc;
    00065
    00066 };
    00067
    00069 class SurfaceConstraints {
    00070  public:
    00071     virtual ~SurfaceConstraints() {}
    00072
    00073     virtual SurfaceChannelOrder getChannelOrder( bool alpha ) const { return ( alpha ) ? SurfaceChannelOrder::RGBA : SurfaceChannelOrder::RGB; }
    00074     virtual int32_t             getRowBytes( int requestedWidth, const SurfaceChannelOrder &sco, int elementSize ) const { return requestedWidth * elementSize * sco.getPixelInc(); }
    00075 };
    00076
    00077 class SurfaceConstraintsDefault : public SurfaceConstraints {
    00078 };
    00079
    00080 typedef shared_ptr<class ImageSource> ImageSourceRef;
    00081
    00082 template<typename T>
    00083 class SurfaceT {
    00084  private:
    00086     struct Obj {
    00087         Obj( int32_t aWidth, int32_t aHeight, SurfaceChannelOrder aChannelOrder, T *aData, bool aOwnsData, int32_t aRowBytes );
    00088         ~Obj();
    00089
    00090         void        initChannels();
    00091         void        setData( T *aData, int32_t aWidth, int32_t aHeight, int32_t aRowBytes );
    00092         void        setChannelOrder( const SurfaceChannelOrder &aChannelOrder );
    00093         void        setDeallocator( void(*aDeallocatorFunc)( void * ), void *aDeallocatorRefcon );
    00094
    00095         int32_t                     mWidth, mHeight, mRowBytes;
    00096         bool                        mIsPremultiplied;
    00097         T                           *mData;
    00098         bool                        mOwnsData;
    00099         SurfaceChannelOrder         mChannelOrder;
    00100         ChannelT<T>                 mChannels[4];
    00101
    00102         void                        (*mDeallocatorFunc)(void *refcon);
    00103         void                        *mDeallocatorRefcon;
    00104     };
    00106
    00107  public:
    00108     SurfaceT() {}
    00109     SurfaceT( int32_t aWidth, int32_t aHeight, bool alpha, SurfaceChannelOrder aChannelOrder = SurfaceChannelOrder::UNSPECIFIED );
    00110     SurfaceT( int32_t aWidth, int32_t aHeight, bool alpha, const SurfaceConstraints &constraints );
    00111     SurfaceT( T *aData, int32_t aWidth, int32_t aHeight, int32_t aRowBytes, SurfaceChannelOrder aChannelOrder );
    00112     SurfaceT( shared_ptr<class ImageSource> imageSource, const SurfaceConstraints &constraints = SurfaceConstraintsDefault(), boost::tribool alpha = boost::logic::indeterminate );
    00113
    00114     operator ImageSourceRef() const;
    00115
    00117     int32_t         getWidth() const { return mObj->mWidth; }
    00119     int32_t         getHeight() const { return mObj->mHeight; }
    00121     Vec2i           getSize() const { return Vec2i( mObj->mWidth, mObj->mHeight ); }
    00123     float           getAspectRatio() const { return mObj->mWidth / (float)mObj->mHeight; }
    00125     Area            getBounds() const { return Area( 0, 0, mObj->mWidth, mObj->mHeight ); }
    00127     bool            hasAlpha() const { return mObj->mChannelOrder.hasAlpha(); }
    00129     bool            isPremultiplied() const { return mObj->mIsPremultiplied; }
    00131     bool            setPremultiplied( bool premult = true ) const { return mObj->mIsPremultiplied = premult; }
    00133     int32_t         getRowBytes() const { return mObj->mRowBytes; }
    00135     uint8_t         getPixelInc() const { return mObj->mChannelOrder.getPixelInc(); }
    00136
    00138     SurfaceT            clone( bool copyPixels = true ) const;
    00140     SurfaceT            clone( const Area &area, bool copyPixels = true ) const;
    00141
    00142     T*                  getData() { return mObj->mData; }
    00143     const T*            getData() const { return mObj->mData; }
    00144     T*                  getData( const Vec2i &offset ) { return reinterpret_cast<T*>( reinterpret_cast<unsigned char*>( mObj->mData + offset.x * getPixelInc() ) + offset.y * mObj->mRowBytes ); }
    00145     const T*            getData( const Vec2i &offset ) const { return reinterpret_cast<T*>( reinterpret_cast<unsigned char*>( mObj->mData + offset.x * getPixelInc() ) + offset.y * mObj->mRowBytes ); }
    00146     T*                  getDataRed( const Vec2i &offset ) { return getData( offset ) + getRedOffset(); }
    00147     const T*            getDataRed( const Vec2i &offset ) const { return getData( offset ) + getRedOffset(); }
    00148     T*                  getDataGreen( const Vec2i &offset ) { return getData( offset ) + getGreenOffset(); }
    00149     const T*            getDataGreen( const Vec2i &offset ) const { return getData( offset ) + getGreenOffset(); }
    00150     T*                  getDataBlue( const Vec2i &offset ) { return getData( offset ) + getBlueOffset(); }
    00151     const T*            getDataBlue( const Vec2i &offset ) const { return getData( offset ) + getBlueOffset(); }
    00152     T*                  getDataAlpha( const Vec2i &offset ) { return getData( offset ) + getAlphaOffset(); }
    00153     const T*            getDataAlpha( const Vec2i &offset ) const { return getData( offset ) + getAlphaOffset(); }
    00154
    00155     void                setData( T *aData, int32_t aWidth, int32_t aHeight, int32_t aRowBytes );
    00157     void                setDeallocator( void(*aDeallocatorFunc)( void * ), void *aDeallocatorRefcon );
    00158
    00159     const SurfaceChannelOrder&  getChannelOrder() const { return mObj->mChannelOrder; }
    00160     uint8_t                     getRedOffset() const { return mObj->mChannelOrder.getRedOffset(); }
    00161     uint8_t                     getGreenOffset() const { return mObj->mChannelOrder.getGreenOffset(); }
    00162     uint8_t                     getBlueOffset() const { return mObj->mChannelOrder.getBlueOffset(); }
    00163     uint8_t                     getAlphaOffset() const { return mObj->mChannelOrder.getAlphaOffset(); }
    00164     void                        setChannelOrder( const SurfaceChannelOrder &aChannelOrder );
    00165
    00166     ChannelT<T>*                getChannel( uint8_t ChannelT ) { return &mObj->mChannels[ChannelT]; }
    00167     ChannelT<T>*                getChannelRed() { return &mObj->mChannels[SurfaceChannelOrder::CHAN_RED]; }
    00168     ChannelT<T>*                getChannelGreen() { return &mObj->mChannels[SurfaceChannelOrder::CHAN_GREEN]; }
    00169     ChannelT<T>*                getChannelBlue() { return &mObj->mChannels[SurfaceChannelOrder::CHAN_BLUE]; }
    00170     ChannelT<T>*                getChannelAlpha() { return &mObj->mChannels[SurfaceChannelOrder::CHAN_ALPHA]; }
    00171
    00172     const ChannelT<T>*          getChannel( uint8_t ChannelT ) const { return &mObj->mChannels[ChannelT]; }
    00173     const ChannelT<T>*          getChannelRed() const { return &mObj->mChannels[SurfaceChannelOrder::CHAN_RED]; }
    00174     const ChannelT<T>*          getChannelGreen() const { return &mObj->mChannels[SurfaceChannelOrder::CHAN_GREEN]; }
    00175     const ChannelT<T>*          getChannelBlue() const { return &mObj->mChannels[SurfaceChannelOrder::CHAN_BLUE]; }
    00176     const ChannelT<T>*          getChannelAlpha() const { return &mObj->mChannels[SurfaceChannelOrder::CHAN_ALPHA]; }
    00177
    00179     ColorAT<T>  getPixel( Vec2i pos ) const { pos.x = constrain<int32_t>( pos.x, 0, mObj->mWidth - 1); pos.y = constrain<int32_t>( pos.y, 0, mObj->mHeight - 1 ); const T *p = getData( pos ); return ColorAT<T>( p[getRedOffset()], p[getGreenOffset()], p[getBlueOffset()], ( hasAlpha() ) ? p[getAlphaOffset()] : CHANTRAIT<T>::max() ); }
    00181     void    setPixel( Vec2i pos, const ColorT<T> &c ) { pos.x = constrain<int32_t>( pos.x, 0, mObj->mWidth - 1); pos.y = constrain<int32_t>( pos.y, 0, mObj->mHeight - 1 ); T *p = getData( pos ); p[getRedOffset()] = c.r; p[getGreenOffset()] = c.g; p[getBlueOffset()] = c.b; }
    00183     void    setPixel( Vec2i pos, const ColorAT<T> &c ) { pos.x = constrain<int32_t>( pos.x, 0, mObj->mWidth - 1); pos.y = constrain<int32_t>( pos.y, 0, mObj->mHeight - 1 ); T *p = getData( pos ); p[getRedOffset()] = c.r; p[getGreenOffset()] = c.g; p[getBlueOffset()] = c.b; if( hasAlpha() ) p[getAlphaOffset()] = c.a; }
    00184
    00185     void                copyFrom( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &relativeOffset = Vec2i::zero() );
    00186 //  template<typename T2>
    00187 //  void                copy( const SurfaceT<T2> &srcSurface, const Area &srcArea, const Offset &dstOffset = Offset::zero() );
    00188
    00189     ColorT<T>                       areaAverage( const Area &area ) const;
    00190
    00192
    00193     typedef shared_ptr<Obj> SurfaceT::*unspecified_bool_type;
    00194     operator unspecified_bool_type() { return ( mObj.get() == 0 ) ? 0 : &SurfaceT::mObj; }
    00195     void reset() { mObj.reset(); }
    00197
    00198  private:
    00199     shared_ptr<Obj>     mObj;
    00200
    00201     void init( shared_ptr<class ImageSource> imageSource, const SurfaceConstraints &constraints = SurfaceConstraintsDefault(), boost::tribool alpha = boost::logic::indeterminate );
    00202
    00203     void    copyRawSameChannelOrder( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &absoluteOffset );
    00204     void    copyRawRgba( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &absoluteOffset );
    00205     void    copyRawRgb( const SurfaceT<T> &srcSurface, const Area &srcArea, const Vec2i &absoluteOffset );
    00206
    00207  public:
    00208     class Iter {
    00209      public:
    00210         Iter( SurfaceT<T> &SurfaceT, const Area &area )
    00211             : mRedOff( SurfaceT.getRedOffset() ), mGreenOff( SurfaceT.getGreenOffset() ),
    00212                 mBlueOff( SurfaceT.getBlueOffset() ), mAlphaOff( SurfaceT.getAlphaOffset() ),
    00213                 mInc( SurfaceT.getPixelInc() ), mRowInc( SurfaceT.getRowBytes() )
    00214         {
    00215             Area clippedArea( area.getClipBy( SurfaceT.getBounds() ) );
    00216             mWidth = clippedArea.getWidth();
    00217             mHeight = clippedArea.getHeight();
    00218             mLinePtr = reinterpret_cast<uint8_t*>( SurfaceT.getData( clippedArea.getUL() ) );
    00219             mPtr = reinterpret_cast<T*>( mLinePtr );
    00220             mStartX = mX = clippedArea.getX1();
    00221             mStartY = mY = clippedArea.getY1();
    00222             mEndX = clippedArea.getX2();
    00223             mEndY = clippedArea.getY2();
    00224             // in order to be at the right place after an initial call to line(), we need to back up one line
    00225             mY = clippedArea.getY1() - 1;
    00226             mLinePtr -= mRowInc;
    00227         }
    00228
    00229         T&          r() const { return mPtr[mRedOff]; }
    00230         T&          g() const { return mPtr[mGreenOff]; }
    00231         T&          b() const { return mPtr[mBlueOff]; }
    00232         T&          a() const { return mPtr[mAlphaOff]; }
    00233
    00234         T&          r( int32_t xOff, int32_t yOff ) const { return mPtr[mRedOff + xOff * mInc + yOff * mRowInc]; }
    00235         T&          g( int32_t xOff, int32_t yOff ) const { return mPtr[mGreenOff + xOff * mInc + yOff * mRowInc]; }
    00236         T&          b( int32_t xOff, int32_t yOff ) const { return mPtr[mBlueOff + xOff * mInc + yOff * mRowInc]; }
    00237         T&          a( int32_t xOff, int32_t yOff ) const { return mPtr[mAlphaOff + xOff * mInc + yOff * mRowInc]; }
    00238
    00239         T&          rClamped( int32_t xOff, int32_t yOff ) const
    00240                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00241                             return mPtr[mRedOff + xOff * mInc + yOff * mRowInc]; }
    00242         T&          gClamped( int32_t xOff, int32_t yOff ) const
    00243                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00244                             return mPtr[mGreenOff + xOff * mInc + yOff * mRowInc]; }
    00245         T&          bClamped( int32_t xOff, int32_t yOff ) const
    00246                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00247                             return mPtr[mBlueOff + xOff * mInc + yOff * mRowInc]; }
    00248         T&          aClamped( int32_t xOff, int32_t yOff ) const
    00249                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00250                             return mPtr[mAlphaOff + xOff * mInc + yOff * mRowInc]; }
    00251
    00252         const int32_t   x() const { return mX; }
    00253         const int32_t   y() const { return mY; }
    00254         Vec2i           getPos() const { return Vec2i( mX, mY ); }
    00255
    00256         bool pixel() {
    00257             ++mX;
    00258             mPtr += mInc;
    00259             return mX < mEndX;
    00260         }
    00261
    00262         bool line() {
    00263             ++mY;
    00264             mLinePtr += mRowInc;
    00265             mPtr = reinterpret_cast<T*>( mLinePtr );
    00266             // in order to be at the right place after an initial call to pixel(), we need to back up one pixel
    00267             mPtr -= mInc;
    00268             mX = mStartX - 1;
    00269             return mY < mEndY;
    00270         }
    00271
    00272         int32_t     getWidth() const { return mWidth; }
    00273         int32_t     getHeight() const { return mHeight; }
    00274
    00275         uint8_t             mRedOff, mGreenOff, mBlueOff, mAlphaOff, mInc;
    00276         uint8_t             *mLinePtr;
    00277         T                   *mPtr;
    00278         int32_t             mRowInc, mWidth, mHeight;
    00279         int32_t             mX, mY, mStartX, mStartY, mEndX, mEndY;
    00280     };
    00281
    00282     class ConstIter {
    00283      public:
    00284         ConstIter( const Iter &iter ) {
    00285             mRedOff = iter.mRedOff;
    00286             mGreenOff = iter.mGreenOff;
    00287             mBlueOff = iter.mBlueOff;
    00288             mAlphaOff = iter.mAlphaOff;
    00289             mInc = iter.mInc;
    00290             mRowInc = iter.mRowInc;
    00291             mWidth = iter.mWidth;
    00292             mHeight = iter.mHeight;
    00293             mLinePtr = iter.mLinePtr;
    00294             mPtr = iter.mPtr;
    00295             mStartX = iter.mStartX;
    00296             mX = iter.mX;
    00297             mStartY = iter.mStartY;
    00298             mY = iter.mY;
    00299             mEndX = iter.mEndX;
    00300             mEndY = iter.mEndY;
    00301         }
    00302
    00303         ConstIter( const SurfaceT<T> &SurfaceT, const Area &area )
    00304             : mRedOff( SurfaceT.getRedOffset() ), mGreenOff( SurfaceT.getGreenOffset() ),
    00305                 mBlueOff( SurfaceT.getBlueOffset() ), mAlphaOff( SurfaceT.getAlphaOffset() ),
    00306                 mInc( SurfaceT.getPixelInc() ), mRowInc( SurfaceT.getRowBytes() )
    00307         {
    00308             Area clippedArea( area.getClipBy( SurfaceT.getBounds() ) );
    00309             mWidth = clippedArea.getWidth();
    00310             mHeight = clippedArea.getHeight();
    00311             mLinePtr = reinterpret_cast<const uint8_t*>( SurfaceT.getData( clippedArea.getUL() ) );
    00312             mPtr = reinterpret_cast<const T*>( mLinePtr );
    00313             mStartX = mX = clippedArea.getX1();
    00314             mStartY = mY = clippedArea.getY1();
    00315             mEndX = clippedArea.getX2();
    00316             mEndY = clippedArea.getY2();
    00317             // in order to be at the right place after an initial call to line(), we need to back up one line
    00318             mY = clippedArea.getY1() - 1;
    00319             mLinePtr -= mRowInc;
    00320         }
    00321
    00322         const T&    r() const { return mPtr[mRedOff]; }
    00323         const T&    g() const { return mPtr[mGreenOff]; }
    00324         const T&    b() const { return mPtr[mBlueOff]; }
    00325         const T&    a() const { return mPtr[mAlphaOff]; }
    00326
    00327         const T&            r( int32_t xOff, int32_t yOff ) const { return mPtr[mRedOff + xOff * mInc + yOff * mRowInc]; }
    00328         const T&            g( int32_t xOff, int32_t yOff ) const { return mPtr[mGreenOff + xOff * mInc + yOff * mRowInc]; }
    00329         const T&            b( int32_t xOff, int32_t yOff ) const { return mPtr[mBlueOff + xOff * mInc + yOff * mRowInc]; }
    00330         const T&            a( int32_t xOff, int32_t yOff ) const { return mPtr[mAlphaOff + xOff * mInc + yOff * mRowInc]; }
    00331
    00332         const T&    rClamped( int32_t xOff, int32_t yOff ) const
    00333                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00334                             return mPtr[mRedOff + xOff * mInc + yOff * mRowInc]; }
    00335         const T&    gClamped( int32_t xOff, int32_t yOff ) const
    00336                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00337                             return mPtr[mGreenOff + xOff * mInc + yOff * mRowInc]; }
    00338         const T&    bClamped( int32_t xOff, int32_t yOff ) const
    00339                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00340                             return mPtr[mBlueOff + xOff * mInc + yOff * mRowInc]; }
    00341         const T&    aClamped( int32_t xOff, int32_t yOff ) const
    00342                         {   xOff = std::min(std::max(mX + xOff, mStartX),mEndX - 1) - mX; yOff = std::min(std::max( mY + yOff, mStartY ), mEndY - 1) - mY;
    00343                             return mPtr[mAlphaOff + xOff * mInc + yOff * mRowInc]; }
    00344
    00345         const int32_t   x() const { return mX; }
    00346         const int32_t   y() const { return mY; }
    00347         Vec2i           getPos() const { return Vec2i( mX, mY ); }
    00348
    00349         bool pixel() {
    00350             ++mX;
    00351             mPtr += mInc;
    00352             return mX < mEndX;
    00353         }
    00354
    00355         bool line() {
    00356             ++mY;
    00357             mLinePtr += mRowInc;
    00358             mPtr = reinterpret_cast<const T*>( mLinePtr );
    00359             // in order to be at the right place after an initial call to pixel(), we need to back up one pixel
    00360             mPtr -= mInc;
    00361             mX = mStartX - 1;
    00362             return mY < mEndY;
    00363         }
    00364
    00365         int32_t     getWidth() const { return mWidth; }
    00366         int32_t     getHeight() const { return mHeight; }
    00367
    00368         uint8_t             mRedOff, mGreenOff, mBlueOff, mAlphaOff, mInc;
    00369         const uint8_t       *mLinePtr;
    00370         const T             *mPtr;
    00371         int32_t             mRowInc, mWidth, mHeight;
    00372         int32_t             mX, mY, mStartX, mStartY, mEndX, mEndY;
    00373     };
    00374
    00375     Iter        getIter() { return Iter( *this, this->getBounds() ); }
    00376     Iter        getIter( const Area &area ) { return Iter( *this, area ); }
    00377     ConstIter   getIter() const { return ConstIter( *this, this->getBounds() ); }
    00378     ConstIter   getIter( const Area &area ) const { return ConstIter( *this, area ); }
    00379 };
    00380
    00381 class SurfaceExc : public std::exception {
    00382     virtual const char* what() const throw() {
    00383         return "Surface exception";
    00384     }
    00385 };
    00386
    00387 class SurfaceConstraintsExc : public SurfaceExc {
    00388     virtual const char* what() const throw() {
    00389         return "Surface exception: does not conform to expected SurfaceConstraints";
    00390     }
    00391 };
    00392
    00393 typedef SurfaceT<uint8_t> Surface;
    00394 typedef SurfaceT<uint8_t> Surface8u;
    00395 typedef SurfaceT<float> Surface32f;
    00396
    00397 } // namespace cinder