TuttleOFX  1
ImageMagickReaderPlugin.cpp
Go to the documentation of this file.
00001 #include "ImageMagickReaderPlugin.hpp"
00002 #include "ImageMagickReaderProcess.hpp"
00003 #include "ImageMagickReaderDefinitions.hpp"
00004 
00005 #include <boost/gil/gil_all.hpp>
00006 #include <boost/filesystem.hpp>
00007 
00008 #include <cstring>
00009 
00010 namespace tuttle {
00011 namespace plugin {
00012 namespace imagemagick {
00013 namespace reader {
00014 
00015 namespace bfs = boost::filesystem;
00016 using namespace boost::gil;
00017 
00018 ImageMagickReaderPlugin::ImageMagickReaderPlugin( OfxImageEffectHandle handle )
00019         : ReaderPlugin( handle )
00020 {
00021         MagickCoreGenesis( "",MagickFalse);
00022 }
00023 
00024 ImageMagickReaderProcessParams ImageMagickReaderPlugin::getProcessParams( const OfxTime time )
00025 {
00026         ImageMagickReaderProcessParams params;
00027 
00028         params._filepath = getAbsoluteFilenameAt( time );
00029 
00030         return params;
00031 }
00032 
00033 /**
00034  * @brief The overridden render function
00035  * @param[in]   args     Rendering parameters
00036  */
00037 void ImageMagickReaderPlugin::render( const OFX::RenderArguments& args )
00038 {
00039         ReaderPlugin::render( args );
00040 
00041         // instantiate the render code based on the pixel depth of the dst clip
00042         OFX::EBitDepth bitDepth         = _clipDst->getPixelDepth();
00043         OFX::EPixelComponent components = _clipDst->getPixelComponents();
00044 
00045         switch( components )
00046         {
00047                 case OFX::ePixelComponentRGBA:
00048                 {
00049                         doGilRender<ImageMagickReaderProcess, false, boost::gil::rgba_layout_t>( *this, args, bitDepth );
00050                         return;
00051                 }
00052                 case OFX::ePixelComponentRGB:
00053                 {
00054                         doGilRender<ImageMagickReaderProcess, false, boost::gil::rgb_layout_t>( *this, args, bitDepth );
00055                         return;
00056                 }
00057                 case OFX::ePixelComponentAlpha:
00058                 {
00059                         doGilRender<ImageMagickReaderProcess, false, boost::gil::gray_layout_t>( *this, args, bitDepth );
00060                         return;
00061                 }
00062                 case OFX::ePixelComponentCustom:
00063                 case OFX::ePixelComponentNone:
00064                 {
00065                         BOOST_THROW_EXCEPTION( exception::Unsupported()
00066                                 << exception::user() + "Pixel components (" + mapPixelComponentEnumToString(components) + ") not supported by the plugin." );
00067                 }
00068         }
00069         BOOST_THROW_EXCEPTION( exception::Unknown() );
00070 }
00071 
00072 void ImageMagickReaderPlugin::changedParam( const OFX::InstanceChangedArgs& args, const std::string& paramName )
00073 {
00074         ReaderPlugin::changedParam( args, paramName );
00075 }
00076 
00077 bool ImageMagickReaderPlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod )
00078 {
00079         ImageInfo* imageInfo = AcquireImageInfo();
00080 
00081         GetImageInfo( imageInfo );
00082         std::string filename = getAbsoluteFilenameAt( args.time );
00083         strcpy( imageInfo->filename, filename.c_str() );
00084         ExceptionInfo* exceptionsInfo = AcquireExceptionInfo();
00085         GetExceptionInfo( exceptionsInfo );
00086 
00087         Image* image = PingImage( imageInfo, exceptionsInfo );
00088 
00089         if( !image )
00090         {
00091                 imageInfo      = DestroyImageInfo( imageInfo );
00092                 exceptionsInfo = DestroyExceptionInfo( exceptionsInfo );
00093                 BOOST_THROW_EXCEPTION( exception::FileInSequenceNotExist()
00094                         << exception::user( "ImageMagick: Unable to open file" )
00095                         << exception::filename( getAbsoluteFilenameAt( args.time ) ) );
00096         }
00097 
00098         point2<ptrdiff_t> imagemagickDims( image->columns, image->rows );
00099         rod.x1 = 0;
00100         rod.x2 = imagemagickDims.x * this->_clipDst->getPixelAspectRatio();
00101         rod.y1 = 0;
00102         rod.y2 = imagemagickDims.y;
00103 
00104         image          = DestroyImage( image );
00105         imageInfo      = DestroyImageInfo( imageInfo );
00106         exceptionsInfo = DestroyExceptionInfo( exceptionsInfo );
00107 
00108         return true;
00109 }
00110 
00111 void ImageMagickReaderPlugin::getClipPreferences( OFX::ClipPreferencesSetter& clipPreferences )
00112 {
00113         ReaderPlugin::getClipPreferences( clipPreferences );
00114         const std::string filename = getAbsoluteFirstFilename();
00115 
00116         ImageInfo* imageInfo = AcquireImageInfo();
00117         GetImageInfo( imageInfo );
00118         strcpy( imageInfo->filename, filename.c_str() );
00119         ExceptionInfo* exceptionsInfo = AcquireExceptionInfo();
00120         GetExceptionInfo( exceptionsInfo );
00121 
00122 //      Image* image = PingImage( imageInfo, exceptionsInfo );
00123         Image* image = ReadImage( imageInfo, exceptionsInfo ); // necessary to obtain QuantumType
00124 
00125         if( !image )
00126                 BOOST_THROW_EXCEPTION( exception::File()
00127                         << exception::user( "ImageMagick: " )
00128                         << exception::filename( filename ) );
00129 
00130         if( getExplicitBitDepthConversion() == eParamReaderBitDepthAuto )
00131         {
00132                 clipPreferences.setClipBitDepth( *this->_clipDst, OFX::eBitDepthFloat ); // by default
00133                 unsigned long bitDepth = GetImageDepth( image, exceptionsInfo ); // if image information use it
00134                 if( bitDepth <= 8 )
00135                 {
00136                         clipPreferences.setClipBitDepth( *this->_clipDst, OFX::eBitDepthUByte );
00137                 }
00138                 else if( bitDepth <= 16 )
00139                 {
00140                         clipPreferences.setClipBitDepth( *this->_clipDst, OFX::eBitDepthUShort );
00141                 }
00142         }
00143 
00144         QuantumType colorType = GetQuantumType( image, exceptionsInfo );
00145 
00146         if( getExplicitChannelConversion() == eParamReaderChannelAuto )
00147         {
00148                 switch( colorType )
00149                 {
00150                         case RGBQuantum:
00151                         {
00152                                 if( OFX::getImageEffectHostDescription()->supportsPixelComponent( OFX::ePixelComponentRGB ) )
00153                                 {
00154                                         clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentRGB );
00155                                 }
00156                                 else
00157                                 {
00158                                         clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentRGBA );
00159                                 }
00160                                 break;
00161                         }
00162                         case RGBAQuantum:
00163                         {
00164                                 clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentRGBA );
00165                                 break;
00166                         }
00167                         case AlphaQuantum:
00168                         case GrayQuantum:
00169                         {
00170                                 clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentAlpha );
00171                                 break;
00172                         }
00173                         default:
00174                         {
00175                                 // convert in RGB colorspace
00176                                 TUTTLE_LOG_WARNING("convert to RGB colorspace");
00177                                 clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentRGBA );
00178                                 break;
00179                         }
00180                 }
00181         }
00182         
00183         clipPreferences.setPixelAspectRatio( *this->_clipDst, 1.0 ); /// @todo tuttle: retrieve info
00184 
00185         image          = DestroyImage( image );
00186         imageInfo      = DestroyImageInfo( imageInfo );
00187         exceptionsInfo = DestroyExceptionInfo( exceptionsInfo );
00188 }
00189 
00190 }
00191 }
00192 }
00193 }