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