TuttleOFX  1
DPXWriterPlugin.cpp
Go to the documentation of this file.
00001 #include "DPXWriterPlugin.hpp"
00002 #include "DPXWriterProcess.hpp"
00003 #include "DPXWriterDefinitions.hpp"
00004 
00005 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00006 
00007 #include <boost/gil/gil_all.hpp>
00008 
00009 #include <boost/filesystem.hpp>
00010 
00011 #include <vector>
00012 
00013 
00014 namespace tuttle {
00015 namespace plugin {
00016 namespace dpx {
00017 namespace writer {
00018 
00019 using namespace boost::gil;
00020 
00021 DPXWriterPlugin::DPXWriterPlugin( OfxImageEffectHandle handle )
00022         : WriterPlugin( handle )
00023 {
00024         _bitDepth       = fetchChoiceParam( kTuttlePluginBitDepth );
00025         _descriptor     = fetchChoiceParam( kTuttlePluginChannel );
00026         _transfer       = fetchChoiceParam( kParamTransfer );
00027         _colorimetric   = fetchChoiceParam( kParamColorimetric );
00028         _packed         = fetchChoiceParam( kParamPacked );
00029         _swapEndian     = fetchBooleanParam( kParamSwapEndian );
00030         _encoding       = fetchChoiceParam( kParamEncoding );
00031         _orientation    = fetchChoiceParam( kParamOrientation );
00032         _project        = fetchStringParam( kParamProject );
00033         _copyright      = fetchStringParam( kParamCopyright );
00034 }
00035 
00036 DPXWriterProcessParams DPXWriterPlugin::getProcessParams( const OfxTime time )
00037 {
00038         DPXWriterProcessParams params;
00039         
00040         params._filepath  = getAbsoluteFilenameAt( time );
00041         params._project   = _project->getValue();
00042         params._copyright = _copyright->getValue();
00043         params._bitDepth  = static_cast< ETuttlePluginBitDepth >( _bitDepth->getValue() );
00044 
00045         switch ( params._bitDepth )
00046         {
00047                 case eTuttlePluginBitDepth8:
00048                         params._iBitDepth = 8;
00049                         break;
00050                 case eTuttlePluginBitDepth10:
00051                         params._iBitDepth = 10;
00052                         break;
00053                 case eTuttlePluginBitDepth12:
00054                         params._iBitDepth = 12;
00055                         break;
00056                 case eTuttlePluginBitDepth16:
00057                         params._iBitDepth = 16;
00058                         break;
00059                 case eTuttlePluginBitDepth32:
00060                         params._iBitDepth = 32;
00061                         break;
00062                 case eTuttlePluginBitDepth64:
00063                         params._iBitDepth = 64;
00064                         break;
00065         }
00066 
00067         switch( _descriptor->getValue() )
00068         {
00069                 case  0: params._descriptor = ::dpx::kUserDefinedDescriptor; break;
00070                 case  1: params._descriptor = ::dpx::kRed; break;
00071                 case  2: params._descriptor = ::dpx::kGreen; break;
00072                 case  3: params._descriptor = ::dpx::kBlue; break;
00073                 case  4: params._descriptor = ::dpx::kAlpha; break;
00074                 case  5: params._descriptor = ::dpx::kLuma; break;
00075                 case  6: params._descriptor = ::dpx::kColorDifference; break;
00076                 case  7: params._descriptor = ::dpx::kDepth; break;
00077                 case  8: params._descriptor = ::dpx::kCompositeVideo; break;
00078                 case  9: params._descriptor = ::dpx::kRGB; break;
00079                 case 10: params._descriptor = ::dpx::kRGBA; break;
00080                 case 11: params._descriptor = ::dpx::kABGR; break;
00081                 case 12: params._descriptor = ::dpx::kCbYCrY; break;
00082                 case 13: params._descriptor = ::dpx::kCbYACrYA; break;
00083                 case 14: params._descriptor = ::dpx::kCbYCr; break;
00084                 case 15: params._descriptor = ::dpx::kCbYCrA; break;
00085                 case 16: params._descriptor = ::dpx::kUserDefined2Comp; break;
00086                 case 17: params._descriptor = ::dpx::kUserDefined3Comp; break;
00087                 case 18: params._descriptor = ::dpx::kUserDefined4Comp; break;
00088                 case 19: params._descriptor = ::dpx::kUserDefined5Comp; break;
00089                 case 20: params._descriptor = ::dpx::kUserDefined6Comp; break;
00090                 case 21: params._descriptor = ::dpx::kUserDefined7Comp; break;
00091                 case 22: params._descriptor = ::dpx::kUserDefined8Comp; break;
00092                 case 23: params._descriptor = ::dpx::kUndefinedDescriptor; break;
00093                 case 24:
00094                         switch( _clipSrc->getPixelComponents() )
00095                         {
00096                                 case OFX::ePixelComponentAlpha: params._descriptor = ::dpx::kLuma; break;
00097                                 case OFX::ePixelComponentRGB:   params._descriptor = ::dpx::kRGB; break;
00098                                 case OFX::ePixelComponentRGBA:  params._descriptor = ::dpx::kRGBA;break;
00099                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00100                                                 << exception::user( "Dpx: unknown input channel type." ) );
00101                                                 break;
00102                         }
00103                         break;
00104                 default: break;
00105         }
00106         switch( _transfer->getValue() )
00107         {
00108                 case 13 : params._transfer = ::dpx::kUndefinedCharacteristic; break;
00109                 default : params._transfer = static_cast< ::dpx::Characteristic >( _transfer->getValue() ); break;
00110         }
00111         switch( _colorimetric->getValue() )
00112         {
00113                 case 13 : params._colorimetric = ::dpx::kUndefinedCharacteristic; break;
00114                 default : params._colorimetric = static_cast< ::dpx::Characteristic >( _colorimetric->getValue() ); break;
00115         }
00116 
00117         params._packed       = static_cast< ::dpx::Packing >( _packed->getValue() );
00118         params._encoding     = static_cast< ::dpx::Encoding >( _encoding->getValue() );
00119         params._orientation  = static_cast< ::dpx::Orientation >( _orientation->getValue() );
00120         params._swapEndian   = _swapEndian->getValue();
00121         
00122         return params;
00123 }
00124 
00125 /**
00126  * @brief The overridden render function
00127  * @param[in]   args     Rendering parameters
00128  */
00129 void DPXWriterPlugin::render( const OFX::RenderArguments& args )
00130 {
00131         WriterPlugin::render( args );
00132         DPXWriterProcessParams params = getProcessParams( args.time );
00133         
00134         OFX::EBitDepth        eOfxBitDepth = _clipSrc->getPixelDepth();
00135         OFX::EPixelComponent  components   = _clipSrc->getPixelComponents();
00136         OfxPointI             size         = _clipSrc->getPixelRodSize( args.time );
00137         
00138         switch ( params._bitDepth )
00139         {
00140                 case eTuttlePluginBitDepth8:
00141                         switch ( eOfxBitDepth )
00142                         {
00143                                 case OFX::eBitDepthCustom:
00144                                 case OFX::eBitDepthNone:
00145                                         BOOST_THROW_EXCEPTION( exception::BitDepthMismatch()
00146                                                 << exception::user( "Dpx: Unable to write upper bit depth" ) );
00147                                         break;
00148                                 case OFX::eBitDepthUShort:
00149                                 case OFX::eBitDepthFloat:
00150                                         switch( components )
00151                                         {
00152                                                 case OFX::ePixelComponentAlpha: doGilRender<DPXWriterProcess, false, boost::gil::gray_layout_t>( *this, args, eOfxBitDepth ); break;
00153                                                 case OFX::ePixelComponentRGB  : doGilRender<DPXWriterProcess, false, boost::gil::rgb_layout_t> ( *this, args, eOfxBitDepth ); break;
00154                                                 case OFX::ePixelComponentRGBA : doGilRender<DPXWriterProcess, false, boost::gil::rgba_layout_t>( *this, args, eOfxBitDepth ); break;
00155                                                 default: BOOST_THROW_EXCEPTION( exception::InputMismatch()
00156                                                                                                                 << exception::user( "Dpx: Unknown component." ) ); break;
00157                                         }
00158                                         return;
00159                                 case OFX::eBitDepthUByte: break;
00160                         }
00161                         break;
00162                 case eTuttlePluginBitDepth10:
00163                         switch ( eOfxBitDepth )
00164                         {
00165                                 case OFX::eBitDepthCustom:
00166                                 case OFX::eBitDepthNone:
00167                                 {
00168                                         BOOST_THROW_EXCEPTION( exception::BitDepthMismatch()
00169                                                 << exception::user( "Dpx: Unable to write upper bit depth" ) );
00170                                         break;
00171                                 }
00172                                 case OFX::eBitDepthUShort:// break; // @TODO temporary use GIL, the conversion Gray => RGBA provide a segfault after writer.Finish() function.
00173                                 case OFX::eBitDepthUByte:
00174                                 case OFX::eBitDepthFloat:
00175                                 {
00176                                         switch( components )
00177                                         {
00178                                                 case OFX::ePixelComponentAlpha: doGilRender<DPXWriterProcess, false, boost::gil::gray_layout_t>( *this, args, eOfxBitDepth ); break;
00179                                                 case OFX::ePixelComponentRGB  : doGilRender<DPXWriterProcess, false, boost::gil::rgb_layout_t> ( *this, args, eOfxBitDepth ); break;
00180                                                 case OFX::ePixelComponentRGBA : doGilRender<DPXWriterProcess, false, boost::gil::rgba_layout_t>( *this, args, eOfxBitDepth ); break;
00181                                                 default: BOOST_THROW_EXCEPTION( exception::InputMismatch()
00182                                                                                                                 << exception::user( "Dpx: Unknown component." ) ); break;
00183                                         }
00184                                         return;
00185                                 }
00186                         }
00187                         break;
00188                 case eTuttlePluginBitDepth12:
00189                         switch ( eOfxBitDepth )
00190                         {
00191                                 case OFX::eBitDepthCustom:
00192                                 case OFX::eBitDepthNone:
00193                                 {
00194                                         BOOST_THROW_EXCEPTION( exception::BitDepthMismatch()
00195                                                 << exception::user( "Dpx: Unable to write upper bit depth" ) );
00196                                         break;
00197                                 }
00198                                 case OFX::eBitDepthUByte:
00199                                 case OFX::eBitDepthFloat:
00200                                 {
00201                                         switch( components )
00202                                         {
00203                                                 case OFX::ePixelComponentAlpha: doGilRender<DPXWriterProcess, false, boost::gil::gray_layout_t>( *this, args, eOfxBitDepth ); break;
00204                                                 case OFX::ePixelComponentRGB  : doGilRender<DPXWriterProcess, false, boost::gil::rgb_layout_t> ( *this, args, eOfxBitDepth ); break;
00205                                                 case OFX::ePixelComponentRGBA : doGilRender<DPXWriterProcess, false, boost::gil::rgba_layout_t>( *this, args, eOfxBitDepth ); break;
00206                                                 default: BOOST_THROW_EXCEPTION( exception::InputMismatch()
00207                                                                                                                 << exception::user( "Dpx: Unknown component." ) ); break;
00208                                         }
00209                                         return;
00210                                 }
00211                                 case OFX::eBitDepthUShort: break;
00212                         }
00213                         break;
00214                 case eTuttlePluginBitDepth16:
00215                         switch ( eOfxBitDepth )
00216                         {
00217                                 case OFX::eBitDepthCustom:
00218                                 case OFX::eBitDepthNone:
00219                                 {
00220                                         BOOST_THROW_EXCEPTION( exception::BitDepthMismatch()
00221                                                 << exception::user( "Dpx: Unable to write upper bit depth" ) );
00222                                         break;
00223                                 }
00224                                 case OFX::eBitDepthUByte:
00225                                 case OFX::eBitDepthFloat:
00226                                 {
00227                                         switch( components )
00228                                         {
00229                                                 case OFX::ePixelComponentAlpha: doGilRender<DPXWriterProcess, false, boost::gil::gray_layout_t>( *this, args, eOfxBitDepth ); break;
00230                                                 case OFX::ePixelComponentRGB  : doGilRender<DPXWriterProcess, false, boost::gil::rgb_layout_t> ( *this, args, eOfxBitDepth ); break;
00231                                                 case OFX::ePixelComponentRGBA : doGilRender<DPXWriterProcess, false, boost::gil::rgba_layout_t>( *this, args, eOfxBitDepth ); break;
00232                                                 default: BOOST_THROW_EXCEPTION( exception::InputMismatch()
00233                                                                                                                 << exception::user( "Dpx: Unknown component." ) ); break;
00234                                         }
00235                                         return;
00236                                 }
00237                                 case OFX::eBitDepthUShort: break;
00238                         }
00239                         break;
00240                 case eTuttlePluginBitDepth32:
00241                 case eTuttlePluginBitDepth64:
00242                         break;
00243         }
00244 
00245         std::string filename = getAbsoluteFilenameAt( args.time );
00246 
00247         ::dpx::Writer   writer;
00248         ::dpx::DataSize dataSize = ::dpx::kByte;
00249 
00250         OutStream       stream;
00251 
00252         if( ! stream.Open( filename.c_str() ) )
00253         {
00254                 BOOST_THROW_EXCEPTION( exception::File()
00255                         << exception::user( "Dpx: Unable to open output file" ) );
00256         }
00257 
00258         writer.SetOutStream( &stream );
00259 
00260         writer.Start();
00261 
00262         writer.SetFileInfo( filename.c_str(), 0, "TuttleOFX DPX Writer", params._project.c_str(), params._copyright.c_str(), ~0, params._swapEndian );
00263 
00264         writer.SetImageInfo( size.x, size.y );
00265 
00266         writer.header.SetImageOrientation( params._orientation );
00267 
00268         int pixelSize = 0;
00269         std::string inputComponentString = "unknown";
00270 
00271         switch ( eOfxBitDepth )
00272         {
00273                 case OFX::eBitDepthCustom:
00274                 case OFX::eBitDepthNone:
00275                         BOOST_THROW_EXCEPTION( exception::BitDepthMismatch()
00276                                 << exception::user( "Dpx: Unable to compute custom or non bit depth" ) );
00277                         break;
00278                 case OFX::eBitDepthUByte:  dataSize = ::dpx::kByte;  pixelSize = 1; break;
00279                 case OFX::eBitDepthUShort: dataSize = ::dpx::kWord;  pixelSize = 2; break;
00280                 case OFX::eBitDepthFloat:  dataSize = ::dpx::kFloat; pixelSize = 4; break;
00281         }
00282         switch( components )
00283         {
00284                 case OFX::ePixelComponentAlpha: inputComponentString = "Gray/Alpha"; break; // pixelSize *= 1;
00285                 case OFX::ePixelComponentRGB  : inputComponentString = "RGB";  pixelSize *= 3; break;
00286                 case OFX::ePixelComponentRGBA : inputComponentString = "RGBA"; pixelSize *= 4;  break;
00287                 default: break;
00288         }
00289         
00290         typedef std::vector<char, OfxAllocator<char> > DataVector;
00291         const std::size_t rowBytesToCopy = size.x * pixelSize;
00292         //const std::size_t rowBytesToCopy = size.x * 4; // allocation of 4 channels, to allow conversion after on this buffer (Gray=>RGBA). Better option to do this ?
00293 
00294         DataVector data( rowBytesToCopy * size.y );
00295         char* dataPtrIt = &data.front();
00296 
00297         boost::scoped_ptr<OFX::Image> src( _clipSrc->fetchImage( args.time ) );
00298 
00299         for( int y = size.y; y > 0; --y )
00300         {
00301                 void* dataSrcPtr = src->getPixelAddress( 0, y-1 );
00302                 memcpy( dataPtrIt, dataSrcPtr, rowBytesToCopy );
00303 
00304                 dataPtrIt += rowBytesToCopy;
00305         }
00306         
00307         switch( params._descriptor )
00308         {
00309                 case ::dpx::kUserDefinedDescriptor:
00310                         switch( components )
00311                         {
00312                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00313                                                 << exception::user( "Dpx: Unable to write user defined" ) );
00314                                                 break;
00315                         }
00316                         break;
00317                 case ::dpx::kRed:
00318                         switch( components )
00319                         {
00320                                 case OFX::ePixelComponentAlpha: break;
00321                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00322                                                 << exception::user( "Dpx: Unable to write Red channel (input is " + inputComponentString + ")." ) );
00323                                                 break;
00324                         }
00325                         break;
00326                 case ::dpx::kGreen:
00327                         switch( components )
00328                         {
00329                                 case OFX::ePixelComponentAlpha: break;
00330                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00331                                                 << exception::user( "Dpx: Unable to write Green channel (input is " + inputComponentString + ")." ) );
00332                                                 break;
00333                         }
00334                         break;
00335                 case ::dpx::kBlue:
00336                         switch( components )
00337                         {
00338                                 case OFX::ePixelComponentAlpha: break;
00339                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00340                                                 << exception::user( "Dpx: Unable to write Blue channel (input is " + inputComponentString + ")." ) );
00341                                                 break;
00342                         }
00343                         break;
00344                 case ::dpx::kAlpha:
00345                         switch( components )
00346                         {
00347                                 case OFX::ePixelComponentAlpha: break;
00348                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00349                                                 << exception::user( "Dpx: Unable to write Alpha channel (input is " + inputComponentString + ")." ) );
00350                                                 break;
00351                         }
00352                         break;
00353                 case ::dpx::kLuma:
00354                         switch( components )
00355                         {
00356                                 case OFX::ePixelComponentAlpha: break;
00357                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00358                                                 << exception::user( "Dpx: Unable to write Luma channel (input is " + inputComponentString + ")." ) );
00359                                                 break;
00360                         }
00361                         break;
00362                 case ::dpx::kColorDifference:
00363                         switch( components )
00364                         {
00365                                 case OFX::ePixelComponentAlpha: break;
00366                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00367                                                 << exception::user( "Dpx: Unable to write ColorDifference channel (input is " + inputComponentString + ")." ) );
00368                                                 break;
00369                         }
00370                         break;
00371                 case ::dpx::kDepth:
00372                         switch( components )
00373                         {
00374                                 case OFX::ePixelComponentAlpha: break;
00375                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00376                                                 << exception::user( "Dpx: Unable to write Depth channel (input is " + inputComponentString + ")." ) );
00377                                                 break;
00378                         }
00379                         break;
00380                 case ::dpx::kCompositeVideo:
00381                         switch( components )
00382                         {
00383                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00384                                                 << exception::user( "Dpx: Unable to write channel (input is " + inputComponentString + ")." ) );
00385                                                 break;
00386                         }
00387                         break;
00388                 case ::dpx::kRGB:
00389                         switch( components )
00390                         {
00391                                 case OFX::ePixelComponentAlpha:
00392                                 {
00393                                         convertGrayToRGB( data, size.x, size.y, pixelSize );
00394                                         break;
00395                                 }
00396                                 case OFX::ePixelComponentRGB: break;
00397                                 case OFX::ePixelComponentRGBA:
00398                                 {
00399                                         convertRGBAToRGB( data, size.x, size.y, pixelSize );
00400                                         break;
00401                                 }
00402                                 default:
00403                                 {
00404                                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00405                                                 << exception::user( "Dpx: Unable to write RGB channels (input is " + inputComponentString + ")." ) );
00406                                                 break;
00407                                 }
00408                         }
00409                         break;
00410                 case ::dpx::kRGBA:
00411                         switch( components )
00412                         {
00413                                 case OFX::ePixelComponentRGBA: break;
00414                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00415                                                 << exception::user( "Dpx: Unable to write RGBA channels (input is " + inputComponentString + ")." ) );
00416                                                 break;
00417                         }
00418                         break;
00419                 case ::dpx::kABGR:
00420                         switch( components )
00421                         {
00422                                 case OFX::ePixelComponentRGBA: 
00423                                         convertRGBAToABGR( data, size.x, size.y, pixelSize );
00424                                         break;
00425                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00426                                                 << exception::user( "Dpx: Unable to write ABGR channels (input is " + inputComponentString + ")." ) );
00427                                                 break;
00428                         }
00429                         break;
00430                 case ::dpx::kCbYCrY:
00431                         switch( components )
00432                         {
00433                                 case OFX::ePixelComponentRGB: break;
00434                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00435                                                 << exception::user( "Dpx: Unable to write CbYCrY channels (input is " + inputComponentString + ")." ) );
00436                                                 break;
00437                         }
00438                         break;
00439                 case ::dpx::kCbYACrYA:
00440                         switch( components )
00441                         {
00442                                 case OFX::ePixelComponentRGBA: break;
00443                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00444                                                 << exception::user( "Dpx: Unable to write CbYCrYA channels (input is " + inputComponentString + ")." ) );
00445                                                 break;
00446                         }
00447                         break;
00448                 case ::dpx::kCbYCr:
00449                         switch( components )
00450                         {
00451                                 case OFX::ePixelComponentRGB: break;
00452                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00453                                                 << exception::user( "Dpx: Unable to write CbYCr channels (input is " + inputComponentString + ")." ) );
00454                                                 break;
00455                         }
00456                         break;
00457                 case ::dpx::kCbYCrA:
00458                         switch( components )
00459                         {
00460                                 case OFX::ePixelComponentRGBA: break;
00461                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00462                                                 << exception::user( "Dpx: Unable to write CbYCrA channels (input is " + inputComponentString + ")." ) );
00463                                                 break;
00464                         }
00465                         break;
00466                 case ::dpx::kUserDefined2Comp:
00467                         switch( components )
00468                         {
00469                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00470                                                 << exception::user( "Dpx: Unable to write 2 channels (input is " + inputComponentString + ")." ) );
00471                                                 break;
00472                         }
00473                         break;
00474                 case ::dpx::kUserDefined3Comp:
00475                         switch( components )
00476                         {
00477                                 case OFX::ePixelComponentRGB: break;
00478                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00479                                                 << exception::user( "Dpx: Unable to write 3 channel (input is " + inputComponentString + ")." ) );
00480                                                 break;
00481                         }
00482                         break;
00483                 case ::dpx::kUserDefined4Comp:
00484                         switch( components )
00485                         {
00486                                 case OFX::ePixelComponentRGBA: break;
00487                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00488                                                 << exception::user( "Dpx: Unable to write 4 channel (input is " + inputComponentString + ")." ) );
00489                                                 break;
00490                         }
00491                         break;
00492                 case ::dpx::kUserDefined5Comp:
00493                         switch( components )
00494                         {
00495                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00496                                                 << exception::user( "Dpx: Unable to write 5 channels (input is " + inputComponentString + ")." ) );
00497                                                 break;
00498                         }
00499                         break;
00500                 case ::dpx::kUserDefined6Comp:
00501                         switch( components )
00502                         {
00503                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00504                                                 << exception::user( "Dpx: Unable to write 6 channels (input is " + inputComponentString + ")." ) );
00505                                                 break;
00506                         }
00507                         break;
00508                 case ::dpx::kUserDefined7Comp:
00509                         switch( components )
00510                         {
00511                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00512                                                 << exception::user( "Dpx: Unable to write 7 channels (input is " + inputComponentString + ")." ) );
00513                                                 break;
00514                         }
00515                         break;
00516                 case ::dpx::kUserDefined8Comp:
00517                         switch( components )
00518                         {
00519                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00520                                                 << exception::user( "Dpx: Unable to write 8 channels (input is " + inputComponentString + ")." ) );
00521                                                 break;
00522                         }
00523                         break;
00524                 case ::dpx::kUndefinedDescriptor:
00525                         switch( components )
00526                         {
00527                                 default: BOOST_THROW_EXCEPTION( exception::ImageFormat()
00528                                                 << exception::user( "Dpx: Unable to write undefined descriptor (input is " + inputComponentString + ")." ) );
00529                                                 break;
00530                         }
00531                         break;
00532         }
00533 
00534         writer.SetElement( 0,
00535                         params._descriptor,
00536                         params._iBitDepth,
00537                         params._transfer,
00538                         params._colorimetric,
00539                         params._packed,
00540                         params._encoding );
00541 
00542         if( ! writer.WriteHeader() )
00543         {
00544                 BOOST_THROW_EXCEPTION( exception::Data()
00545                         << exception::user( "Dpx: Unable to write data (DPX Header)" ) );
00546         }
00547         if( ! writer.WriteElement( 0, &data.front(), dataSize ) )
00548         {
00549                 BOOST_THROW_EXCEPTION( exception::Data()
00550                         << exception::user( "Dpx: Unable to write data (DPX User Data)" ) );
00551         }
00552 
00553         if( ! writer.Finish() )
00554         {
00555                 BOOST_THROW_EXCEPTION( exception::Data()
00556                         << exception::user( "Dpx: Unable to write data (DPX finish)" ) );
00557         }
00558         
00559         stream.Close();
00560 }
00561 
00562 void DPXWriterPlugin::changedParam( const OFX::InstanceChangedArgs& args, const std::string& paramName )
00563 {
00564         WriterPlugin::changedParam( args, paramName );
00565 }
00566 
00567 }
00568 }
00569 }
00570 }