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