Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/ImageIo.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/DataSource.h"
00027 #include "cinder/DataTarget.h"
00028 #include "cinder/Surface.h"
00029 #include "cinder/Exception.h"
00030 
00031 #include <vector>
00032 #include <map>
00033 #include <utility>
00034 
00035 namespace cinder {
00036 
00037 typedef std::shared_ptr<class ImageSource>      ImageSourceRef;
00038 typedef std::shared_ptr<class ImageLoader>      ImageLoaderRef;
00039 typedef std::shared_ptr<class ImageTarget>      ImageTargetRef;
00040 typedef std::shared_ptr<class ImageTargetFile>  ImageTargetFileRef;
00041 
00042 class ImageIo {
00043   public:
00044     typedef enum ColorModel { CM_RGB, CM_GRAY, CM_UNKNOWN } ColorModel;
00045     typedef enum DataType { UINT8, UINT16, FLOAT32, DATA_UNKNOWN } DataType;
00046     typedef enum ChannelType { CHAN_RGB_R, CHAN_RGB_G, CHAN_RGB_B, CHAN_GRAY, CHAN_ALPHA, CHAN_MASK, CHAN_LAB_L, CHAN_LAB_A, CHAN_LAB_B,
00047                     CHAN_YUV_Y, CHAN_YUV_U, CHAN_YUV_V, CHAN_CMYK_C, CHAN_CMYK_M, CHAN_CMYK_Y, CHAN_CMYK_K,
00048                     CHAN_UNKNOWN } ChannelType;
00049     typedef enum ChannelOrder { RGBA, BGRA, ARGB, ABGR, RGBX, BGRX, XRGB, XBGR, RGB, BGR, Y, YA, CUSTOM } ChannelOrder;     // Y = Gray/Luminance, X = ignored
00050 
00051     int32_t         getWidth() const { return mWidth; }
00052     int32_t         getHeight() const { return mHeight; }
00053     ColorModel      getColorModel() const { return mColorModel; }
00054     DataType        getDataType() const { return mDataType; }
00055     ChannelOrder    getChannelOrder() const { return mChannelOrder; }
00056     virtual bool    hasAlpha() const { return channelOrderHasAlpha( mChannelOrder ); }
00057 
00058     static void     translateRgbColorModelToOffsets( ChannelOrder channelOrder, int8_t *red, int8_t *green, int8_t *blue, int8_t *alpha, int8_t *inc );
00059     static void     translateGrayColorModelToOffsets( ChannelOrder channelOrder, int8_t *gray, int8_t *alpha, int8_t *inc );
00060     static bool     channelOrderHasAlpha( ChannelOrder channelOrder );
00061     static int8_t   channelOrderNumChannels( ChannelOrder channelOrder );
00062     static uint8_t  dataTypeBytes( DataType dataType );
00063 
00065     static std::vector<std::string> getLoadExtensions();
00067     static std::vector<std::string> getWriteExtensions();
00068 
00069   protected:
00070     ImageIo();
00071 
00072     void    setSize( int32_t width, int32_t height ) { mWidth = width; mHeight = height; }
00073     void    setColorModel( ColorModel colorModel ) { mColorModel  = colorModel; }
00074     void    setDataType( DataType aDataType ) { mDataType = aDataType; }    
00075     void    setChannelOrder( ChannelOrder aChannelOrder ) { mChannelOrder = aChannelOrder; }
00076 
00077     int32_t                     mWidth, mHeight;
00078     ColorModel                  mColorModel;
00079     DataType                    mDataType;
00080     ChannelOrder                mChannelOrder;
00081 };
00082 
00083 class ImageSource : public ImageIo {
00084   public:
00085     ImageSource() : ImageIo(), mIsPremultiplied( false ), mPixelAspectRatio( 1 ) {}
00086     virtual ~ImageSource() {}  
00087 
00088     class Options {
00089       public:
00090         Options() : mIndex( 0 ) {}
00091 
00093         Options& index( int32_t aIndex ) { mIndex = aIndex; return *this; }
00094         
00095         int32_t             getIndex() const { return mIndex; }
00096         
00097       protected:
00098         int32_t         mIndex;
00099     };
00100 
00102     float       getPixelAspectRatio() const;
00104     bool        isPremultiplied() const;
00105 
00106     virtual void    load( ImageTargetRef target ) = 0;
00107 
00108     typedef void (ImageSource::*RowFunc)(ImageTargetRef, int32_t, const void*);
00109 
00110   protected:
00111     void        setPixelAspectRatio( float pixelAspectRatio ) { mPixelAspectRatio = pixelAspectRatio; }
00112     void        setPremultiplied( bool premult = true ) { mIsPremultiplied = premult; }
00113   
00114     RowFunc     setupRowFunc( ImageTargetRef target );
00115     void        setupRowFuncRgbSource( ImageTargetRef target );
00116     void        setupRowFuncGraySource( ImageTargetRef target );
00117     template<typename SD, typename TD, ColorModel TCS>
00118     RowFunc     setupRowFuncForTypesAndTargetColorModel( ImageTargetRef target );
00119     template<typename SD, typename TD>
00120     RowFunc     setupRowFuncForTypes( ImageTargetRef target );
00121     template<typename SD>
00122     RowFunc     setupRowFuncForSourceType( ImageTargetRef target );
00123 
00124     template<typename SD, typename TD, ImageIo::ColorModel TCM, bool ALPHA>
00125     void        rowFuncSourceRgb( ImageTargetRef target, int32_t row, const void *data );
00126     template<typename SD, typename TD, ColorModel TCM, bool ALPHA>
00127     void        rowFuncSourceGray( ImageTargetRef target, int32_t row, const void *data );
00128 
00129     float                       mPixelAspectRatio;
00130     bool                        mIsPremultiplied;
00131     
00132     int8_t                      mRowFuncSourceRed, mRowFuncSourceGreen, mRowFuncSourceBlue, mRowFuncSourceAlpha;
00133     int8_t                      mRowFuncTargetRed, mRowFuncTargetGreen, mRowFuncTargetBlue, mRowFuncTargetAlpha;
00134     int8_t                      mRowFuncSourceGray, mRowFuncTargetGray;
00135     int8_t                      mRowFuncSourceInc, mRowFuncTargetInc;
00136 };
00137 
00138 class ImageTarget : public ImageIo {
00139   public:
00140     virtual ~ImageTarget() {};
00141 
00142     virtual void*   getRowPointer( int32_t row ) = 0;
00143     virtual void    setRow( int32_t row, const void *data ) { throw; }
00144     virtual void    finalize() { }
00145     
00146     class Options {
00147       public:
00148         Options() : mQuality( 0.9f ), mColorModelDefault( true ) {}
00149         
00150         Options& quality( float quality ) { mQuality = quality; return *this; }
00151         Options& colorModel( ImageIo::ColorModel cm ) { mColorModelDefault = false; mColorModel = cm; return *this; }
00152         
00153         void    setColorModelDefault() { mColorModelDefault = true; }
00154         
00155         float               getQuality() const { return mQuality; }
00156         bool                isColorModelDefault() const { return mColorModelDefault; }
00157         ImageIo::ColorModel getColorModel() const { return mColorModel; }
00158         
00159       protected:
00160         float                   mQuality;
00161         bool                    mColorModelDefault;
00162         ImageIo::ColorModel     mColorModel;
00163     };
00164     
00165   protected:
00166     ImageTarget() {}    
00167 };
00168 
00170 ImageSourceRef  loadImage( const std::string &path, ImageSource::Options options = ImageSource::Options(), std::string extension = "" );
00172 ImageSourceRef  loadImage( DataSourceRef dataSource, ImageSource::Options options = ImageSource::Options(), std::string extension = "" );
00174 void            writeImage( DataTargetRef dataTarget, const ImageSourceRef &imageSource, ImageTarget::Options options = ImageTarget::Options(), std::string extension = "" );
00177 void            writeImage( const std::string &path, const ImageSourceRef &imageSource, ImageTarget::Options options = ImageTarget::Options(), std::string extension = "" );
00179 void            writeImage( ImageTargetRef imageTarget, const ImageSourceRef &imageSource );
00180 
00181 class ImageIoException : public Exception {
00182 };
00183 
00184 class ImageIoExceptionFailedLoad : public ImageIoException {
00185 };
00186 
00187 class ImageIoExceptionFailedWrite : public ImageIoException {
00188 };
00189 
00190 class ImageIoExceptionUnknownExtension : public ImageIoException {
00191 };
00192 
00193 class ImageIoExceptionIllegalColorModel : public ImageIoException {
00194 };
00195 
00196 class ImageIoExceptionIllegalDataType : public ImageIoException {
00197 };
00198 
00199 class ImageIoExceptionIllegalChannelOrder : public ImageIoException {
00200 };
00201 
00202 
00203 struct ImageIoRegistrar {
00204     typedef ImageSourceRef (*SourceCreationFunc)( DataSourceRef, ImageSource::Options options );
00205     typedef ImageTargetRef (*TargetCreationFunc)( DataTargetRef, ImageSourceRef, ImageTarget::Options options, const std::string& );
00206 
00207     static ImageSourceRef   createSource( DataSourceRef dataSource, ImageSource::Options options, std::string extension );
00208     static ImageTargetRef   createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, std::string extension );
00209     
00210     static void     registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00211     static void     registerSourceGeneric( SourceCreationFunc func, int32_t priority = 2 );
00212     
00213     static void     registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );
00214     
00215   private:
00216     
00217     struct Inst {
00218         void    registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00219         void    registerSourceGeneric( SourceCreationFunc func, int32_t priority );
00220         void    registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );       
00221 
00222         ImageSourceRef  createSource( DataSourceRef dataSource, ImageSource::Options options, std::string extension );
00223         ImageTargetRef  createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, std::string extension );
00224     
00225         std::map<std::string, std::multimap<int32_t,SourceCreationFunc> >   mSources;
00226         std::map<int32_t, SourceCreationFunc>                               mGenericSources;
00227         std::map<std::string, std::multimap<int32_t,std::pair<TargetCreationFunc,std::string> > >   mTargets;
00228     };
00229 
00230     static ImageIoRegistrar::Inst*  instance();     
00231         
00232     friend class ImageIo;
00233 };
00234 
00235 template<typename T>
00236 struct ImageIoRegistrant {
00237     ImageIoRegistrant() {
00238         (void) register_object;
00239     }
00240   private:
00241     struct exec_register {
00242         exec_register() {
00243             T::registerSelf();
00244         }
00245     };
00246     
00247     static exec_register register_object;
00248 };
00249 
00250 template<typename D> typename ImageIoRegistrant<D>::exec_register ImageIoRegistrant<D>::register_object;
00251 
00252 #define REGISTER_IMAGE_IO_FILE_HANDLER( TYPE ) \
00253 struct ImageIoRegisterT##TYPE : public ImageIoRegistrant<TYPE> { \
00254     ImageIoRegisterT##TYPE() : ImageIoRegistrant<TYPE>() {} \
00255 };
00256 
00257 } // namespace cinder