TuttleOFX
1
|
00001 #include "TurboJpegWriterAlgorithm.hpp" 00002 00003 #include <terry/globals.hpp> 00004 00005 #include <cstdio> 00006 00007 #include <turbojpeg.h> 00008 00009 namespace tuttle { 00010 namespace plugin { 00011 namespace turboJpeg { 00012 namespace writer { 00013 00014 template<class View> 00015 TurboJpegWriterProcess<View>::TurboJpegWriterProcess( TurboJpegWriterPlugin &effect ) 00016 : ImageGilFilterProcessor<View>( effect, eImageOrientationFromTopToBottom ) 00017 , _plugin( effect ) 00018 { 00019 this->setNoMultiThreading(); 00020 } 00021 00022 template<class View> 00023 void TurboJpegWriterProcess<View>::setup( const OFX::RenderArguments& args ) 00024 { 00025 ImageGilFilterProcessor<View>::setup( args ); 00026 _params = _plugin.getProcessParams( args.time ); 00027 00028 } 00029 00030 /** 00031 * @brief Function called by rendering thread each time a process must be done. 00032 * @param[in] procWindowRoW Processing window 00033 */ 00034 template<class View> 00035 void TurboJpegWriterProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00036 { 00037 BOOST_ASSERT( procWindowRoW == this->_srcPixelRod ); 00038 using namespace boost::gil; 00039 00040 View srcView = this->_srcView; 00041 copy_pixels( this->_srcView, this->_dstView ); 00042 00043 try 00044 { 00045 writeImage( srcView ); 00046 } 00047 catch( exception::Common& e ) 00048 { 00049 e << exception::filename( _params.filepath ); 00050 throw; 00051 } 00052 catch(...) 00053 { 00054 BOOST_THROW_EXCEPTION( exception::Unknown() 00055 << exception::user( "Unable to write image" ) 00056 << exception::dev( boost::current_exception_diagnostic_information() ) 00057 << exception::filename( _params.filepath ) ); 00058 } 00059 } 00060 00061 template<class View> 00062 void TurboJpegWriterProcess<View>::writeImage( View& src ) 00063 { 00064 using namespace boost::gil; 00065 using namespace terry; 00066 00067 FILE *file = NULL; 00068 unsigned char *jpegBuf = NULL; 00069 00070 int width = src.width(); 00071 int height = src.height(); 00072 unsigned long jpegSize = 0; 00073 int ps = TJPF_RGB; 00074 int flags = 0; 00075 int pitch = 0; 00076 int subsampling = 0; 00077 00078 file = fopen( _params.filepath.c_str(), "wb"); 00079 if( file == NULL ) 00080 { 00081 BOOST_THROW_EXCEPTION( exception::File() 00082 << exception::user( "TurboJpeg: Unable to open file" ) 00083 << exception::filename( _params.filepath ) ); 00084 } 00085 fseek( file, 0, SEEK_SET ); 00086 00087 switch( _params.optimization ) 00088 { 00089 case eTurboJpegOptimizationNone: flags = 0; break; 00090 case eTurboJpegOptimizationSSE3: flags |= TJ_FORCESSE3; 00091 case eTurboJpegOptimizationSSE2: flags |= TJ_FORCESSE2; 00092 case eTurboJpegOptimizationSSE: flags |= TJ_FORCESSE; 00093 case eTurboJpegOptimizationMMX: flags |= TJ_FORCEMMX; 00094 } 00095 00096 switch( _params.subsampling ) 00097 { 00098 case eTurboJpegSubsampling444: subsampling = TJSAMP_444; break; 00099 case eTurboJpegSubsampling422: subsampling = TJSAMP_422; break; 00100 case eTurboJpegSubsampling420: subsampling = TJSAMP_420; break; 00101 case eTurboJpegSubsamplingGray: subsampling = TJSAMP_GRAY; break; 00102 case eTurboJpegSubsampling440: subsampling = TJSAMP_440; break; 00103 } 00104 00105 const tjhandle jpeghandle = tjInitCompress(); 00106 00107 rgb8_image_t tmpImg ( src.width(), src.height() ); 00108 rgb8_view_t tmpVw( view( tmpImg ) ); 00109 00110 boost::gil::copy_and_convert_pixels( src, tmpVw ); 00111 00112 unsigned char * data = ( unsigned char * ) boost::gil::interleaved_view_get_raw_data( tmpVw ); 00113 00114 //int ret = 00115 tjCompress2( jpeghandle, data, width, pitch, height, ps, &jpegBuf, &jpegSize, subsampling, _params.quality, flags ); 00116 00117 fwrite( (void *)jpegBuf, 1, jpegSize, file ); 00118 00119 delete[] jpegBuf; jpegBuf = NULL; 00120 tjDestroy( jpeghandle ); 00121 fclose( file ); file = NULL; 00122 00123 } 00124 00125 } 00126 } 00127 } 00128 }