TuttleOFX
1
|
00001 #ifndef _ofxsImageEffect_H_ 00002 #define _ofxsImageEffect_H_ 00003 /* 00004 * OFX Support Library, a library that skins the OFX plug-in API with C++ classes. 00005 * Copyright (C) 2004-2005 The Open Effects Association Ltd 00006 * Author Bruno Nicoletti bruno@thefoundry.co.uk 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the following disclaimer. 00013 * Redistributions in binary form must reproduce the above copyright notice, 00014 * this list of conditions and the following disclaimer in the documentation 00015 * and/or other materials provided with the distribution. 00016 * Neither the name The Open Effects Association Ltd, nor the names of its 00017 * contributors may be used to endorse or promote products derived from this 00018 * software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 00024 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 * The Open Effects Association Ltd 00032 * 1 Wardour St 00033 * London W1D 6PA 00034 * England 00035 * 00036 * 00037 * 00038 */ 00039 00040 /** @file This file contains core code that wraps OFX 'objects' with C++ classes. 00041 * 00042 * This file only holds code that is visible to a plugin implementation, and so hides much 00043 * of the direct OFX objects and any library side only functions. 00044 */ 00045 #include "ofxsParam.h" 00046 #include "ofxsInteract.h" 00047 #include "ofxsMessage.h" 00048 #include "ofxParametricParam.h" 00049 #include "extensions/nuke/camera.h" 00050 00051 #include <ofxProgress.h> 00052 #include <ofxTimeLine.h> 00053 00054 #include <map> 00055 #include <vector> 00056 #include <string> 00057 #include <algorithm> 00058 #include <sstream> 00059 00060 /** @brief Nasty macro used to define empty protected copy ctors and assign ops */ 00061 #define mDeclareProtectedAssignAndCC( CLASS ) \ 00062 CLASS& operator=( const CLASS& ) { assert( false ); return *this; } \ 00063 CLASS( const CLASS & ) { assert( false ); } 00064 00065 namespace OFX { 00066 namespace Private { 00067 00068 OfxStatus mainEntryStr( const char* actionRaw, 00069 const void* handleRaw, 00070 OfxPropertySetHandle inArgsRaw, 00071 OfxPropertySetHandle outArgsRaw, 00072 const char* plugname ); 00073 } 00074 } 00075 00076 /** 00077 * @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. 00078 */ 00079 namespace OFX { 00080 /** forward class declarations */ 00081 struct tag_ofxStatus; 00082 00083 class ClipDescriptor; 00084 class ImageEffectDescriptor; 00085 00086 class Image; 00087 class Clip; 00088 class ImageEffect; 00089 class ImageMemory; 00090 00091 /** @brief Enumerates the contexts a plugin can be used in */ 00092 enum EContext 00093 { 00094 eContextNone, 00095 eContextGenerator, 00096 eContextFilter, 00097 eContextTransition, 00098 eContextPaint, 00099 eContextGeneral, 00100 eContextRetimer, 00101 eContextReader, 00102 eContextWriter, 00103 }; 00104 00105 const std::string mapContextEnumToString( const EContext s ); 00106 00107 /** @brief Enumerates the pixel depths supported */ 00108 enum EBitDepth 00109 { 00110 eBitDepthCustom = -1, ///< some non standard bit depth 00111 eBitDepthNone = 0, ///< bit depth that indicates no data is present 00112 eBitDepthUByte = 1, 00113 eBitDepthUShort = 2, 00114 eBitDepthFloat = 3 00115 }; 00116 00117 const std::string mapBitDepthEnumToString( const EBitDepth e ); 00118 00119 /** @brief Enumerates the component types supported */ 00120 enum EPixelComponent 00121 { 00122 ePixelComponentNone, 00123 ePixelComponentRGBA, 00124 ePixelComponentRGB, 00125 ePixelComponentAlpha, 00126 ePixelComponentCustom ///< some non standard pixel type 00127 }; 00128 00129 std::string mapPixelComponentEnumToString( const EPixelComponent e ); 00130 00131 /** @brief Enumerates the ways a fielded image can be extracted from a clip */ 00132 enum EFieldExtraction 00133 { 00134 eFieldExtractBoth, /**< @brief extract both fields */ 00135 eFieldExtractSingle, /**< @brief extracts a single field, so you have a half height image */ 00136 eFieldExtractDoubled /**< @brief extracts a single field, but doubles up the field, so you have a full height image */ 00137 }; 00138 00139 /** @brief Enumerates the kind of render thread safety a plugin has */ 00140 enum ERenderSafety 00141 { 00142 eRenderUnsafe, /**< @brief can only render a single instance at any one time */ 00143 eRenderInstanceSafe, /**< @brief can call a single render on an instance, but can render multiple instances simultaneously */ 00144 eRenderFullySafe /**< @brief can call render any number of times on an instance, and render multiple instances simultaneously */ 00145 }; 00146 00147 /** @brief Enumerates the fields present in an image */ 00148 enum EField 00149 { 00150 eFieldNone, /**< @brief unfielded image */ 00151 eFieldBoth, /**< @brief fielded image with both fields present */ 00152 eFieldLower, /**< @brief only the spatially lower field is present */ 00153 eFieldUpper /**< @brief only the spatially upper field is present */ 00154 }; 00155 00156 std::string mapFieldEnumToString( const EField e ); 00157 00158 enum EPreMultiplication 00159 { 00160 eImageOpaque, /**< @brief the image is opaque and so has no premultiplication state */ 00161 eImagePreMultiplied, /**< @brief the image is premultiplied by it's alpha */ 00162 eImageUnPreMultiplied, /**< @brief the image is unpremultiplied */ 00163 }; 00164 00165 std::string mapPreMultiplicationEnumToString( const EPreMultiplication e ); 00166 00167 00168 class PluginFactory 00169 { 00170 public: 00171 virtual ~PluginFactory() {} 00172 virtual void load() {} 00173 virtual void unload() {} 00174 virtual void describe( OFX::ImageEffectDescriptor& desc ) = 0; 00175 virtual void describeInContext( OFX::ImageEffectDescriptor& desc, EContext context ) = 0; 00176 virtual ImageEffect* createInstance( OfxImageEffectHandle handle, EContext context ) = 0; 00177 virtual const std::string& getID() const = 0; 00178 virtual const std::string& getUID() const = 0; 00179 virtual unsigned int getMajorVersion() const = 0; 00180 virtual unsigned int getMinorVersion() const = 0; 00181 virtual OfxPluginEntryPoint* getMainEntry() = 0; 00182 }; 00183 00184 template<class FACTORY> 00185 class FactoryMainEntryHelper 00186 { 00187 protected: 00188 const std::string& getHelperID() const { return _id; } 00189 unsigned int getHelperMajorVersion() const { return _maj; } 00190 unsigned int getHelperMinorVersion() const { return _min; } 00191 00192 FactoryMainEntryHelper( const std::string& id, const unsigned int maj, const unsigned int min ) 00193 : _id( id ) 00194 , _maj( maj ) 00195 , _min( min ) 00196 { 00197 std::ostringstream ss; 00198 ss << id << "." << maj << "." << min; 00199 _uid = ss.str(); 00200 } 00201 00202 const std::string& getHelperUID() const { return _uid; } 00203 static OfxStatus mainEntry( const char* action, const void* handle, OfxPropertySetHandle in, OfxPropertySetHandle out ) 00204 { 00205 return OFX::Private::mainEntryStr( action, handle, in, out, _uid.c_str() ); 00206 } 00207 00208 static std::string _uid; 00209 std::string _id; 00210 unsigned int _maj; 00211 unsigned int _min; 00212 }; 00213 00214 template<class T> 00215 std::string OFX::FactoryMainEntryHelper<T>::_uid; 00216 00217 template<class FACTORY> 00218 class PluginFactoryHelper : public FactoryMainEntryHelper<FACTORY>, 00219 public PluginFactory 00220 { 00221 public: 00222 PluginFactoryHelper( const std::string& id, unsigned int maj, unsigned int min ) : FactoryMainEntryHelper<FACTORY>( id, maj, min ) 00223 {} 00224 virtual ~PluginFactoryHelper() {} 00225 OfxPluginEntryPoint* getMainEntry() { return FactoryMainEntryHelper<FACTORY>::mainEntry; } 00226 const std::string& getID() const { return FactoryMainEntryHelper<FACTORY>::getHelperID(); } 00227 const std::string& getUID() const { return FactoryMainEntryHelper<FACTORY>::getHelperUID(); } 00228 unsigned int getMajorVersion() const { return FactoryMainEntryHelper<FACTORY>::getHelperMajorVersion(); } 00229 unsigned int getMinorVersion() const { return FactoryMainEntryHelper<FACTORY>::getHelperMinorVersion(); } 00230 }; 00231 00232 #define mDeclarePluginFactory( CLASS, LOADFUNCDEF, UNLOADFUNCDEF ) \ 00233 class CLASS : public OFX::PluginFactoryHelper < CLASS > \ 00234 { \ 00235 public: \ 00236 CLASS( const std::string & id, unsigned int verMaj, unsigned int verMin ) : OFX::PluginFactoryHelper < CLASS > ( id, verMaj, verMin ) {} \ 00237 virtual ~CLASS() {} \ 00238 virtual void load() LOADFUNCDEF ; \ 00239 virtual void unload() UNLOADFUNCDEF ; \ 00240 virtual void describe( OFX::ImageEffectDescriptor & desc ); \ 00241 virtual void describeInContext( OFX::ImageEffectDescriptor & desc, OFX::EContext context ); \ 00242 virtual OFX::ImageEffect* createInstance( OfxImageEffectHandle handle, OFX::EContext context ); \ 00243 }; 00244 00245 typedef std::vector<PluginFactory*> PluginFactoryArray; 00246 00247 /** @brief Fetch's a suite from the host and logs errors 00248 * 00249 * All the standard suites are fetched by the support code, you should use this 00250 * to fetch any extra non-standard suites. 00251 */ 00252 void* fetchSuite( const char* suiteName, int suiteVersion, bool optional = false ); 00253 00254 //////////////////////////////////////////////////////////////////////////////// 00255 /** @brief A class that lists all the properties of a host */ 00256 struct ImageEffectHostDescription 00257 { 00258 public: 00259 std::string hostName; 00260 std::string hostLabel; 00261 bool hostIsBackground; 00262 bool supportsOverlays; 00263 bool supportsMultiResolution; 00264 bool supportsTiles; 00265 bool temporalClipAccess; 00266 bool supportsMultipleClipDepths; 00267 bool supportsMultipleClipPARs; 00268 bool supportsSetableFrameRate; 00269 bool supportsSetableFielding; 00270 bool supportsStringAnimation; 00271 bool supportsCustomInteract; 00272 bool supportsChoiceAnimation; 00273 bool supportsBooleanAnimation; 00274 bool supportsCustomAnimation; 00275 bool supportsParametricParameter; 00276 bool supportsCameraParameter; 00277 int maxParameters; 00278 int maxPages; 00279 int pageRowCount; 00280 int pageColumnCount; 00281 typedef std::vector<EPixelComponent> PixelComponentArray; 00282 PixelComponentArray _supportedComponents; 00283 typedef std::vector<EContext> ContextArray; 00284 ContextArray _supportedContexts; 00285 typedef std::vector<EBitDepth> BitDepthArray; 00286 BitDepthArray _supportedPixelDepths; 00287 bool supportsProgressSuite; 00288 bool supportsTimeLineSuite; 00289 00290 public: 00291 bool supportsPixelComponent( const OFX::EPixelComponent component ) const 00292 { 00293 return std::find( _supportedComponents.begin(), _supportedComponents.end(), component ) != _supportedComponents.end(); 00294 } 00295 bool supportsBitDepth( const OFX::EBitDepth bitDepth ) const 00296 { 00297 return std::find( _supportedPixelDepths.begin(), _supportedPixelDepths.end(), bitDepth ) != _supportedPixelDepths.end(); 00298 } 00299 bool supportsContext( const OFX::EContext context ) const 00300 { 00301 return std::find( _supportedContexts.begin(), _supportedContexts.end(), context ) != _supportedContexts.end(); 00302 } 00303 00304 /** @return the pixel depth used by host application, if it doesn't support multiple clip depth. */ 00305 EBitDepth getPixelDepth() const 00306 { 00307 if( _supportedPixelDepths.size() == 1 ) 00308 { 00309 return _supportedPixelDepths[0]; 00310 } 00311 else 00312 { 00313 OFXS_COUT_WARNING("The host doesn't support multiple clip depths, but doesn't define supported pixel depth. (size: " << _supportedPixelDepths.size() << ")" ); 00314 return eBitDepthFloat; 00315 } 00316 } 00317 }; 00318 00319 /// retrieve the host description 00320 ImageEffectHostDescription* getImageEffectHostDescription(); 00321 00322 //////////////////////////////////////////////////////////////////////////////// 00323 /** @brief Wraps up a clip */ 00324 class ClipDescriptor 00325 { 00326 protected: 00327 mDeclareProtectedAssignAndCC( ClipDescriptor ); 00328 ClipDescriptor( void ) { assert( false ); } 00329 00330 protected: 00331 /** @brief name of the clip */ 00332 std::string _clipName; 00333 00334 /** @brief properties for this clip */ 00335 PropertySet _clipProps; 00336 00337 protected: 00338 /** @brief hidden constructor */ 00339 ClipDescriptor( const std::string& name, OfxPropertySetHandle props ); 00340 00341 friend class ImageEffectDescriptor; 00342 00343 public: 00344 const PropertySet& getPropertySet() const { return _clipProps; } 00345 00346 PropertySet& getPropertySet() { return _clipProps; } 00347 00348 /** @brief set the label properties */ 00349 void setLabels( const std::string& label, const std::string& shortLabel, const std::string& longLabel ); 00350 void setLabel( const std::string& label ) { setLabels( label, label, label ); } 00351 00352 /** @brief set how fielded images are extracted from the clip defaults to eFieldExtractDoubled */ 00353 void setFieldExtraction( EFieldExtraction v ); 00354 00355 /** @brief set which components are supported, defaults to none set, this must be called at least once! */ 00356 void addSupportedComponent( EPixelComponent v ); 00357 00358 /** @brief set which components are supported. This version adds by the raw C-string label, allowing you to add 00359 * custom component types */ 00360 void addSupportedComponent( const std::string& comp ); 00361 00362 /** @brief say whether we are going to do random temporal access on this clip, defaults to false */ 00363 void setTemporalClipAccess( bool v ); 00364 00365 /** @brief say whether if the clip is optional, defaults to false */ 00366 void setOptional( bool v ); 00367 00368 /** @brief say whether this clip supports tiling, defaults to true */ 00369 void setSupportsTiles( bool v ); 00370 00371 /** @brief say whether this clip is a 'mask', so the host can know to replace with a roto or similar, defaults to false */ 00372 void setIsMask( bool v ); 00373 }; 00374 00375 //////////////////////////////////////////////////////////////////////////////// 00376 /** @brief Wraps up an effect descriptor, used in the describe actions */ 00377 class ImageEffectDescriptor : public ParamSetDescriptor 00378 { 00379 protected: 00380 mDeclareProtectedAssignAndCC( ImageEffectDescriptor ); 00381 ImageEffectDescriptor( void ) { assert( false ); } 00382 00383 protected: 00384 /** @brief The effect handle */ 00385 OfxImageEffectHandle _effectHandle; 00386 00387 /** @brief properties for this clip */ 00388 PropertySet _effectProps; 00389 00390 /** @brief Set of all previously defined parameters, defined on demand */ 00391 std::map<std::string, ClipDescriptor*> _definedClips; 00392 00393 /** @brief Set of strings for clip preferences action (stored in here so the array persists and can be used in a property name)*/ 00394 std::map<std::string, std::string> _clipComponentsPropNames; 00395 std::map<std::string, std::string> _clipDepthPropNames; 00396 std::map<std::string, std::string> _clipPARPropNames; 00397 std::map<std::string, std::string> _clipROIPropNames; 00398 std::map<std::string, std::string> _clipFrameRangePropNames; 00399 00400 std::auto_ptr<EffectInteractWrap> _overlayDescriptor; 00401 00402 public: 00403 /** @brief ctor */ 00404 ImageEffectDescriptor( OfxImageEffectHandle handle ); 00405 00406 /** @brief dtor */ 00407 ~ImageEffectDescriptor(); 00408 00409 const PropertySet& getPropertySet() const { return _effectProps; } 00410 00411 PropertySet& getPropertySet() { return _effectProps; } 00412 00413 OfxImageEffectHandle getImageEffectHandle() { return _effectHandle; } 00414 00415 /** @brief, set the label properties in a plugin */ 00416 void setLabels( const std::string& label, const std::string& shortLabel, const std::string& longLabel ); 00417 void setLabel( const std::string& label ) { setLabels(label, label, label); } 00418 00419 void setDescription( const std::string& description ); 00420 00421 /** @brief Set the plugin grouping, defaults to "" */ 00422 void setPluginGrouping( const std::string& group ); 00423 00424 /** @brief Add a context to those supported, defaults to none, must be called at least once */ 00425 void addSupportedContext( EContext v ); 00426 00427 /** @brief Add a pixel depth to those supported, defaults to none, must be called at least once */ 00428 void addSupportedBitDepth( EBitDepth v ); 00429 00430 /** @brief Add a file extension to those supported, defaults to none */ 00431 void addSupportedExtension( const std::string& extension ); 00432 void addSupportedExtensions( const std::vector<std::string>& extensions ); 00433 00434 /** @brief Is the plugin single instance only ? defaults to false */ 00435 void setSingleInstance( bool v ); 00436 00437 /** @brief Does the plugin expect the host to perform per frame SMP threading defaults to true */ 00438 void setHostFrameThreading( bool v ); 00439 00440 /** @brief Does the plugin support multi resolution images, defaults to true */ 00441 void setSupportsMultiResolution( bool v ); 00442 00443 /** @brief Does the plugin support image tiling, defaults to true */ 00444 void setSupportsTiles( bool v ); 00445 00446 /** @brief Does the plugin perform temporal clip access, defaults to false */ 00447 void setTemporalClipAccess( bool v ); 00448 00449 /** @brief Does the plugin want to have render called twice per frame in all circumanstances for fielded images ? defaults to true */ 00450 void setRenderTwiceAlways( bool v ); 00451 00452 /** @brief Does the plugin support inputs and output clips of differing depths, defaults to false */ 00453 void setSupportsMultipleClipDepths( bool v ); 00454 00455 /** @brief Does the plugin support inputs and output clips of pixel aspect ratios, defaults to false */ 00456 void setSupportsMultipleClipPARs( bool v ); 00457 00458 /** @brief How thread safe is the plugin, defaults to eRenderInstanceSafe */ 00459 void setRenderThreadSafety( ERenderSafety v ); 00460 00461 /** @brief If the slave param changes the clip preferences need to be re-evaluated */ 00462 void addClipPreferencesSlaveParam( ParamDescriptor& p ); 00463 00464 /** @brief Create a clip, only callable from describe in context 00465 * 00466 * The returned clip \em must not be deleted by the client code. This is all managed by the ImageEffectDescriptor itself. 00467 */ 00468 ClipDescriptor* defineClip( const std::string& name ); 00469 00470 /** @brief Access to the string maps needed for runtime properties. Because the char array must persist after the call, 00471 * we need these to be stored in the descriptor, which is only deleted on unload.*/ 00472 00473 const std::map<std::string, std::string>& getClipComponentPropNames() const { return _clipComponentsPropNames; } 00474 const std::map<std::string, std::string>& getClipDepthPropNames() const { return _clipDepthPropNames; } 00475 const std::map<std::string, std::string>& getClipPARPropNames() const { return _clipPARPropNames; } 00476 const std::map<std::string, std::string>& getClipROIPropNames() const { return _clipROIPropNames; } 00477 const std::map<std::string, std::string>& getClipFrameRangePropNames() const { return _clipFrameRangePropNames; } 00478 00479 /** @brief override this to create an interact for the effect */ 00480 virtual void setOverlayInteractDescriptor(EffectInteractWrap* desc); 00481 }; 00482 00483 //////////////////////////////////////////////////////////////////////////////// 00484 /** @brief Wraps up an image */ 00485 class Image 00486 { 00487 protected: 00488 /** @brief the handle that holds this image */ 00489 PropertySet _imageProps; 00490 00491 /** @brief friend so we get access to ctor */ 00492 friend class Clip; 00493 00494 void* _pixelData; /**< @brief the base address of the image */ 00495 EPixelComponent _pixelComponents; /**< @brief get the components in the image */ 00496 int _rowDistanceBytes; /**< @brief the number of bytes per scanline */ 00497 00498 int _pixelBytes; /**< @brief the number of bytes per pixel */ 00499 EBitDepth _pixelDepth; /**< @brief get the pixel depth */ 00500 EPreMultiplication _preMultiplication; /**< @brief premultiplication on the image */ 00501 OfxRectI _regionOfDefinition; /**< @brief the RoD in pixel coordinates, this may be more or less than the bounds! */ 00502 OfxRectI _bounds; /**< @brief the bounds on the pixel data */ 00503 double _pixelAspectRatio; /**< @brief the pixel aspect ratio */ 00504 EField _field; /**< @brief which field this represents */ 00505 std::string _uniqueID; /**< @brief the unique ID of this image */ 00506 OfxPointD _renderScale; /**< @brief any scaling factor applied to the image */ 00507 00508 public: 00509 /** @brief ctor */ 00510 Image( OfxPropertySetHandle props ); 00511 00512 /** @brief dtor */ 00513 virtual ~Image(); 00514 00515 const PropertySet& getPropertySet() const { return _imageProps; } 00516 00517 PropertySet& getPropertySet() { return _imageProps; } 00518 00519 /** @brief get the pixel depth */ 00520 EBitDepth getPixelDepth() const { return _pixelDepth; } 00521 00522 /** @brief get the components in the image */ 00523 EPixelComponent getPixelComponents() const { return _pixelComponents; } 00524 00525 /** @brief get the string representing the pixel components */ 00526 std::string getPixelComponentsProperty() const { return _imageProps.propGetString( kOfxImageEffectPropComponents ); } 00527 00528 /** @brief premultiplication on the image */ 00529 EPreMultiplication getPreMultiplication() const { return _preMultiplication; } 00530 00531 /** @brief get the scale factor that has been applied to this image */ 00532 OfxPointD getRenderScale() const { return _renderScale; } 00533 00534 /** @brief get the scale factor that has been applied to this image */ 00535 double getPixelAspectRatio() const { return _pixelAspectRatio; } 00536 00537 /** @brief get the pixel data for this image */ 00538 void* getPixelData() const { return _pixelData; } 00539 00540 /** @brief get the region of definition (in pixel coordinates) of this image */ 00541 OfxRectI getRegionOfDefinition() const { return _regionOfDefinition; } 00542 00543 /** @brief get the bounds on the image data (in pixel coordinates) of this image */ 00544 OfxRectI getBounds() const { return _bounds; } 00545 00546 OfxPointI getBoundsSize() const { const OfxPointI res = { _bounds.x2 - _bounds.x1, _bounds.y2 - _bounds.y1 }; return res; } 00547 00548 std::size_t getPixelBytes() const; 00549 00550 /** @brief get the distance between 2 rows in bytes, may be negative */ 00551 int getRowDistanceBytes() const { return _rowDistanceBytes; } 00552 00553 /** @brief get the data row size in bytes, by definition >= 0 */ 00554 std::size_t getBoundsRowDataBytes() const; 00555 00556 std::size_t getBoundsNbPixels() const; 00557 00558 std::size_t getBoundsImageDataBytes() const; 00559 00560 bool isLinearBuffer() const { return (int)(getBoundsRowDataBytes()) == getRowDistanceBytes(); } 00561 00562 /** @brief get the fielding of this image */ 00563 EField getField() const { return _field; } 00564 00565 /** @brief the unique ID of this image */ 00566 std::string getUniqueIdentifier() const { return _uniqueID; } 00567 00568 /** @brief return a pixel pointer 00569 * 00570 * x and y are in pixel coordinates 00571 * 00572 * If the components are custom, then this will return NULL as the support code 00573 * can't know the pixel size to do the work. 00574 */ 00575 void* getPixelAddress( int x, int y ); 00576 }; 00577 00578 //////////////////////////////////////////////////////////////////////////////// 00579 /** @brief Wraps up a clip instance */ 00580 class Clip 00581 { 00582 protected: 00583 mDeclareProtectedAssignAndCC( Clip ); 00584 00585 /** @brief name of the clip */ 00586 std::string _clipName; 00587 00588 /** @brief properties for this clip */ 00589 PropertySet _clipProps; 00590 00591 /** @brief handle for this clip */ 00592 OfxImageClipHandle _clipHandle; 00593 00594 /** @brief effect instance that owns this clip */ 00595 ImageEffect* _effect; 00596 00597 /** @brief hidden constructor */ 00598 Clip( ImageEffect* effect, const std::string& name, OfxImageClipHandle handle, OfxPropertySetHandle props ); 00599 00600 /** @brief so one can be made */ 00601 friend class ImageEffect; 00602 00603 public: 00604 /// get the underlying property set on this clip 00605 const PropertySet& getPropertySet() const { return _clipProps; } 00606 00607 /// get the underlying property set on this clip 00608 PropertySet& getPropertySet() { return _clipProps; } 00609 00610 /// get the OFX clip handle 00611 OfxImageClipHandle getHandle() { return _clipHandle; } 00612 00613 /** @brief get the name */ 00614 const std::string& name( void ) const { return _clipName; } 00615 00616 /** @brief fetch the labels */ 00617 void getLabels( std::string& label, std::string& shortLabel, std::string& longLabel ) const; 00618 00619 /** @brief what is the pixel depth images will be given to us as */ 00620 EBitDepth getPixelDepth( void ) const; 00621 00622 /** @brief what is the components images will be given to us as */ 00623 EPixelComponent getPixelComponents( void ) const; 00624 00625 /** @brief get the string representing the pixel components */ 00626 std::string getPixelComponentsProperty( void ) const { return _clipProps.propGetString( kOfxImageEffectPropComponents ); } 00627 00628 /** @brief what is the actual pixel depth of the clip */ 00629 EBitDepth getUnmappedPixelDepth( void ) const; 00630 00631 /** @brief what is the component type of the clip */ 00632 EPixelComponent getUnmappedPixelComponents( void ) const; 00633 00634 /** @brief get the string representing the pixel components */ 00635 std::string getUnmappedPixelComponentsProperty( void ) const { return _clipProps.propGetString( kOfxImageClipPropUnmappedComponents ); } 00636 00637 /** @brief get the components in the image */ 00638 EPreMultiplication getPreMultiplication( void ) const; 00639 00640 /** @brief which spatial field comes first temporally */ 00641 EField getFieldOrder( void ) const; 00642 00643 /** @brief is the clip connected */ 00644 bool isConnected( void ) const; 00645 00646 /** @brief can the clip be continuously sampled */ 00647 bool hasContinuousSamples( void ) const; 00648 00649 /** @brief get the scale factor that has been applied to this clip */ 00650 double getPixelAspectRatio( void ) const; 00651 00652 /** @brief get the frame rate, in frames per second on this clip, after any clip preferences have been applied */ 00653 double getFrameRate( void ) const; 00654 00655 /** @brief return the range of frames over which this clip has images, after any clip preferences have been applied */ 00656 OfxRangeD getFrameRange( void ) const; 00657 00658 /** @brief get the frame rate, in frames per second on this clip, before any clip preferences have been applied */ 00659 double getUnmappedFrameRate( void ) const; 00660 00661 /** @brief return the range of frames over which this clip has images, before any clip preferences have been applied */ 00662 OfxRangeD getUnmappedFrameRange( void ) const; 00663 00664 /** @brief get the RoD for this clip in the cannonical coordinate system */ 00665 OfxRectD getCanonicalRod( const OfxTime t ) const; 00666 OfxRectD getCanonicalRod( const OfxTime t, const OfxPointD& renderScale ) const; 00667 OfxPointD getCanonicalRodSize( const OfxTime t ) const 00668 { 00669 OfxRectD r = getCanonicalRod(t); 00670 OfxPointD p = {r.x2-r.x1, r.y2-r.y1}; 00671 return p; 00672 } 00673 OfxPointD getCanonicalRodSize( const OfxTime t, const OfxPointD& renderScale ) const 00674 { 00675 OfxPointD p = getCanonicalRodSize(t); 00676 p.x *= renderScale.x; 00677 p.y *= renderScale.y; 00678 return p; 00679 } 00680 00681 /** @brief get the RoD for this clip in pixel space */ 00682 OfxRectI getPixelRod( const OfxTime t ) const; 00683 OfxRectI getPixelRod( const OfxTime t, const OfxPointD& renderScale ) const; 00684 OfxPointI getPixelRodSize( const OfxTime t ) const 00685 { 00686 OfxRectI r = getPixelRod(t); 00687 OfxPointI p = {r.x2-r.x1, r.y2-r.y1}; 00688 return p; 00689 } 00690 OfxPointI getPixelRodSize( const OfxTime t, const OfxPointD& renderScale ) const 00691 { 00692 OfxPointI p = getPixelRodSize(t); 00693 p.x = static_cast<int>( p.x * renderScale.x ); 00694 p.y = static_cast<int>( p.y * renderScale.y ); 00695 return p; 00696 } 00697 00698 /** @brief fetch an image 00699 * 00700 * When finished with, the client code must delete the image. 00701 * 00702 * If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. 00703 */ 00704 Image* fetchImage( OfxTime t ); 00705 00706 /** @brief fetch an image, with a specific region in cannonical coordinates 00707 * 00708 * When finished with, the client code must delete the image. 00709 * 00710 * If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. 00711 */ 00712 Image* fetchImage( OfxTime t, OfxRectD bounds ); 00713 00714 /** @brief fetch an image, with a specific region in cannonical coordinates 00715 * 00716 * When finished with, the client code must delete the image. 00717 * 00718 * If the same image is fetched twice, it must be deleted in each case, they will not be the same pointer. 00719 */ 00720 Image* fetchImage( OfxTime t, OfxRectD* bounds ) 00721 { 00722 if( bounds ) 00723 return fetchImage( t, *bounds ); 00724 else 00725 return fetchImage( t ); 00726 } 00727 00728 }; 00729 00730 //////////////////////////////////////////////////////////////////////////////// 00731 /** @brief Class that skins image memory allocation */ 00732 class ImageMemory 00733 { 00734 protected: 00735 OfxImageMemoryHandle _handle; 00736 bool _alloc; 00737 00738 public: 00739 ImageMemory(); 00740 ImageMemory( size_t nBytes, ImageEffect* associatedEffect = 0 ); 00741 ~ImageMemory(); 00742 00743 void alloc( size_t nBytes, ImageEffect* associatedEffect ); 00744 00745 /** @brief lock the memory and return a pointer to it */ 00746 void* lock( void ); 00747 00748 /** @brief unlock the memory */ 00749 void unlock( void ); 00750 }; 00751 00752 //////////////////////////////////////////////////////////////////////////////// 00753 /** @brief POD struct to pass rendering arguments into @ref ImageEffect::render and @ref OFX::ImageEffect::isIdentity */ 00754 struct RenderArguments 00755 { 00756 double time; 00757 OfxPointD renderScale; 00758 OfxRectI renderWindow; 00759 EField fieldToRender; 00760 }; 00761 00762 /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::render */ 00763 struct BeginSequenceRenderArguments 00764 { 00765 OfxRangeD frameRange; 00766 double frameStep; 00767 bool isInteractive; 00768 OfxPointD renderScale; 00769 }; 00770 00771 /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::beginSequenceRender */ 00772 struct EndSequenceRenderArguments 00773 { 00774 bool isInteractive; 00775 OfxPointD renderScale; 00776 }; 00777 00778 /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getRegionOfDefinition */ 00779 struct RegionOfDefinitionArguments 00780 { 00781 double time; 00782 OfxPointD renderScale; 00783 }; 00784 00785 /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getRegionsOfInterest */ 00786 struct RegionsOfInterestArguments 00787 { 00788 double time; 00789 OfxPointD renderScale; 00790 OfxRectD regionOfInterest; 00791 }; 00792 00793 /** @brief Class used to set regions of interest on a clip in @ref OFX::ImageEffect::getRegionsOfInterest 00794 * 00795 * This is a base class, the actual class is private and you don't need to see the glue involved. 00796 */ 00797 class RegionOfInterestSetter 00798 { 00799 public: 00800 /** @brief function to set the RoI of a clip, pass in the clip to set the RoI of, and the RoI itself */ 00801 virtual void setRegionOfInterest( const Clip& clip, const OfxRectD& RoI ) = 0; 00802 virtual ~RegionOfInterestSetter() = 0; 00803 }; 00804 00805 /** @brief POD struct to pass arguments into @ref OFX::ImageEffect::getFramesNeeded */ 00806 struct FramesNeededArguments 00807 { 00808 double time; 00809 }; 00810 00811 /** @brief Class used to set the frames needed to render a single frame of a clip in @ref OFX::ImageEffect::getFramesNeeded 00812 * 00813 * This is a base class, the actual class is private and you don't need to see the glue involved. 00814 */ 00815 class FramesNeededSetter 00816 { 00817 public: 00818 /** @brief function to set the frames needed on a clip, the range is min <= time <= max */ 00819 virtual void setFramesNeeded( const Clip& clip, const OfxRangeD& range ) = 0; 00820 virtual ~FramesNeededSetter() = 0; 00821 }; 00822 00823 /** @brief Class used to set the clip preferences of the effect. 00824 */ 00825 class ClipPreferencesSetter 00826 { 00827 OFX::PropertySet outArgs_; 00828 bool doneSomething_; 00829 typedef std::map<std::string, std::string> StringStringMap; 00830 const StringStringMap& clipDepthPropNames_; 00831 const StringStringMap& clipComponentPropNames_; 00832 const StringStringMap& clipPARPropNames_; 00833 const std::string& extractValueForName( const StringStringMap& m, const std::string& name ); 00834 00835 public: 00836 ImageEffectHostDescription* _imageEffectHostDescription; 00837 00838 public: 00839 ClipPreferencesSetter( OFX::PropertySet props, 00840 const StringStringMap& depthPropNames, 00841 const StringStringMap& componentPropNames, 00842 const StringStringMap& PARPropNames ) 00843 : outArgs_( props ), 00844 doneSomething_( false ), 00845 clipDepthPropNames_( depthPropNames ), 00846 clipComponentPropNames_( componentPropNames ), 00847 clipPARPropNames_( PARPropNames ) 00848 { 00849 _imageEffectHostDescription = getImageEffectHostDescription(); 00850 } 00851 00852 bool didSomething( void ) const { return doneSomething_; } 00853 00854 /** @brief, force the host to set a clip's mapped component type to be \em comps. 00855 * 00856 * Only callable on non optional clips in all contexts. Must set comps to be one of the types the effect says it supports on the given clip. 00857 * 00858 * See the OFX API documentation for the default values of this. 00859 */ 00860 void setClipComponents( Clip& clip, EPixelComponent comps ); 00861 00862 /** @brief, force the host to set a clip's mapped bit depth be \em bitDepth 00863 * 00864 * Only callable if the OFX::ImageEffectHostDescription::supportsMultipleClipDepths is true. 00865 * 00866 * See the OFX API documentation for the default values of this. 00867 */ 00868 void setClipBitDepth( Clip& clip, EBitDepth bitDepth ); 00869 00870 /** @brief, force the host to set a clip's mapped Pixel Aspect Ratio to be \em PAR 00871 * 00872 * Only callable if the OFX::ImageEffectHostDescription::supportsMultipleClipPARs is true. 00873 * 00874 * Default is up to the host, generally based on the input clips. 00875 * 00876 * Not supported by most host applications. 00877 */ 00878 void setPixelAspectRatio( Clip& clip, double PAR ); 00879 00880 /** @brief Allows an effect to change the output frame rate 00881 * 00882 * Only callable if OFX::ImageEffectHostDescription::supportsSetableFrameRate is true. 00883 * 00884 * Default is controlled by the host, typically the framerate of the input clips. 00885 */ 00886 void setOutputFrameRate( double v ); 00887 00888 /** @brief Set the premultiplication state of the output clip. 00889 * 00890 * Defaults to the premultiplication state of ??? 00891 */ 00892 void setOutputPremultiplication( EPreMultiplication v ); 00893 00894 /** @brief Set whether the effect can be continously sampled. 00895 * 00896 * Defaults to false. 00897 */ 00898 void setOutputHasContinousSamples( bool v ); 00899 00900 /** @brief Sets whether the effect will produce different images in all frames, even if the no params or input images are varying (eg: a noise generator). 00901 * 00902 * Defaults to false. 00903 */ 00904 void setOutputFrameVarying( bool v ); 00905 00906 /** @brief Sets the output fielding 00907 * 00908 * Default is host dependent, must be one of 00909 * - eFieldNone, 00910 * - eFieldLower, 00911 * - eFieldUpper 00912 */ 00913 void setOutputFielding( EField v ); 00914 }; 00915 00916 static const OfxPointD kNoRenderScale = { 1.0, 1.0 }; 00917 00918 /** @brief POD data structure passing in the instance changed args */ 00919 struct InstanceChangedArgs 00920 { 00921 InstanceChangedArgs( const OfxTime time = 0.0, const OfxPointD renderScale = kNoRenderScale, const InstanceChangeReason reason = OFX::eChangePluginEdit ) 00922 : time(time) 00923 , renderScale( renderScale ) 00924 , reason( reason ) 00925 {} 00926 00927 OfxTime time; //< time of the change 00928 OfxPointD renderScale; ///< the renderscale on the instance 00929 InstanceChangeReason reason; ///< why did it change 00930 }; 00931 00932 00933 //////////////////////////////////////////////////////////////////////////////// 00934 /** @brief Wraps up an effect instance, plugin implementations need to inherit from this */ 00935 class ImageEffect : public ParamSet 00936 { 00937 protected: 00938 mDeclareProtectedAssignAndCC( ImageEffect ); 00939 00940 private: 00941 /** @brief to get access to the effect handle without exposing it generally via a function */ 00942 friend class ImageMemory; 00943 00944 /** @brief The effect handle */ 00945 OfxImageEffectHandle _effectHandle; 00946 00947 /** @brief properties for this clip */ 00948 PropertySet _effectProps; 00949 00950 /** @brief the context of the effect */ 00951 EContext _context; 00952 00953 /** @brief Set of all previously defined parameters, defined on demand */ 00954 std::map<std::string, Clip*> _fetchedClips; 00955 00956 /** @brief the overlay interacts that are open on this image effect */ 00957 std::list<OverlayInteract*> _overlayInteracts; 00958 00959 /** @brief cached result of whether progress start succeeded. */ 00960 bool _progressStartSuccess; 00961 00962 public: 00963 /** @brief ctor */ 00964 ImageEffect( OfxImageEffectHandle handle ); 00965 00966 /** @brief dtor */ 00967 virtual ~ImageEffect(); 00968 00969 const PropertySet& getPropertySet() const { return _effectProps; } 00970 00971 PropertySet& getPropertySet() { return _effectProps; } 00972 00973 OfxImageEffectHandle getHandle( void ) const { return _effectHandle; } 00974 00975 /** @brief the context this effect was instantiate in */ 00976 EContext getContext( void ) const; 00977 00978 /** @brief size of the project */ 00979 OfxPointD getProjectSize( void ) const; 00980 00981 /** @brief origin of the project */ 00982 OfxPointD getProjectOffset( void ) const; 00983 00984 /** @brief extent of the project */ 00985 OfxPointD getProjectExtent( void ) const; 00986 00987 /** @brief pixel aspect ratio of the project */ 00988 double getProjectPixelAspectRatio( void ) const; 00989 00990 /** @brief how long does the effect last */ 00991 double getEffectDuration( void ) const; 00992 00993 /** @brief the frame rate of the project */ 00994 double getFrameRate( void ) const; 00995 00996 /** @brief is the instance currently being interacted with */ 00997 bool isInteractive( void ) const; 00998 00999 /** @brief set the instance to be sequentially renderred, this should have been part of clip preferences! */ 01000 void setSequentialRender( bool v ); 01001 01002 /** @brief Have we informed the host we want to be seqentially renderred ? */ 01003 bool getSequentialRender( void ) const; 01004 01005 OFX::Message::EMessageReply sendMessage( OFX::Message::EMessageType type, const std::string& id, const std::string& msg ); 01006 01007 /** @brief Fetch the named clip from this instance 01008 * 01009 * The returned clip \em must not be deleted by the client code. This is all managed by the ImageEffect itself. 01010 */ 01011 Clip* fetchClip( const std::string& name ); 01012 01013 CameraParam* fetchCameraParam( const std::string& name ); 01014 01015 /** @brief does the host want us to abort rendering? */ 01016 bool abort() const; 01017 01018 /** @brief adds a new interact to the set of interacts open on this effect */ 01019 void addOverlayInteract( OverlayInteract* interact ); 01020 01021 /** @brief removes an interact to the set of interacts open on this effect */ 01022 void removeOverlayInteract( OverlayInteract* interact ); 01023 01024 /** @brief force all overlays on this interact to be redrawn */ 01025 void redrawOverlays( void ); 01026 01027 //////////////////////////////////////////////////////////////////////////////// 01028 // these are actions that need to be overridden by a plugin that implements an effect host 01029 01030 /** @brief The purge caches action, a request for an instance to free up as much memory as possible in low memory situations */ 01031 virtual void purgeCaches( void ); 01032 01033 /** @brief The sync private data action, called when the effect needs to sync any private data to persistant parameters */ 01034 virtual void syncPrivateData( void ); 01035 01036 /** @brief client render function, this is one of the few that must be overridden */ 01037 virtual void render( const RenderArguments& args ) = 0; 01038 01039 /** @brief client begin sequence render function */ 01040 virtual void beginSequenceRender( const BeginSequenceRenderArguments& args ); 01041 01042 /** @brief client end sequence render function */ 01043 virtual void endSequenceRender( const EndSequenceRenderArguments& args ); 01044 01045 /** @brief client is identity function, returns the clip and time for the identity function 01046 * 01047 * If the effect would do no processing for the given param set and render arguments, then this 01048 * function should return true and set the \em identityClip pointer to point to the clip that is the identity 01049 * and \em identityTime to be the time at which to access the clip for the identity operation. 01050 */ 01051 virtual bool isIdentity( const RenderArguments& args, Clip*& identityClip, double& identityTime ); 01052 01053 /** @brief The get RoD action. 01054 * 01055 * If the effect wants change the rod from the default value (which is the union of RoD's of all input clips) 01056 * it should set the \em rod argument and return true. 01057 * 01058 * This is all in cannonical coordinates. 01059 */ 01060 virtual bool getRegionOfDefinition( const RegionOfDefinitionArguments& args, OfxRectD& rod ); 01061 01062 /** @brief the get region of interest action 01063 * 01064 * If the effect wants change its region of interest on any input clip from the default values (which is the same as the RoI in the arguments) 01065 * it should do so by calling the OFX::RegionOfInterestSetter::setRegionOfInterest function on the \em rois argument. 01066 * 01067 * Note, everything is in \em cannonical \em coordinates. 01068 */ 01069 virtual void getRegionsOfInterest( const RegionsOfInterestArguments& args, RegionOfInterestSetter& rois ); 01070 01071 /** @brief the get frames needed action 01072 * 01073 * If the effect wants change the frames needed on an input clip from the default values (which is the same as the frame to be renderred) 01074 * it should do so by calling the OFX::FramesNeededSetter::setFramesNeeded function on the \em frames argument. 01075 */ 01076 virtual void getFramesNeeded( const FramesNeededArguments& args, FramesNeededSetter& frames ); 01077 01078 /** @brief get the clip preferences */ 01079 virtual void getClipPreferences( ClipPreferencesSetter& clipPreferences ); 01080 01081 /** @brief the effect is about to be actively edited by a user, called when the first user interface is opened on an instance */ 01082 virtual void beginEdit( void ); 01083 01084 /** @brief the effect is no longer being edited by a user, called when the last user interface is closed on an instance */ 01085 virtual void endEdit( void ); 01086 01087 /** @brief the effect is about to have some values changed */ 01088 virtual void beginChanged( InstanceChangeReason reason ); 01089 01090 /** @brief called when a param has just had its value changed */ 01091 virtual void changedParam( const InstanceChangedArgs& args, const std::string& paramName ); 01092 01093 /** @brief called when a clip has just been changed in some way (a rewire maybe) */ 01094 virtual void changedClip( const InstanceChangedArgs& args, const std::string& clipName ); 01095 01096 /** @brief the effect has just had some values changed */ 01097 virtual void endChanged( InstanceChangeReason reason ); 01098 01099 /** @brief what is the time domain of this effect, valid only in the general context 01100 * 01101 * return true if range was set, otherwise the default (the union of the time domain of all input clips) is used 01102 */ 01103 virtual bool getTimeDomain( OfxRangeD& range ); 01104 01105 /// Start doing progress. 01106 void progressStart( const std::string& message ); 01107 01108 /// finish yer progress 01109 void progressEnd(); 01110 01111 /// set the progress to some level of completion, 01112 /// returns true if you should abandon processing, false to continue 01113 bool progressUpdate( const double t ); 01114 01115 /// get the current time on the timeline. This is not necessarily the same 01116 /// time as being passed to an action (eg render) 01117 double timeLineGetTime(); 01118 01119 /// set the timeline to a specific time 01120 void timeLineGotoTime( const double t ); 01121 01122 /// get the first and last times available on the effect's timeline 01123 void timeLineGetBounds( double& t1, double& t2 ); 01124 inline OfxRangeD timeLineGetBounds() { OfxRangeD range; timeLineGetBounds( range.min, range.max ); return range; } 01125 }; 01126 01127 //////////////////////////////////////////////////////////////////////////////// 01128 /** @brief The OFX::Plugin namespace. All the functions in here needs to be defined by each plugin that uses the support libs. 01129 */ 01130 namespace Plugin { 01131 /** @brief Plugin side function used to identify the plugin to the support library */ 01132 void getPluginID( OFX::PluginFactoryArray& id ); 01133 01134 /// If the client has defined its own exception type, allow it to catch it in the main function 01135 #ifdef OFX_CLIENT_EXCEPTION_TYPE 01136 OfxStatus catchException( OFX_CLIENT_EXCEPTION_TYPE& ex ); 01137 #endif 01138 }; 01139 01140 }; 01141 01142 // undeclare the protected assign and CC macro 01143 #undef mDeclareProtectedAssignAndCC 01144 01145 #endif