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 ), 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 } // namespace cinder