00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 shared_ptr<class ImageSource> ImageSourceRef;
00038 typedef shared_ptr<class ImageLoader> ImageLoaderRef;
00039 typedef shared_ptr<class ImageTarget> ImageTargetRef;
00040 typedef 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;
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
00089 float getPixelAspectRatio() const;
00091 bool isPremultiplied() const;
00092
00093 virtual void load( ImageTargetRef target ) = 0;
00094
00095 typedef void (ImageSource::*RowFunc)(ImageTargetRef, int32_t, const void*);
00096
00097 protected:
00098 void setPixelAspectRatio( float pixelAspectRatio ) { mPixelAspectRatio = pixelAspectRatio; }
00099 void setPremultiplied( bool premult = true ) { mIsPremultiplied = premult; }
00100
00101 RowFunc setupRowFunc( ImageTargetRef target );
00102 void setupRowFuncRgbSource( ImageTargetRef target );
00103 void setupRowFuncGraySource( ImageTargetRef target );
00104 template<typename SD, typename TD, ColorModel TCS>
00105 RowFunc setupRowFuncForTypesAndTargetColorModel( ImageTargetRef target );
00106 template<typename SD, typename TD>
00107 RowFunc setupRowFuncForTypes( ImageTargetRef target );
00108 template<typename SD>
00109 RowFunc setupRowFuncForSourceType( ImageTargetRef target );
00110
00111 template<typename SD, typename TD, ImageIo::ColorModel TCM, bool ALPHA>
00112 void rowFuncSourceRgb( ImageTargetRef target, int32_t row, const void *data );
00113 template<typename SD, typename TD, ColorModel TCM, bool ALPHA>
00114 void rowFuncSourceGray( ImageTargetRef target, int32_t row, const void *data );
00115
00116 float mPixelAspectRatio;
00117 bool mIsPremultiplied;
00118
00119 int8_t mRowFuncSourceRed, mRowFuncSourceGreen, mRowFuncSourceBlue, mRowFuncSourceAlpha;
00120 int8_t mRowFuncTargetRed, mRowFuncTargetGreen, mRowFuncTargetBlue, mRowFuncTargetAlpha;
00121 int8_t mRowFuncSourceGray, mRowFuncTargetGray;
00122 int8_t mRowFuncSourceInc, mRowFuncTargetInc;
00123 };
00124
00125 class ImageTarget : public ImageIo {
00126 public:
00127 virtual ~ImageTarget() {};
00128
00129 virtual void* getRowPointer( int32_t row ) = 0;
00130 virtual void setRow( int32_t row, const void *data ) { throw; }
00131 virtual void finalize() { }
00132
00133 protected:
00134 ImageTarget() {}
00135 };
00136
00138 ImageSourceRef loadImage( const std::string &path, std::string extension = "" );
00140 ImageSourceRef loadImage( DataSourceRef dataSource, std::string extension = "" );
00142 void writeImage( DataTargetRef dataTarget, const ImageSourceRef &imageSource, std::string extension = "" );
00145 void writeImage( const std::string &path, const ImageSourceRef &imageSource, std::string extension = "" );
00147 void writeImage( ImageTargetRef imageTarget, const ImageSourceRef &imageSource );
00148
00149 class ImageIoException : public Exception {
00150 };
00151
00152 class ImageIoExceptionFailedLoad : public ImageIoException {
00153 };
00154
00155 class ImageIoExceptionFailedWrite : public ImageIoException {
00156 };
00157
00158 class ImageIoExceptionUnknownExtension : public ImageIoException {
00159 };
00160
00161 class ImageIoExceptionIllegalColorModel : public ImageIoException {
00162 };
00163
00164 class ImageIoExceptionIllegalDataType : public ImageIoException {
00165 };
00166
00167 class ImageIoExceptionIllegalChannelOrder : public ImageIoException {
00168 };
00169
00170
00171 struct ImageIoRegistrar {
00172 typedef ImageSourceRef (*SourceCreationFunc)( DataSourceRef );
00173 typedef ImageTargetRef (*TargetCreationFunc)( DataTargetRef, ImageSourceRef, const std::string& );
00174
00175 static ImageSourceRef createSource( DataSourceRef dataSource, std::string extension );
00176 static ImageTargetRef createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, std::string extension );
00177
00178 static void registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00179 static void registerSourceGeneric( SourceCreationFunc func, int32_t priority = 2 );
00180
00181 static void registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );
00182
00183 private:
00184
00185 struct Inst {
00186 void registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00187 void registerSourceGeneric( SourceCreationFunc func, int32_t priority );
00188 void registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );
00189
00190 ImageSourceRef createSource( DataSourceRef dataSource, std::string extension );
00191 ImageTargetRef createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, std::string extension );
00192
00193 std::map<std::string, std::multimap<int32_t,SourceCreationFunc> > mSources;
00194 std::map<int32_t, SourceCreationFunc> mGenericSources;
00195 std::map<std::string, std::multimap<int32_t,std::pair<TargetCreationFunc,std::string> > > mTargets;
00196 };
00197
00198 static ImageIoRegistrar::Inst* instance();
00199
00200 friend class ImageIo;
00201 };
00202
00203 template<typename T>
00204 struct ImageIoRegistrant {
00205 ImageIoRegistrant() {
00206 (void) register_object;
00207 }
00208 private:
00209 struct exec_register {
00210 exec_register() {
00211 T::registerSelf();
00212 }
00213 };
00214
00215 static exec_register register_object;
00216 };
00217
00218 template<typename D> typename ImageIoRegistrant<D>::exec_register ImageIoRegistrant<D>::register_object;
00219
00220 #define REGISTER_IMAGE_IO_FILE_HANDLER( TYPE ) \
00221 struct ImageIoRegisterT##TYPE : public ImageIoRegistrant<TYPE> { \
00222 ImageIoRegisterT##TYPE() : ImageIoRegistrant<TYPE>() {} \
00223 };
00224
00225 }