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 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;
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 ), mCustomPixelInc( 0 ) {}
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; }
00114 void setCustomPixelInc( int8_t customPixelInc ) { mCustomPixelInc = customPixelInc; }
00115
00116 RowFunc setupRowFunc( ImageTargetRef target );
00117 void setupRowFuncRgbSource( ImageTargetRef target );
00118 void setupRowFuncGraySource( ImageTargetRef target );
00119 template<typename SD, typename TD, ColorModel TCS>
00120 RowFunc setupRowFuncForTypesAndTargetColorModel( ImageTargetRef target );
00121 template<typename SD, typename TD>
00122 RowFunc setupRowFuncForTypes( ImageTargetRef target );
00123 template<typename SD>
00124 RowFunc setupRowFuncForSourceType( ImageTargetRef target );
00125
00126 template<typename SD, typename TD, ImageIo::ColorModel TCM, bool ALPHA>
00127 void rowFuncSourceRgb( ImageTargetRef target, int32_t row, const void *data );
00128 template<typename SD, typename TD, ColorModel TCM, bool ALPHA>
00129 void rowFuncSourceGray( ImageTargetRef target, int32_t row, const void *data );
00130
00131 float mPixelAspectRatio;
00132 bool mIsPremultiplied;
00133 int8_t mCustomPixelInc;
00134
00135 int8_t mRowFuncSourceRed, mRowFuncSourceGreen, mRowFuncSourceBlue, mRowFuncSourceAlpha;
00136 int8_t mRowFuncTargetRed, mRowFuncTargetGreen, mRowFuncTargetBlue, mRowFuncTargetAlpha;
00137 int8_t mRowFuncSourceGray, mRowFuncTargetGray;
00138 int8_t mRowFuncSourceInc, mRowFuncTargetInc;
00139 };
00140
00141 class ImageTarget : public ImageIo {
00142 public:
00143 virtual ~ImageTarget() {};
00144
00145 virtual void* getRowPointer( int32_t row ) = 0;
00146 virtual void setRow( int32_t row, const void *data ) { throw; }
00147 virtual void finalize() { }
00148
00149 class Options {
00150 public:
00151 Options() : mQuality( 0.9f ), mColorModelDefault( true ) {}
00152
00153 Options& quality( float quality ) { mQuality = quality; return *this; }
00154 Options& colorModel( ImageIo::ColorModel cm ) { mColorModelDefault = false; mColorModel = cm; return *this; }
00155
00156 void setColorModelDefault() { mColorModelDefault = true; }
00157
00158 float getQuality() const { return mQuality; }
00159 bool isColorModelDefault() const { return mColorModelDefault; }
00160 ImageIo::ColorModel getColorModel() const { return mColorModel; }
00161
00162 protected:
00163 float mQuality;
00164 bool mColorModelDefault;
00165 ImageIo::ColorModel mColorModel;
00166 };
00167
00168 protected:
00169 ImageTarget() {}
00170 };
00171
00173 ImageSourceRef loadImage( const fs::path &path, ImageSource::Options options = ImageSource::Options(), std::string extension = "" );
00175 ImageSourceRef loadImage( DataSourceRef dataSource, ImageSource::Options options = ImageSource::Options(), std::string extension = "" );
00177 void writeImage( DataTargetRef dataTarget, const ImageSourceRef &imageSource, ImageTarget::Options options = ImageTarget::Options(), std::string extension = "" );
00180 void writeImage( const fs::path &path, const ImageSourceRef &imageSource, ImageTarget::Options options = ImageTarget::Options(), std::string extension = "" );
00182 void writeImage( ImageTargetRef imageTarget, const ImageSourceRef &imageSource );
00183
00184 class ImageIoException : public Exception {
00185 };
00186
00187 class ImageIoExceptionFailedLoad : public ImageIoException {
00188 };
00189
00190 class ImageIoExceptionFailedWrite : public ImageIoException {
00191 };
00192
00193 class ImageIoExceptionUnknownExtension : public ImageIoException {
00194 };
00195
00196 class ImageIoExceptionIllegalColorModel : public ImageIoException {
00197 };
00198
00199 class ImageIoExceptionIllegalDataType : public ImageIoException {
00200 };
00201
00202 class ImageIoExceptionIllegalChannelOrder : public ImageIoException {
00203 };
00204
00205
00206 struct ImageIoRegistrar {
00207 typedef ImageSourceRef (*SourceCreationFunc)( DataSourceRef, ImageSource::Options options );
00208 typedef ImageTargetRef (*TargetCreationFunc)( DataTargetRef, ImageSourceRef, ImageTarget::Options options, const std::string& );
00209
00210 static ImageSourceRef createSource( DataSourceRef dataSource, ImageSource::Options options, std::string extension );
00211 static ImageTargetRef createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, std::string extension );
00212
00213 static void registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority = 2 );
00214 static void registerSourceGeneric( SourceCreationFunc func, int32_t priority = 2 );
00215
00216 static void registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );
00217
00218 private:
00219
00220 struct Inst {
00221 void registerSourceType( std::string extension, SourceCreationFunc func, int32_t priority );
00222 void registerSourceGeneric( SourceCreationFunc func, int32_t priority );
00223 void registerTargetType( std::string extension, TargetCreationFunc func, int32_t priority, const std::string &extensionData );
00224
00225 ImageSourceRef createSource( DataSourceRef dataSource, ImageSource::Options options, std::string extension );
00226 ImageTargetRef createTarget( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, std::string extension );
00227
00228 std::map<std::string, std::multimap<int32_t,SourceCreationFunc> > mSources;
00229 std::map<int32_t, SourceCreationFunc> mGenericSources;
00230 std::map<std::string, std::multimap<int32_t,std::pair<TargetCreationFunc,std::string> > > mTargets;
00231 };
00232
00233 static ImageIoRegistrar::Inst* instance();
00234
00235 friend class ImageIo;
00236 };
00237
00238 template<typename T>
00239 struct ImageIoRegistrant {
00240 ImageIoRegistrant() {
00241 (void) register_object;
00242 }
00243 private:
00244 struct exec_register {
00245 exec_register() {
00246 T::registerSelf();
00247 }
00248 };
00249
00250 static exec_register register_object;
00251 };
00252
00253 template<typename D> typename ImageIoRegistrant<D>::exec_register ImageIoRegistrant<D>::register_object;
00254
00255 #define REGISTER_IMAGE_IO_FILE_HANDLER( TYPE ) \
00256 struct ImageIoRegisterT##TYPE : public ImageIoRegistrant<TYPE> { \
00257 ImageIoRegisterT##TYPE() : ImageIoRegistrant<TYPE>() {} \
00258 };
00259
00260 }