TuttleOFX  1
TurboJpegWriterProcess.tcc
Go to the documentation of this file.
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 }