TuttleOFX
1
|
00001 #include "ImageMagickReaderDefinitions.hpp" 00002 #include "ImageMagickReaderProcess.hpp" 00003 00004 #include <tuttle/common/system/system.hpp> 00005 #include <terry/globals.hpp> 00006 #include <tuttle/plugin/exceptions.hpp> 00007 00008 #include <magick/MagickCore.h> 00009 00010 #include <boost/gil/gil_all.hpp> 00011 #include <boost/filesystem/fstream.hpp> 00012 #include <boost/scoped_ptr.hpp> 00013 #include <boost/lexical_cast.hpp> 00014 #include <boost/assert.hpp> 00015 00016 00017 #if ( MAGICKCORE_QUANTUM_DEPTH == 8 ) 00018 #ifdef _MSC_VER 00019 #pragma NOTE( "MAGICKCORE_QUANTUM_DEPTH is 8" ) 00020 #else 00021 #warning "MAGICKCORE_QUANTUM_DEPTH is 8" 00022 #endif 00023 #define MAGICKCORE_QUANTUM_SUPPORT boost::uint32_t 00024 #elif ( MAGICKCORE_QUANTUM_DEPTH == 16 ) 00025 #ifdef _MSC_VER 00026 #pragma NOTE( "MAGICKCORE_QUANTUM_DEPTH is 16" ) 00027 #else 00028 #warning "MAGICKCORE_QUANTUM_DEPTH is 16" 00029 #endif 00030 #define MAGICKCORE_QUANTUM_SUPPORT boost::uint64_t 00031 #elif ( MAGICKCORE_QUANTUM_DEPTH == 32 ) 00032 #ifdef _MSC_VER 00033 #pragma NOTE( "MAGICKCORE_QUANTUM_DEPTH is 32" ) 00034 #else 00035 #warning "MAGICKCORE_QUANTUM_DEPTH is 32" 00036 #define MAGICKCORE_QUANTUM_SUPPORT boost::uint64_t 00037 #endif 00038 #endif 00039 00040 BOOST_STATIC_ASSERT( MAGICKCORE_QUANTUM_DEPTH != 8 || MAGICKCORE_QUANTUM_DEPTH != 16 ); 00041 00042 namespace boost { 00043 namespace gil { 00044 00045 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*0, MAGICKCORE_QUANTUM_DEPTH, true> rgba_quantum_packed_channel0_t; 00046 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*1, MAGICKCORE_QUANTUM_DEPTH, true> rgba_quantum_packed_channel1_t; 00047 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*2, MAGICKCORE_QUANTUM_DEPTH, true> rgba_quantum_packed_channel2_t; 00048 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*3, MAGICKCORE_QUANTUM_DEPTH, true> rgba_quantum_packed_channel3_t; 00049 00050 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*0, MAGICKCORE_QUANTUM_DEPTH, true> rgb_quantum_packed_channel0_t; 00051 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*1, MAGICKCORE_QUANTUM_DEPTH, true> rgb_quantum_packed_channel1_t; 00052 typedef const packed_channel_reference<MAGICKCORE_QUANTUM_SUPPORT, MAGICKCORE_QUANTUM_DEPTH*2, MAGICKCORE_QUANTUM_DEPTH, true> rgb_quantum_packed_channel2_t; 00053 00054 // RGBA 00055 typedef mpl::vector4<rgba_quantum_packed_channel0_t, rgba_quantum_packed_channel1_t, 00056 rgba_quantum_packed_channel2_t, rgba_quantum_packed_channel3_t> rgba_quantum_packed_channels_t; 00057 typedef packed_pixel<MAGICKCORE_QUANTUM_SUPPORT, rgba_quantum_packed_channels_t, bgra_layout_t> bgra_quantum_packed_pixel_t; 00058 typedef view_type_from_pixel<bgra_quantum_packed_pixel_t>::type bgra_quantum_packed_view_t; 00059 typedef image<bgra_quantum_packed_pixel_t, false> bgra_quantum_packed_image_t; 00060 00061 // RGB 00062 typedef mpl::vector3<rgb_quantum_packed_channel0_t, rgb_quantum_packed_channel1_t, 00063 rgb_quantum_packed_channel2_t> rgb_quantum_packed_channels_t; 00064 typedef packed_pixel<MAGICKCORE_QUANTUM_SUPPORT, rgb_quantum_packed_channels_t, bgr_layout_t> bgr_quantum_packed_pixel_t; 00065 typedef view_type_from_pixel<bgr_quantum_packed_pixel_t>::type bgr_quantum_packed_view_t; 00066 typedef image<bgr_quantum_packed_pixel_t, false> bgr_quantum_packed_image_t; 00067 00068 } 00069 } 00070 00071 namespace tuttle { 00072 namespace plugin { 00073 namespace imagemagick { 00074 namespace reader { 00075 00076 using namespace boost::gil; 00077 namespace bfs = boost::filesystem; 00078 00079 template<class View> 00080 ImageMagickReaderProcess<View>::ImageMagickReaderProcess( ImageMagickReaderPlugin& instance ) 00081 : ImageGilProcessor<View>( instance, eImageOrientationFromTopToBottom ) 00082 , _plugin( instance ) 00083 { 00084 this->setNoMultiThreading(); 00085 } 00086 00087 template<class View> 00088 void ImageMagickReaderProcess<View>::setup( const OFX::RenderArguments& args ) 00089 { 00090 ImageGilProcessor<View>::setup( args ); 00091 _params = _plugin.getProcessParams( args.time ); 00092 } 00093 00094 /** 00095 * @brief Function called by rendering thread each time a process must be done. 00096 * @param[in] procWindowRoW Processing window in RoW 00097 */ 00098 template<class View> 00099 void ImageMagickReaderProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00100 { 00101 // no tiles and no multithreading supported 00102 BOOST_ASSERT( procWindowRoW == this->_dstPixelRod ); 00103 readGilImage( this->_dstView, _plugin.getProcessParams( this->_renderArgs.time )._filepath ); 00104 } 00105 00106 template<class SView, class DView> 00107 void copy_and_convert_from_buffer( Image* image, DView& dst ) 00108 { 00109 ExceptionInfo exception; 00110 PixelPacket* buffer = GetAuthenticPixels( image, 0, 0, dst.width(), dst.height(), &exception ); 00111 00112 SView bufferView = interleaved_view( dst.width(), dst.height(), 00113 ( typename SView::value_type* )( buffer ), 00114 dst.width() * sizeof( typename SView::value_type ) ); 00115 00116 boost::gil::copy_and_convert_pixels( bufferView, dst ); 00117 } 00118 00119 /** 00120 */ 00121 template<class View> 00122 View& ImageMagickReaderProcess<View>::readGilImage( View& dst, const std::string& filepath ) 00123 { 00124 ImageInfo* imageInfo = AcquireImageInfo(); 00125 GetImageInfo( imageInfo ); 00126 strcpy( imageInfo->filename, filepath.c_str() ); 00127 ExceptionInfo* exceptionsInfo = AcquireExceptionInfo(); 00128 GetExceptionInfo( exceptionsInfo ); 00129 00130 ::Image* image = ReadImage( imageInfo, exceptionsInfo ); 00131 00132 CatchException( exceptionsInfo ); 00133 00134 if( image->colorspace != RGBColorspace && 00135 image->colorspace != GRAYColorspace && 00136 image->colorspace != TransparentColorspace ) 00137 { 00138 TUTTLE_LOG_WARNING( " Change colorspace to RGB." ); 00139 SetImageColorspace( image, RGBColorspace ); 00140 } 00141 00142 QuantumType colorType = GetQuantumType( image, exceptionsInfo ); 00143 00144 switch( colorType ) 00145 { 00146 case RGBQuantum: 00147 { 00148 #if ( MAGICKCORE_QUANTUM_DEPTH == 8 ) 00149 rgb8_image_t tmpImg ( dst.width(), dst.height() ); 00150 rgb8_view_t tmpVw = view( tmpImg ); 00151 00152 copy_and_convert_from_buffer<bgr_quantum_packed_view_t, rgb8_view_t>( image, tmpVw ); 00153 #elif ( MAGICKCORE_QUANTUM_DEPTH == 16 ) 00154 rgb16_image_t tmpImg ( dst.width(), dst.height() ); 00155 rgb16_view_t tmpVw = view( tmpImg ); 00156 00157 copy_and_convert_from_buffer<bgr_quantum_packed_view_t, rgb16_view_t>( image, tmpVw ); 00158 #elif ( MAGICKCORE_QUANTUM_DEPTH == 32 ) 00159 rgb32_image_t tmpImg ( dst.width(), dst.height() ); 00160 rgb32_view_t tmpVw = view( tmpImg ); 00161 00162 copy_and_convert_from_buffer<bgr_quantum_packed_view_t, rgb32_view_t>( image, tmpVw ); 00163 #endif 00164 copy_and_convert_pixels( tmpVw, dst ); 00165 break; 00166 } 00167 case RGBAQuantum: 00168 { 00169 #if ( MAGICKCORE_QUANTUM_DEPTH == 8 ) 00170 copy_and_convert_from_buffer<bgra8_view_t, View>( image, dst ); 00171 #elif ( MAGICKCORE_QUANTUM_DEPTH == 16 ) 00172 copy_and_convert_from_buffer<bgra16_view_t, View>( image, dst ); 00173 #elif ( MAGICKCORE_QUANTUM_DEPTH == 32 ) 00174 copy_and_convert_from_buffer<bgra32_view_t, View>( image, dst ); 00175 #endif 00176 break; 00177 } 00178 case AlphaQuantum: 00179 case GrayQuantum: 00180 { 00181 00182 #if ( MAGICKCORE_QUANTUM_DEPTH == 8 ) 00183 rgba8_image_t tmpImg ( dst.width(), dst.height() ); 00184 rgba8_view_t tmpVw = view( tmpImg ); 00185 00186 copy_and_convert_from_buffer<bgra_quantum_packed_view_t, rgba8_view_t>( image, tmpVw ); 00187 #elif ( MAGICKCORE_QUANTUM_DEPTH == 16 ) 00188 rgba16_image_t tmpImg ( dst.width(), dst.height() ); 00189 rgba16_view_t tmpVw = view( tmpImg ); 00190 00191 copy_and_convert_from_buffer<bgra_quantum_packed_view_t, rgba16_view_t>( image, tmpVw ); 00192 #elif ( MAGICKCORE_QUANTUM_DEPTH == 32 ) 00193 rgba32_image_t tmpImg ( dst.width(), dst.height() ); 00194 rgba32_view_t tmpVw = view( tmpImg ); 00195 00196 copy_and_convert_from_buffer<bgra_quantum_packed_view_t, rgba32_view_t>( image, tmpVw ); 00197 #endif 00198 copy_and_convert_pixels( boost::gil::nth_channel_view ( tmpVw, 0 ), dst ); 00199 00200 break; 00201 } 00202 default: 00203 { 00204 BOOST_THROW_EXCEPTION( exception::Unsupported() 00205 << exception::user( "Unknown color type (" + boost::lexical_cast<std::string>( colorType )+")" ) ); 00206 break; 00207 } 00208 } 00209 00210 image = DestroyImage( image ); 00211 imageInfo = DestroyImageInfo( imageInfo ); 00212 exceptionsInfo = DestroyExceptionInfo( exceptionsInfo ); 00213 return dst; 00214 } 00215 00216 } 00217 } 00218 } 00219 }