change: Switch to offical OpenFX Support. Still can't compile.

This commit is contained in:
Mike Solar
2025-09-03 21:14:56 +08:00
parent 7ff76427f9
commit b649b5e1bd
198 changed files with 57444 additions and 980 deletions
+96
View File
@@ -0,0 +1,96 @@
#ifndef OFX_BINARY_H
#define OFX_BINARY_H
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <string>
#include <iostream>
#if defined(WIN32) || defined(WIN64)
#define I386
#elif defined(__linux__) || defined(__FreeBSD__)
#define UNIX
#ifdef __i386__
#define I386
#elif defined(__amd64__)
#define AMD64
#else
#error cannot detect architecture
#endif
#elif defined( __APPLE__)
#define UNIX
#else
#error cannot detect operating system
#endif
#if defined(UNIX)
#include <dlfcn.h>
#elif defined (WINDOWS)
#include "windows.h"
#include <assert.h>
#endif
#include <sys/stat.h>
namespace OFX
{
/// class representing a DLL/Shared Object/etc
class Binary {
/// destruction will close the library and invalidate
/// any function pointers returned by lookupSymbol()
protected :
std::string _binaryPath;
bool _invalid;
#if defined(UNIX)
void *_dlHandle;
#elif defined (WINDOWS)
HINSTANCE _dlHandle;
#endif
time_t _time;
off_t _size;
int _users;
public :
/// create object representing the binary. will stat() it,
/// and this fails, will set binary to be invalid.
Binary(const std::string &binaryPath);
~Binary() { unload(); }
bool isLoaded() const { return _dlHandle != 0; }
/// is this binary invalid? (did the a stat() or load() on the file fail,
/// or are we missing a some of the symbols?
bool isInvalid() const { return _invalid; }
/// set invalid status (e.g. called by user if a mandatory symbol was missing)
void setInvalid(bool invalid) { _invalid = invalid; }
/// Last modification time of the file.
time_t getTime() const { return _time; }
/// Current size of the file.
off_t getSize() const { return _size; }
/// Path to the file.
const std::string &getBinaryPath() const { return _binaryPath; }
void ref();
void unref();
/// open the binary.
void load();
/// close the binary
void unload();
/// look up a symbol in the binary file and return it as a pointer.
/// returns null pointer if not found, or if the library is not loaded.
void *findSymbol(const std::string &symbol);
};
}
#endif
+499
View File
@@ -0,0 +1,499 @@
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#ifndef OFX_CLIP_H
#define OFX_CLIP_H
#include "ofxImageEffect.h"
#include "ofxhPropertySuite.h"
#include "ofxhUtilities.h"
namespace OFX {
namespace Host {
namespace ImageEffect {
// forward declarations
class Image;
class Instance;
# ifdef OFX_SUPPORTS_OPENGLRENDER
class Texture;
# endif
/// Base to both descriptor and instance it
/// is used to basically fetch common properties
/// by function name
class ClipBase {
protected :
Property::Set _properties;
public :
/// base ctor, for a descriptor
ClipBase();
virtual ~ClipBase() { }
/// ctor, when copy constructing an instance from a descripto
explicit ClipBase(const ClipBase &other);
/// name of the clip
const std::string &getName() const
{
return _properties.getStringProperty(kOfxPropName);
}
/// name of the clip
const std::string &getShortLabel() const;
/// name of the clip
const std::string &getLabel() const;
/// name of the clip
const std::string &getLongLabel() const;
/// return a std::vector of supported comp
const std::vector<std::string> &getSupportedComponents() const;
/// is the given component supported
bool isSupportedComponent(const std::string &comp) const;
/// does the clip do random temporal access
bool temporalAccess() const;
/// is the clip optional
bool isOptional() const;
/// is the clip a nominal 'mask' clip
bool isMask() const;
/// how does this clip like fielded images to be presented to it
const std::string &getFieldExtraction() const;
/// is the clip a nominal 'mask' clip
bool supportsTiles() const;
/// get property set, const version
const Property::Set &getProps() const;
/// get property set , non const version
Property::Set &getProps();
/// get a handle on the properties of the clip descriptor for the C api
OfxPropertySetHandle getPropHandle() const;
/// get a handle on the clip descriptor/instance for the C api
OfxImageClipHandle getHandle() const;
virtual bool verifyMagic() {
return true;
}
};
/// a clip descriptor
class ClipDescriptor : public ClipBase {
public:
/// constructor
ClipDescriptor(const std::string &name);
/// is the clip an output clip
bool isOutput() const {return getName() == kOfxImageEffectOutputClipName; }
};
/// a clip instance
class ClipInstance : public ClipBase
, protected Property::GetHook
, protected Property::NotifyHook {
protected:
ImageEffect::Instance* _effectInstance; ///< image effect instance
bool _isOutput; ///< are we the output clip
std::string _pixelDepth; ///< what is the bit depth we is at. Set during the clip prefernces action.
std::string _components; ///< what components do we have. Set during the clip prefernces action.
public:
ClipInstance(ImageEffect::Instance* effectInstance, ClipDescriptor& desc);
/// is the clip an output clip
bool isOutput() const {return _isOutput;}
/// notify override properties
virtual void notify(const std::string &name, bool isSingle, int indexOrN);
/// get hook override
virtual void reset(const std::string &name);
// get the virtuals for viewport size, pixel scale, background colour
virtual double getDoubleProperty(const std::string &name, int index) const;
// get the virtuals for viewport size, pixel scale, background colour
virtual void getDoublePropertyN(const std::string &name, double *values, int count) const;
// get the virtuals for viewport size, pixel scale, background colour
virtual int getIntProperty(const std::string &name, int index) const;
// get the virtuals for viewport size, pixel scale, background colour
virtual void getIntPropertyN(const std::string &name, int *values, int count) const;
// get the virtuals for viewport size, pixel scale, background colour
virtual const std::string &getStringProperty(const std::string &name, int index) const;
// fetch multiple values in a multi-dimension property
virtual void getStringPropertyN(const std::string &name, const char** values, int count) const;
// get hook virtuals
virtual int getDimension(const std::string &name) const;
// instance changed action
OfxStatus instanceChangedAction(const std::string &why,
OfxTime time,
OfxPointD renderScale);
// properties of an instance that are live
/// Pixel Depth - fetch depth of all chromatic component in this clip
///
/// kOfxBitDepthNone (implying a clip is unconnected, not valid for an image)
/// kOfxBitDepthByte
/// kOfxBitDepthShort
/// kOfxBitDepthHalf
/// kOfxBitDepthFloat
const std::string &getPixelDepth() const
{
return _pixelDepth;
}
/// set the current pixel depth
/// called by clip preferences action
void setPixelDepth(const std::string &s)
{
_pixelDepth = s;
}
/// Components that can be fetched from this clip -
///
/// kOfxImageComponentNone (implying a clip is unconnected, not valid for an image)
/// kOfxImageComponentRGBA
/// kOfxImageComponentRGB
/// kOfxImageComponentAlpha
/// and any custom ones you may think of
virtual const std::string &getComponents() const;
/// set the current set of components
/// called by clip preferences action
virtual void setComponents(const std::string &s);
/// Get the Raw Unmapped Pixel Depth from the host for chromatic planes
///
/// \returns
/// - kOfxBitDepthNone (implying a clip is unconnected image)
/// - kOfxBitDepthByte
/// - kOfxBitDepthShort
/// - kOfxBitDepthHalf
/// - kOfxBitDepthFloat
virtual const std::string &getUnmappedBitDepth() const = 0;
/// Get the Raw Unmapped Components from the host
///
/// \returns
/// - kOfxImageComponentNone (implying a clip is unconnected, not valid for an image)
/// - kOfxImageComponentRGBA
/// - kOfxImageComponentAlpha
virtual const std::string &getUnmappedComponents() const = 0;
// PreMultiplication -
//
// kOfxImageOpaque - the image is opaque and so has no premultiplication state
// kOfxImagePreMultiplied - the image is premultiplied by it's alpha
// kOfxImageUnPreMultiplied - the image is unpremultiplied
virtual const std::string &getPremult() const = 0;
// Pixel Aspect Ratio -
//
// The pixel aspect ratio of a clip or image.
virtual double getAspectRatio() const = 0;
// Frame Rate -
//
// The frame rate of a clip or instance's project.
virtual double getFrameRate() const = 0;
// Frame Range (startFrame, endFrame) -
//
// The frame range over which a clip has images.
virtual void getFrameRange(double &startFrame, double &endFrame) const = 0;
/// Field Order - Which spatial field occurs temporally first in a frame.
/// \returns
/// - kOfxImageFieldNone - the clip material is unfielded
/// - kOfxImageFieldLower - the clip material is fielded, with image rows 0,2,4.... occuring first in a frame
/// - kOfxImageFieldUpper - the clip material is fielded, with image rows line 1,3,5.... occuring first in a frame
virtual const std::string &getFieldOrder() const = 0;
// Connected -
//
// Says whether the clip is actually connected at the moment.
virtual bool getConnected() const = 0;
// Unmapped Frame Rate -
//
// The unmapped frame rate.
virtual double getUnmappedFrameRate() const = 0;
// Unmapped Frame Range -
//
// The unmapped frame range over which an output clip has images.
virtual void getUnmappedFrameRange(double &unmappedStartFrame, double &unmappedEndFrame) const = 0;
// Continuous Samples -
//
// 0 if the images can only be sampled at discreet times (eg: the clip is a sequence of frames),
// 1 if the images can only be sampled continuously (eg: the clip is infact an animating roto spline and can be rendered anywhen).
virtual bool getContinuousSamples() const = 0;
/// override this to fill in the image at the given time.
/// The bounds of the image on the image plane should be
/// 'appropriate', typically the value returned in getRegionsOfInterest
/// on the effect instance. Outside a render call, the optionalBounds should
/// be 'appropriate' for the.
/// If bounds is not null, fetch the indicated section of the canonical image plane.
virtual ImageEffect::Image* getImage(OfxTime time, const OfxRectD *optionalBounds) = 0;
# ifdef OFX_SUPPORTS_OPENGLRENDER
/// override this to fill in the OpenGL texture at the given time.
/// The bounds of the image on the image plane should be
/// 'appropriate', typically the value returned in getRegionsOfInterest
/// on the effect instance. Outside a render call, the optionalBounds should
/// be 'appropriate' for the.
/// If bounds is not null, fetch the indicated section of the canonical image plane.
virtual ImageEffect::Texture* loadTexture(OfxTime time, const char *format, const OfxRectD *optionalBounds) = 0;
# endif
/// override this to return the rod on the clip
virtual OfxRectD getRegionOfDefinition(OfxTime time) const = 0;
/// given the colour component, find the nearest set of supported colour components
/// override this for extra wierd custom component depths
virtual const std::string &findSupportedComp(const std::string &s) const;
};
/// instance of an image inside an image effect
class ImageBase : public Property::Set {
protected :
/// called during ctors to get bits from the clip props into ours
void getClipBits(ClipInstance& instance);
int _referenceCount; ///< reference count on this image
public:
// default constructor
virtual ~ImageBase();
/// basic ctor, makes empty property set but sets not value
ImageBase();
/// construct from a clip instance, but leave the
/// filling it to the calling code via the propery set
explicit ImageBase(ClipInstance& instance);
// Render Scale (renderScaleX,renderScaleY) -
//
// The proxy render scale currently being applied.
// ------
// Bounds (bx1,by1,bx2,by2) -
//
// The bounds of an image's pixels. The bounds, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// ROD (rodx1,rody1,rodx2,rody2) -
//
// The full region of definition. The ROD, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// Row Bytes -
//
// The number of bytes in a row of an image.
// ------
// Field -
//
// kOfxImageFieldNone - the image is an unfielded frame
// kOfxImageFieldBoth - the image is fielded and contains both interlaced fields
// kOfxImageFieldLower - the image is fielded and contains a single field, being the lower field (rows 0,2,4...)
// kOfxImageFieldUpper - the image is fielded and contains a single field, being the upper field (rows 1,3,5...)
// ------
// Unique Identifier -
//
// Uniquely labels an image. This is host set and allows a plug-in to differentiate between images. This is
// especially useful if a plugin caches analysed information about the image (for example motion vectors). The
// plugin can label the cached information with this identifier. If a user connects a different clip to the
// analysed input, or the image has changed in some way then the plugin can detect this via an identifier change
// and re-evaluate the cached information.
// construction based on clip instance
ImageBase(ClipInstance& instance, // construct from clip instance taking pixel depth, components, pre mult and aspect ratio
double renderScaleX,
double renderScaleY,
const OfxRectI &bounds,
const OfxRectI &rod,
int rowBytes,
std::string field,
std::string uniqueIdentifier);
// OfxImageClipHandle getHandle();
OfxPropertySetHandle getPropHandle() const { return Property::Set::getHandle(); }
/// get the bounds of the pixels in memory
OfxRectI getBounds() const;
/// get the full region of this image
OfxRectI getROD() const;
/// release the reference count, which, if zero, deletes this
void releaseReference();
/// add a reference to this image
void addReference() {_referenceCount++;}
};
/// instance of an image inside an image effect
class Image : public ImageBase {
public:
// default constructor
virtual ~Image();
/// basic ctor, makes empty property set but sets not value
Image();
/// construct from a clip instance, but leave the
/// filling it to the calling code via the propery set
explicit Image(ClipInstance& instance);
// Render Scale (renderScaleX,renderScaleY) -
//
// The proxy render scale currently being applied.
// ------
// Data -
//
// The pixel data pointer of an image.
// ------
// Bounds (bx1,by1,bx2,by2) -
//
// The bounds of an image's pixels. The bounds, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// ROD (rodx1,rody1,rodx2,rody2) -
//
// The full region of definition. The ROD, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// Row Bytes -
//
// The number of bytes in a row of an image.
// ------
// Field -
//
// kOfxImageFieldNone - the image is an unfielded frame
// kOfxImageFieldBoth - the image is fielded and contains both interlaced fields
// kOfxImageFieldLower - the image is fielded and contains a single field, being the lower field (rows 0,2,4...)
// kOfxImageFieldUpper - the image is fielded and contains a single field, being the upper field (rows 1,3,5...)
// ------
// Unique Identifier -
//
// Uniquely labels an image. This is host set and allows a plug-in to differentiate between images. This is
// especially useful if a plugin caches analysed information about the image (for example motion vectors). The
// plugin can label the cached information with this identifier. If a user connects a different clip to the
// analysed input, or the image has changed in some way then the plugin can detect this via an identifier change
// and re-evaluate the cached information.
// construction based on clip instance
Image(ClipInstance& instance, // construct from clip instance taking pixel depth, components, pre mult and aspect ratio
double renderScaleX,
double renderScaleY,
void* data,
const OfxRectI &bounds,
const OfxRectI &rod,
int rowBytes,
std::string field,
std::string uniqueIdentifier);
};
# ifdef OFX_SUPPORTS_OPENGLRENDER
/// instance of an OpenGL texture inside an image effect
class Texture : public ImageBase {
public:
// default constructor
virtual ~Texture();
/// basic ctor, makes empty property set but sets not value
Texture();
/// construct from a clip instance, but leave the
/// filling it to the calling code via the propery set
explicit Texture(ClipInstance& instance);
// Render Scale (renderScaleX,renderScaleY) -
//
// The proxy render scale currently being applied.
// ------
// Index -
//
// The texture id (cast to GLuint).
// ------
// Target -
//
// The texture target (cast to GLenum).
// ------
// Bounds (bx1,by1,bx2,by2) -
//
// The bounds of an image's pixels. The bounds, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// ROD (rodx1,rody1,rodx2,rody2) -
//
// The full region of definition. The ROD, in PixelCoordinates, are of the
// addressable pixels in an image's data pointer. The order of the values is
// x1, y1, x2, y2. X values are x1 &lt;= X &lt; x2 Y values are y1 &lt;= Y &lt; y2
// ------
// Row Bytes -
//
// The number of bytes in a row of an image.
// ------
// Field -
//
// kOfxImageFieldNone - the image is an unfielded frame
// kOfxImageFieldBoth - the image is fielded and contains both interlaced fields
// kOfxImageFieldLower - the image is fielded and contains a single field, being the lower field (rows 0,2,4...)
// kOfxImageFieldUpper - the image is fielded and contains a single field, being the upper field (rows 1,3,5...)
// ------
// Unique Identifier -
//
// Uniquely labels an image. This is host set and allows a plug-in to differentiate between images. This is
// especially useful if a plugin caches analysed information about the image (for example motion vectors). The
// plugin can label the cached information with this identifier. If a user connects a different clip to the
// analysed input, or the image has changed in some way then the plugin can detect this via an identifier change
// and re-evaluate the cached information.
// construction based on clip instance
Texture(ClipInstance& instance, // construct from clip instance taking pixel depth, components, pre mult and aspect ratio
double renderScaleX,
double renderScaleY,
int index,
int target,
const OfxRectI &bounds,
const OfxRectI &rod,
int rowBytes,
std::string field,
std::string uniqueIdentifier);
};
# endif
} // Memory
} // Host
} // OFX
#endif // OFX_CLIP_H
+84
View File
@@ -0,0 +1,84 @@
#ifndef OFX_HOST_H
#define OFX_HOST_H
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <map>
#include <string>
#include <cstdarg>
#include "ofxCore.h"
#include "ofxImageEffect.h"
#include "ofxTimeLine.h"
#include "ofxhPropertySuite.h"
namespace OFX {
namespace Host {
/// a plugin what we use
class Plugin;
/// a param descriptor
namespace Param {
class Descriptor;
}
/// Base class for all objects passed to a plugin by the 'setHost' function
/// passed back by any plug-in.
class Host {
protected :
OfxHost _host;
Property::Set _properties;
public:
Host();
virtual ~Host() {}
/// get the props on this host
Property::Set &getProperties() {return _properties; }
/// fetch a suite
/// The base class returns the following suites
/// PropertySuite
/// MemorySuite
virtual const void *fetchSuite(const char *suiteName, int suiteVersion);
/// get the C API handle that is passed across the API to represent this host
OfxHost *getHandle();
/// override this to handle do post-construction initialisation on a Param::Descriptor
virtual void initParamDescriptor(Param::Descriptor *) { }
/// is my magic number valid?
bool verifyMagic() { return true; }
/// message (called when an exception occurs, calls vmessage)
OfxStatus message(const char* type,
const char* id,
const char* format,
...);
/// vmessage
virtual OfxStatus vmessage(const char* type,
const char* id,
const char* format,
va_list args) = 0;
/// setPersistentMessage
virtual OfxStatus setPersistentMessage(const char* type,
const char* id,
const char* format,
va_list args) = 0;
/// clearPersistentMessage
virtual OfxStatus clearPersistentMessage() = 0;
};
}
}
#endif
+679
View File
@@ -0,0 +1,679 @@
#ifndef OFX_IMAGE_EFFECT_H
#define OFX_IMAGE_EFFECT_H
#include "ofxCore.h"
#include "ofxImageEffect.h"
#include "ofxhHost.h"
#include "ofxhClip.h"
#include "ofxhProgress.h"
#include "ofxhTimeLine.h"
#include "ofxhParam.h"
#include "ofxhMemory.h"
#include "ofxhInteract.h"
#ifdef _MSC_VER
//Use visual studio extension
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
namespace OFX {
namespace Host {
// forward declare
class Plugin;
namespace Memory {
class Instance;
}
namespace ImageEffect {
// forward declare
class ImageEffectPlugin;
class OverlayInstance;
class Instance;
class Descriptor;
/// An image effect host, passed to the setHost function of all image effect plugins
class Host : public OFX::Host::Host {
public :
Host();
/// fetch a suite
virtual const void *fetchSuite(const char *suiteName, int suiteVersion);
/// Create a new instance of an image effect plug-in.
///
/// It is called by ImageEffectPlugin::createInstance which the
/// client code calls when it wants to make a new instance.
///
/// \arg clientData - the clientData passed into the ImageEffectPlugin::createInstance
/// \arg plugin - the plugin being created
/// \arg desc - the descriptor for that plugin
/// \arg context - the context to be created in
virtual Instance* newInstance(void* clientData,
ImageEffectPlugin* plugin,
Descriptor& desc,
const std::string& context) = 0;
/// Function called as each plugin binary is found and loaded from disk
///
/// Use this in any dialogue etc... showing progress
virtual void loadingStatus(const std::string &);
/// Override this to filter out plugins which the host can't support for whatever reason
///
/// \arg plugin - the plugin to examine
/// \arg reason - set this to report the reason the plugin was not loaded
virtual bool pluginSupported(ImageEffectPlugin *plugin, std::string &reason) const;
/// Override this to create a descriptor, this makes the 'root' descriptor
virtual Descriptor *makeDescriptor(ImageEffectPlugin* plugin) = 0;
/// used to construct a context description, rootContext is the main context
virtual Descriptor *makeDescriptor(const Descriptor &rootContext, ImageEffectPlugin *plug) = 0;
/// used to construct populate the cache
virtual Descriptor *makeDescriptor(const std::string &bundlePath, ImageEffectPlugin *plug) = 0;
/// Override this to initialise an image effect descriptor after it has been
/// created.
virtual void initDescriptor(Descriptor* desc);
#ifdef OFX_SUPPORTS_MULTITHREAD
// these functions must be implemented if the host supports OfxMultiThreadSuiteV1
// all the following functions are described in ofxMultiThread.h
//
/// @see OfxMultiThreadSuiteV1.multiThread()
virtual OfxStatus multiThread(OfxThreadFunctionV1 func,unsigned int nThreads, void *customArg) = 0;
/// @see OfxMultiThreadSuiteV1.multiThreadNumCPUS()
virtual OfxStatus multiThreadNumCPUS(unsigned int *nCPUs) const = 0;
/// @see OfxMultiThreadSuiteV1.multiThreadIndex()
virtual OfxStatus multiThreadIndex(unsigned int *threadIndex) const = 0;
/// @see OfxMultiThreadSuiteV1.multiThreadIsSpawnedThread()
virtual int multiThreadIsSpawnedThread() const = 0;
/// @see OfxMultiThreadSuiteV1.mutexCreate()
virtual OfxStatus mutexCreate(OfxMutexHandle *mutex, int lockCount) = 0;
/// @see OfxMultiThreadSuiteV1.mutexDestroy()
virtual OfxStatus mutexDestroy(const OfxMutexHandle mutex) = 0;
/// @see OfxMultiThreadSuiteV1.mutexLock()
virtual OfxStatus mutexLock(const OfxMutexHandle mutex) = 0;
/// @see OfxMultiThreadSuiteV1.mutexUnLock()
virtual OfxStatus mutexUnLock(const OfxMutexHandle mutex) = 0;
/// @see OfxMultiThreadSuiteV1.mutexTryLock()
virtual OfxStatus mutexTryLock(const OfxMutexHandle mutex) = 0;
#endif // OFX_SUPPORTS_MULTITHREAD
# ifdef OFX_SUPPORTS_OPENGLRENDER
/// @see OfxImageEffectOpenGLRenderSuiteV1.flushResources()
virtual OfxStatus flushOpenGLResources() const = 0;
# endif
/// override this to use your own memory instance - must inherrit from memory::instance
virtual Memory::Instance* newMemoryInstance(size_t nBytes);
// return an memory::instance calls makeMemoryInstance that can be overriden
Memory::Instance* imageMemoryAlloc(size_t nBytes);
};
/// our global host object, set when the plugin cache is created
extern Host *gImageEffectHost;
////////////////////////////////////////////////////////////////////////////////
/// base class to both effect descriptors and instances
class Base {
protected:
Property::Set _properties;
public:
Base(const Property::Set &set);
Base(const Property::PropSpec * propSpec);
virtual ~Base();
/// is my magic number valid?
virtual bool verifyMagic() { return true; }
/// obtain a handle on this for passing to the C api
OfxImageEffectHandle getHandle() const;
/// get the properties set
Property::Set &getProps();
/// get the properties set, const version
const Property::Set &getProps() const;
/// name of the clip
const std::string &getShortLabel() const;
/// name of the clip
const std::string &getLabel() const;
/// name of the clip
const std::string &getLongLabel() const;
/// is the given context supported
bool isContextSupported(const std::string &s) const;
/// what is the name of the group the plug-in belongs to
const std::string &getPluginGrouping() const;
/// is the effect single instance
bool isSingleInstance() const;
/// what is the thread safety on this effect
const std::string &getRenderThreadSafety() const;
/// should the host attempt to managed multi-threaded rendering if it can
/// via tiling or some such
bool getHostFrameThreading() const;
/// get the overlay interact main entry if it exists
OfxPluginEntryPoint *getOverlayInteractMainEntry() const;
/// does the effect support images of differing sizes
bool supportsMultiResolution() const;
/// does the effect support tiled rendering
bool supportsTiles() const;
/// does this effect need random temporal access
bool temporalAccess() const;
/// is the given RGBA/A pixel depth supported by the effect
bool isPixelDepthSupported(const std::string &s) const;
/// when field rendering, does the effect need to be called
/// twice to render a frame in all circumstances (with different fields)
bool fieldRenderTwiceAlways() const;
/// does the effect support multiple clip depths
bool supportsMultipleClipDepths() const;
/// does the effect support multiple clip pixel aspect ratios
bool supportsMultipleClipPARs() const;
/// does changing the named param re-tigger a clip preferences action
bool isClipPreferencesSlaveParam(const std::string &s) const;
};
/// an image effect plugin descriptor
class Descriptor
: public Base
, public Param::SetDescriptor {
private :
// private CC
Descriptor(const Descriptor &other)
: Base(other._properties)
, Param::SetDescriptor()
, _plugin(other._plugin)
{}
protected:
Plugin *_plugin; ///< the plugin I belong to
std::map<std::string, ClipDescriptor*> _clips; ///< clips descriptors by name
std::vector<ClipDescriptor*> _clipsByOrder; ///< clip descriptors in order of declaration
mutable Interact::Descriptor _overlayDescriptor; ///< descriptor to use for overlays, it has delayed description
public:
/// used to construct the global description
Descriptor(Plugin *plug);
/// used to construct a context description, 'other' is the main context
Descriptor(const Descriptor &rootContext, Plugin *plug);
/// used to construct populate the cache
Descriptor(const std::string &bundlePath, Plugin *plug);
/// dtor
virtual ~Descriptor();
/// implemented for Param::SetDescriptor
virtual Property::Set &getParamSetProps();
/// get the plugin I belong to
Plugin *getPlugin() const {return _plugin;}
/// create a new clip and add this to the clip map
virtual ClipDescriptor *defineClip(const std::string &name);
/// get the clips
const std::map<std::string, ClipDescriptor*> &getClips() const;
/// add a new clip
void addClip(const std::string &name, ClipDescriptor *clip);
/// get the clips in order of construction
const std::vector<ClipDescriptor*> &getClipsByOrder() const
{
return _clipsByOrder;
}
/// Get the interact description, this will also call describe on the interact
/// This will return NULL if there is not main entry point or if the description failed
/// otherwise it will return the described overlay
Interact::Descriptor &getOverlayDescriptor(int bitDepthPerComponent = 8, bool hasAlpha = false);
};
/// a map used to specify needed frame ranges on set of clips
typedef std::map<ClipInstance *, std::vector<OfxRangeD> > RangeMap;
/// an image effect plugin instance.
///
/// Client code needs to filling the pure virtuals in this.
class Instance : public Base,
public Param::SetInstance,
public Progress::ProgressI,
public TimeLine::TimeLineI,
private Property::NotifyHook,
private Property::GetHook
{
protected:
OFX::Host::ImageEffect::ImageEffectPlugin *_plugin;
std::string _context;
Descriptor *_descriptor;
std::map<std::string, ClipInstance*> _clips;
bool _interactive;
bool _created;
bool _clipPrefsDirty; ///< do we need to re-run the clip prefs action
bool _continuousSamples; ///< set by clip prefs
bool _frameVarying; ///< set by clip prefs
std::string _outputPreMultiplication; ///< set by clip prefs
std::string _outputFielding; ///< set by clip prefs
double _outputFrameRate; ///< set by clip prefs
public:
/// constructor based on clip descriptor
Instance(ImageEffectPlugin* plugin,
Descriptor &other,
const std::string &context,
bool interactive);
virtual ~Instance();
/// implemented for Param::SetInstance
virtual Property::Set &getParamSetProps();
/// implemented for Param::SetInstance
virtual void paramChangedByPlugin(Param::Instance *param);
/// get the descriptor for this instance
const Descriptor &getDescriptor() const {return *_descriptor;}
/// return the plugin this instance was created with
OFX::Host::ImageEffect::ImageEffectPlugin*getPlugin() const { return _plugin; }
/// return the context this instance was created with
const std::string &getContext() const { return _context; }
/// get the descriptor for this instance
Descriptor &getDescriptor() {return *_descriptor;}
/// get default output fielding. This is passed into the clip prefs action
/// and might be mapped (if the host allows such a thing)
virtual const std::string &getDefaultOutputFielding() const = 0;
/// get output fielding as set in the clip preferences action.
const std::string &getOutputFielding() const {return _outputFielding; }
/// get output fielding as set in the clip preferences action.
const std::string &getOutputPreMultiplication() const {return _outputPreMultiplication; }
/// get the output frame rate, as set in the clip prefences action.
double getOutputFrameRate() const {return _outputFrameRate;}
/// called after construction to populate the various members
/// ideally should be called in the ctor, but it relies on
/// virtuals so has to be delayed until after the effect is
/// constructed
OfxStatus populate();
/// get the nth clip, in order of declaration
ClipInstance* getNthClip(int index);
/// get the nth clip, in order of declaration
int getNClips() const
{
return int(_clips.size());
}
/// are the clip preferences currently dirty
bool areClipPrefsDirty() const {return _clipPrefsDirty;}
/// are all the non optional clips connected
bool checkClipConnectionStatus() const;
/// can this this instance render images at arbitrary times, not just frame boundaries
/// set by getClipPreferenceAction()
bool continuousSamples() const {return _continuousSamples;}
/// does this instance generate a different picture on a frame change, even if the
/// params and input images are exactly the same. eg: random noise generator
bool isFrameVarying() const {return _frameVarying;}
/// pure virtuals that must be overriden
virtual ClipInstance* getClip(const std::string& name) const;
/// override this to make processing abort, return 1 to abort processing
virtual int abort();
/// override this to use your own memory instance - must inherrit from memory::instance
virtual Memory::Instance* newMemoryInstance(size_t nBytes);
// return an memory::instance calls makeMemoryInstance that can be overriden
Memory::Instance* imageMemoryAlloc(size_t nBytes);
/// make a clip
virtual ClipInstance* newClipInstance(ImageEffect::Instance* plugin,
ClipDescriptor* descriptor,
int index) = 0;
/// message suite
virtual OfxStatus vmessage(const char* type,
const char* id,
const char* format,
va_list args) = 0;
virtual OfxStatus setPersistentMessage(const char* type,
const char* id,
const char* format,
va_list args) = 0;
virtual OfxStatus clearPersistentMessage() = 0;
/// call the effect entry point
virtual OfxStatus mainEntry(const char *action,
const void *handle,
Property::Set *inArgs,
Property::Set *outArgs);
int upperGetDimension(const std::string &name);
/// overridden from Property::Notify
virtual void notify(const std::string &name, bool singleValue, int indexOrN);
/// overridden from gethook, get the virutals for viewport size, pixel scale, background colour
virtual double getDoubleProperty(const std::string &name, int index) const;
/// overridden from gethook, get the virutals for viewport size, pixel scale, background colour
virtual void getDoublePropertyN(const std::string &name, double *values, int count) const;
/// overridden from gethook, don't know what to do
virtual void reset(const std::string &name);
//// overridden from gethook
virtual int getDimension(const std::string &name) const;
//
// live parameters
//
// The size of the current project in canonical coordinates.
// The size of a project is a sub set of the kOfxImageEffectPropProjectExtent. For example a
// project may be a PAL SD project, but only be a letter-box within that. The project size is
// the size of this sub window.
virtual void getProjectSize(double& xSize, double& ySize) const = 0;
// The offset of the current project in canonical coordinates.
// The offset is related to the kOfxImageEffectPropProjectSize and is the offset from the origin
// of the project 'subwindow'. For example for a PAL SD project that is in letterbox form, the
// project offset is the offset to the bottom left hand corner of the letter box. The project
// offset is in canonical coordinates.
virtual void getProjectOffset(double& xOffset, double& yOffset) const = 0;
// The extent of the current project in canonical coordinates.
// The extent is the size of the 'output' for the current project. See ProjectCoordinateSystems
// for more infomation on the project extent. The extent is in canonical coordinates and only
// returns the top right position, as the extent is always rooted at 0,0. For example a PAL SD
// project would have an extent of 768, 576.
virtual void getProjectExtent(double& xSize, double& ySize) const = 0;
// The pixel aspect ratio of the current project
virtual double getProjectPixelAspectRatio() const = 0;
// The duration of the effect
// This contains the duration of the plug-in effect, in frames.
virtual double getEffectDuration() const = 0;
// For an instance, this is the frame rate of the project the effect is in.
virtual double getFrameRate() const = 0;
/// This is called whenever a param is changed by the plugin so that
/// the recursive instanceChangedAction will be fed the correct frame
virtual double getFrameRecursive() const = 0;
/// This is called whenever a param is changed by the plugin so that
/// the recursive instanceChangedAction will be fed the correct
/// renderScale
virtual void getRenderScaleRecursive(double &x, double &y) const = 0;
/// Get whether the component is a supported 'chromatic' component (RGBA or alpha) in
/// the base API.
/// Override this if you have extended your chromatic colour types (eg RGB) and want
/// the clip preferences logic to still work
virtual bool isChromaticComponent(const std::string &str) const;
/// function to check for multiple bit depth support
/// The answer will depend on host, plugin and context
virtual bool canCurrentlyHandleMultipleClipDepths() const;
/// calculate the default rod for this effect instance
virtual OfxRectD calcDefaultRegionOfDefinition(OfxTime time,
OfxPointD renderScale) const;
//
// actions
//
/// this is used to populate with any extra action in argumnents that may be needed
virtual void setCustomInArgs(const std::string &action, Property::Set &inArgs);
/// this is used to populate with any extra action out argumnents that may be needed
virtual void setCustomOutArgs(const std::string &action, Property::Set &outArgs);
/// this is used retrieve any out args after the action was called in mainEntry
virtual void examineOutArgs(const std::string &action, OfxStatus stat, const Property::Set &outArgs);
/// create an instance. This needs to be called _after_ construction and
/// _after_ the host populates it's params and clips with the 'correct'
/// values (either persisted ones or the defaults)
virtual OfxStatus createInstanceAction();
// begin/change/end instance changed
//
// why -
//
// kOfxChangeUserEdited - the user or host changed the instance somehow and
// caused a change to something, this includes undo/redos,
// resets and loading values from files or presets,
// kOfxChangePluginEdited - the plugin itself has changed the value of the instance
// in some action
// kOfxChangeTime - the time has changed and this has affected the value
// of the object because it varies over time
//
virtual OfxStatus beginInstanceChangedAction(const std::string &why);
virtual OfxStatus paramInstanceChangedAction(const std::string &paramName,
const std::string & why,
OfxTime time,
OfxPointD renderScale);
virtual OfxStatus clipInstanceChangedAction(const std::string &clipName,
const std::string & why,
OfxTime time,
OfxPointD renderScale);
virtual OfxStatus endInstanceChangedAction(const std::string &why);
// purge your caches
virtual OfxStatus purgeCachesAction();
// sync your private data
virtual OfxStatus syncPrivateDataAction();
// begin/end edit instance
virtual OfxStatus beginInstanceEditAction();
virtual OfxStatus endInstanceEditAction();
# ifdef OFX_SUPPORTS_OPENGLRENDER
// attach/detach OpenGL context
virtual OfxStatus contextAttachedAction();
virtual OfxStatus contextDetachedAction();
# endif
// render action
virtual OfxStatus beginRenderAction(OfxTime startFrame,
OfxTime endFrame,
OfxTime step,
bool interactive,
OfxPointD renderScale,
bool sequentialRender,
bool interactiveRender
);
virtual OfxStatus renderAction(OfxTime time,
const std::string & field,
const OfxRectI &renderRoI,
OfxPointD renderScale,
bool sequentialRender,
bool interactiveRender,
bool draftRender
);
virtual OfxStatus endRenderAction(OfxTime startFrame,
OfxTime endFrame,
OfxTime step,
bool interactive,
OfxPointD renderScale,
bool sequentialRender,
bool interactiveRender
);
/// Call the region of definition action the plugin at the given time
/// and with the given render scales. The value is returned in rod.
/// Note that if the plugin does not trap the action the default
/// RoD is calculated and returned.
virtual OfxStatus getRegionOfDefinitionAction(OfxTime time,
OfxPointD renderScale,
OfxRectD &rod);
/// call the get region of interest action on the plugin for the
/// given frame and renderscale. The render RoI is passed in in
/// roi, the std::map will contain the requested rois. Note
/// That this call will check for tiling support and for
/// default replies and set up the correct rois in these cases
/// as well
virtual OfxStatus getRegionOfInterestAction(OfxTime time,
OfxPointD renderScale,
const OfxRectD &roi,
std::map<ClipInstance *, OfxRectD> &rois);
// get frames needed to render the given frame
virtual OfxStatus getFrameNeededAction(OfxTime time,
RangeMap &rangeMap);
// is identity
virtual OfxStatus isIdentityAction(OfxTime &time,
const std::string & field,
const OfxRectI &renderRoI,
OfxPointD renderScale,
std::string &clip);
// time domain
virtual OfxStatus getTimeDomainAction(OfxRangeD& range);
/// Get the interact description, this will also call describe on the interact
/// This will return NULL if there is not main entry point or if the description failed
/// otherwise it will return the described overlay
/// This is called by the CTOR of OverlayInteract to get the descriptor to do things with
Interact::Descriptor &getOverlayDescriptor(int bitDepthPerComponent = 8, bool hasAlpha = false);
/// Setup the default clip preferences on the clips
virtual void setDefaultClipPreferences();
/// Initialise the clip preferences arguments, override this to do
/// stuff with wierd components etc... Calls setDefaultClipPreferences
virtual void setupClipPreferencesArgs(Property::Set &args);
/// Run the clip preferences action from the effect.
///
/// This will look into the input clips and output clip
/// and set the following properties that the effect should
/// fetch the image at.
/// - pixel depth
/// - components
/// - pixel aspect ratio
/// It will also set on the effect itselff
/// - whether it is continuously samplable
/// - the premult state of the output
/// - whether the effect is frame varying
/// - the fielding of the output clip
///
/// This will be run automatically by the effect in the following situations...
/// - an input clip is changed
/// - a clip preferences slave param is changed
///
/// The host still needs to call this explicitly just after the effect is wired
/// up.
virtual bool getClipPreferences();
/// calls getClipPreferences only if the prefs are dirty
///
/// returns whether the clips prefs were dirty or not
bool runGetClipPrefsConditionally()
{
if(areClipPrefsDirty()) {
getClipPreferences();
return true;
}
return false;
}
/// find the best supported bit depth for the given one. Override this if you define
/// more depths
virtual const std::string &bestSupportedDepth(const std::string &depth) const;
/// find the most chromatic components out of the two. Override this if you define
/// more chromatic components
virtual const std::string &findMostChromaticComponents(const std::string &a, const std::string &b) const;
};
////////////////////////////////////////////////////////////////////////////////
/// An overlay interact for image effects, derived from one of these to
/// be an overlay interact
class OverlayInteract : public Interact::Instance {
protected :
/// our image effect instance
ImageEffect::Instance &_instance;
public :
/// ctor this calls Instance->getOverlayDescriptor to get the descriptor
OverlayInteract(ImageEffect::Instance &v, int bitDepthPerComponent = 8, bool hasAlpha = false);
};
} // namespace ImageEffect
} // namespace Host
} // namespace OFX
#endif // OFX_IMAGE_EFFECT_H
@@ -0,0 +1,221 @@
#ifndef OFXH_IMAGE_EFFECT_API_H
#define OFXH_IMAGE_EFFECT_API_H
#include "ofxhPluginAPICache.h"
#include "ofxhPluginCache.h"
#include <string>
#include <map>
#include <set>
#include <memory>
#include <utility>
#include "ofxCore.h"
#include "ofxImageEffect.h"
#include "ofxhImageEffect.h"
#include "ofxhHost.h"
namespace OFX::Host::ImageEffect {
class PluginCache;
/// subclass of Plugin representing an ImageEffect plugin. used to store API-specific
/// data
class ImageEffectPlugin : public Plugin {
PluginCache &_pc;
// this comes off Descriptor's property set after a describe
// context independent
Descriptor *_baseDescriptor; /// NEEDS TO BE MADE WITH A FACTORY FUNCTION ON THE HOST!!!!!!
/// map to store contexts in
std::map<std::string, std::unique_ptr<Descriptor>> _contexts;
mutable std::set<std::string> _knownContexts;
mutable bool _madeKnownContexts;
std::unique_ptr<PluginHandle> _pluginHandle;
void addContextInternal(const std::string &context) const;
public:
ImageEffectPlugin(PluginCache &pc, PluginBinary *pb, int pi, OfxPlugin *pl);
ImageEffectPlugin(PluginCache &pc,
PluginBinary *pb,
int pi,
const std::string &api,
int apiVersion,
const std::string &pluginId,
const std::string &rawId,
int pluginMajorVersion,
int pluginMinorVersion);
~ImageEffectPlugin() override;
/// return the API handler this plugin was constructed by
APICache::PluginAPICacheI &getApiHandler() override;
/// get the base image effect descriptor
Descriptor &getDescriptor();
/// get the base image effect descriptor, const version
const Descriptor &getDescriptor() const;
/// get the image effect descriptor for the context
Descriptor *getContext(const std::string &context);
void addContext(const std::string &context);
void addContext(const std::string &context, std::unique_ptr<Descriptor> ied);
virtual void saveXML(std::ostream &os);
const std::set<std::string>& getContexts() const;
PluginHandle *getPluginHandle();
void unload();
/// this is called to make an instance of the effect
/// the client data ptr is what is passed back to the client creation function
ImageEffect::Instance* createInstance(const std::string &context, void *clientDataPtr);
};
class MajorPlugin {
std::string _id;
int _major;
public:
MajorPlugin(std::string id, int major) : _id(std::move(id)), _major(major) {
}
explicit MajorPlugin(ImageEffectPlugin *iep) : _id(iep->getIdentifier()), _major(iep->getVersionMajor()) {
}
[[nodiscard]] const std::string &getId() const {
return _id;
}
[[nodiscard]] int getMajor() const {
return _major;
}
bool operator<(const MajorPlugin &other) const {
if (_id < other._id)
return true;
if (_id > other._id)
return false;
if (_major < other._major)
return true;
return false;
}
};
/// implementation of the specific Image Effect handler API cache.
class PluginCache : public APICache::PluginAPICacheI {
public:
private:
/// all plugins
std::vector<ImageEffectPlugin *> _plugins;
/// latest version of each plugin by ID
std::map<std::string, ImageEffectPlugin *> _pluginsByID;
/// latest minor version of each plugin by (ID,major)
std::map<MajorPlugin, ImageEffectPlugin *> _pluginsByIDMajor;
/// xml parsing state
ImageEffectPlugin *_currentPlugin;
/// xml parsing state
Property::Property *_currentProp;
Descriptor *_currentContext;
Param::Descriptor *_currentParam;
ClipDescriptor *_currentClip;
/// pointer to our image effect host
OFX::Host::ImageEffect::Host* _host;
public:
explicit PluginCache(OFX::Host::ImageEffect::Host &host);
~PluginCache() override;
/// get the plugin by id. vermaj and vermin can be specified. if they are not it will
/// pick the highest found version.
ImageEffectPlugin *getPluginById(const std::string &id, int vermaj=-1, int vermin=-1);
/// get the plugin by label. vermaj and vermin can be specified. if they are not it will
/// pick the highest found version.
ImageEffectPlugin *getPluginByLabel(const std::string &label, int vermaj=-1, int vermin=-1);
OFX::Host::ImageEffect::Host *getHost() {
return _host;
}
[[nodiscard]] const std::vector<ImageEffectPlugin *>& getPlugins() const;
[[nodiscard]] const std::map<std::string, ImageEffectPlugin *>& getPluginsByID() const;
[[nodiscard]] const std::map<MajorPlugin, ImageEffectPlugin *>& getPluginsByIDMajor() const
{
return _pluginsByIDMajor;
}
/// handle the case where the info needs filling in from the file. runs the "describe" action on the plugin.
void loadFromPlugin(Plugin *p) const override;
/// handler for preparing to read in a chunk of XML from the cache, set up context to do this
void beginXmlParsing(Plugin *p) override;
/// XML handler : element begins (everything is stored in elements and attributes)
void xmlElementBegin(const std::string &el, std::map<std::string, std::string> map) override;
void xmlCharacterHandler(const std::string &) override;
void xmlElementEnd(const std::string &el) override;
void endXmlParsing() override;
void saveXML(Plugin *ip, std::ostream &os) const override;
void confirmPlugin(Plugin *p) override;
bool pluginSupported(Plugin *p, std::string &reason) const override;
Plugin *newPlugin(PluginBinary *pb,
int pi,
OfxPlugin *pl) override;
Plugin *newPlugin(PluginBinary *pb,
int pi,
const std::string &api,
int apiVersion,
const std::string &pluginId,
const std::string &rawId,
int pluginMajorVersion,
int pluginMinorVersion) override;
void dumpToStdOut();
};
} // ImageEffect
// Host
// OFX
#endif
+278
View File
@@ -0,0 +1,278 @@
#ifndef OFX_INTERACT_H
#define OFX_INTERACT_H
#include "ofxInteract.h"
#include "ofxOld.h" // old plugins may rely on deprecated properties being present
#include "ofxhPropertySuite.h"
namespace OFX {
namespace Host {
namespace Interact {
/// fetch a versioned suite for our interact
const void *GetSuite(int version);
class Base {
public:
virtual ~Base() {
}
/// grab a handle on the parameter for passing to the C API
OfxInteractHandle getHandle() {return (OfxInteractHandle)this;}
/// get the property handle for this instance/descriptor
virtual OfxPropertySetHandle getPropHandle() = 0;
};
/// state the interact can be in
enum State {
eUninitialised,
eDescribed,
eCreated,
eFailed
};
/// Descriptor for an interact. Interacts all share a single description
class Descriptor : public Base {
protected:
Property::Set _properties; ///< its props
State _state; ///< how is it feeling today
OfxPluginEntryPoint *_entryPoint; ///< the entry point for this overlay
public:
/// CTOR
Descriptor();
/// dtor
virtual ~Descriptor();
/// set the main entry points
void setEntryPoint(OfxPluginEntryPoint *entryPoint) {_entryPoint = entryPoint;}
/// call describe on this descriptor, returns true if all went well
bool describe(int bitDepthPerComponent, bool hasAlpha);
/// grab a handle on the properties of this parameter for the C api
OfxPropertySetHandle getPropHandle() {return _properties.getHandle();}
/// get prop set
const Property::Set &getProperties() const {return _properties;}
/// get a non const prop set
Property::Set &getProperties() {return _properties;}
/// call the entry point with action and the given args
OfxStatus callEntry(const char *action,
void *handle,
OfxPropertySetHandle inArgs,
OfxPropertySetHandle outArgs);
/// what is it's state?
State getState() const {return _state;}
};
/// a generic interact, it doesn't belong to anything in particular
/// we need to generify this slighty more and remove the renderscale args
/// into a derived class, as they only belong to image effect plugins
class Instance : public Base, protected Property::GetHook {
protected:
Descriptor &_descriptor; ///< who we are
Property::Set _properties; ///< its props
State _state; ///< how is it feeling today
void *_effectInstance; ///< this is ugly, we need a base class to all plugin instances at some point.
Property::Set _argProperties;
/// initialise the argument properties
void initArgProp(OfxTime time,
const OfxPointD &renderScale);
/// set pen props in the args
void setPenArgProps(const OfxPointD &penPos,
const OfxPointI &penPosViewport,
double pressure);
/// set key args in the props
void setKeyArgProps(int key,
char* keyString);
public:
Instance(Descriptor &desc, void *effectInstance);
virtual ~Instance();
/// what is it's state?
State getState() const {return _state;}
/// grab a handle on the properties of this parameter for the C api
OfxPropertySetHandle getPropHandle() {return _properties.getHandle();}
/// get prop set
const Property::Set &getProperties() const {return _properties;}
/// call the entry point in the descriptor with action and the given args
virtual OfxStatus callEntry(const char *action,
Property::Set *inArgs);
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
/// hooks to kOfxInteractPropViewportSize in the property set
/// this is actually redundant and is to be deprecated
virtual void getViewportSize(double &width, double &height) const = 0;
#endif
// hooks to live kOfxInteractPropPixelScale in the property set
virtual void getPixelScale(double& xScale, double& yScale) const = 0;
// hooks to kOfxInteractPropBackgroundColour in the property set
virtual void getBackgroundColour(double &r, double &g, double &b) const = 0;
// hooks to kOfxInteractPropSuggestedColour and kOfxPropOverlayColour in the property set
// return false if there is no color suggestion by the host.
virtual bool getSuggestedColour(double &r, double &g, double &b) const = 0;
/// implement
virtual OfxStatus swapBuffers() = 0;
/// implement this
virtual OfxStatus redraw() = 0;
/// returns the params the interact uses
virtual void getSlaveToParam(std::vector<std::string>& params) const;
// do nothing
virtual int getDimension(const std::string &name) const;
// don't know what to do
virtual void reset(const std::string &name);
/// the gethook virutals for pixel scale, background colour
virtual double getDoubleProperty(const std::string &name, int index) const;
/// for pixel scale and background colour
virtual void getDoublePropertyN(const std::string &name, double *first, int n) const;
/// call create instance
virtual OfxStatus createInstanceAction();
// interact action - kOfxInteractActionDraw
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
virtual OfxStatus drawAction(OfxTime time, const OfxPointD &renderScale);
// interact action - kOfxInteractActionPenMotion
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// penX - the X position
// penY - the Y position
// pressure - the pen pressue 0 to 1
virtual OfxStatus penMotionAction(OfxTime time,
const OfxPointD &renderScale,
const OfxPointD &penPos,
const OfxPointI &penPosViewport,
double pressure);
// interact action - kOfxInteractActionPenUp
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// penX - the X position
// penY - the Y position
// pressure - the pen pressue 0 to 1
virtual OfxStatus penUpAction(OfxTime time,
const OfxPointD &renderScale,
const OfxPointD &penPos,
const OfxPointI &penPosViewport,
double pressure);
// interact action - kOfxInteractActionPenDown
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// penX - the X position
// penY - the Y position
// pressure - the pen pressue 0 to 1
virtual OfxStatus penDownAction(OfxTime time,
const OfxPointD &renderScale,
const OfxPointD &penPos,
const OfxPointI &penPosViewport,
double pressure);
// interact action - kOfxInteractActionkeyDown
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// key - the pressed key
// keyString - the pressed key string
virtual OfxStatus keyDownAction(OfxTime time,
const OfxPointD &renderScale,
int key,
char* keyString);
// interact action - kOfxInteractActionkeyUp
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// key - the pressed key
// keyString - the pressed key string
virtual OfxStatus keyUpAction(OfxTime time,
const OfxPointD &renderScale,
int key,
char* keyString);
// interact action - kOfxInteractActionkeyRepeat
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
// key - the pressed key
// keyString - the pressed key string
virtual OfxStatus keyRepeatAction(OfxTime time,
const OfxPointD &renderScale,
int key,
char* keyString);
// interact action - kOfxInteractActionLoseFocus
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
virtual OfxStatus gainFocusAction(OfxTime time,
const OfxPointD &renderScale);
// interact action - kOfxInteractActionLoseFocus
//
// Params -
//
// time - the effect time at which changed occured
// renderScale - the render scale
virtual OfxStatus loseFocusAction(OfxTime time,
const OfxPointD &renderScale);
};
} // Interact
} // Host
} // OFX
#endif // OFX_INTERACT_H
+39
View File
@@ -0,0 +1,39 @@
#ifndef OFX_MEMORY_H
#define OFX_MEMORY_H
#include "ofxImageEffect.h"
namespace OFX {
namespace Host {
namespace Memory {
class Instance {
public:
Instance();
virtual ~Instance();
virtual bool alloc(size_t nBytes);
virtual OfxImageMemoryHandle getHandle();
virtual void freeMem();
virtual void* getPtr();
virtual void lock();
virtual void unlock();
virtual bool verifyMagic() { return true; }
protected:
char* _ptr;
int _locked;
};
} // Memory
} // Host
} // OFX
#endif // OFX_MEMORY_H
+678
View File
@@ -0,0 +1,678 @@
#ifndef OFXH_PARAM_H
#define OFXH_PARAM_H
#include <string>
#include <map>
#include <list>
#include <cstdarg>
//ofx
#include "ofxParam.h"
//ofxh
#include "ofxhPropertySuite.h"
namespace OFX {
namespace Host {
namespace Param {
/// fetch the param suite
const void *GetSuite(int version);
bool isColourParam(const std::string &paramType);
bool isIntParam(const std::string &paramType);
/// is this a standard type
bool isStandardType(const std::string &type);
/// base class for all params
class Base {
private:
Base();
protected:
std::string _paramName;
std::string _paramType;
Property::Set _properties;
public:
Base(const std::string &name, const std::string &type);
Base(const std::string &name, const std::string &type, const Property::Set &properties);
virtual ~Base();
/// grab a handle on the parameter for passing to the C API
OfxParamHandle getHandle() const;
virtual bool verifyMagic() { return true; }
/// grab a handle on the properties of this parameter for the C api
OfxPropertySetHandle getPropHandle() const;
const Property::Set &getProperties() const;
Property::Set &getProperties();
const std::string &getType() const;
const std::string &getName() const;
const std::string &getParentName() const;
const std::string &getLabel() const;
const std::string &getShortLabel() const;
const std::string &getLongLabel() const;
const std::string &getScriptName() const;
const std::string &getDoubleType() const;
const std::string &getDefaultCoordinateSystem() const;
const std::string &getCacheInvalidation() const;
const std::string &getHint() const;
bool getEnabled() const;
bool getCanUndo() const;
bool getSecret() const;
bool getIsPersistant() const;
bool getEvaluateOnChange() const;
bool getCanAnimate() const;
};
/// the Descriptor of a plugin parameter
class Descriptor : public Base {
Descriptor();
public:
/// make a parameter, with the given type and name
Descriptor(const std::string &type, const std::string &name);
/// add standard param props, will call the below
void addStandardParamProps(const std::string &type);
/// add standard properties to a params that can take an interact
void addInteractParamProps(const std::string &type);
/// add standard properties to a value holding param
void addValueParamProps(const std::string &type, Property::TypeEnum valueType, int dim);
/// add standard properties to a value holding param
void addNumericParamProps(const std::string &type, Property::TypeEnum valueType, int dim);
};
/// base class to the param set instance and param set descriptor
class BaseSet {
public:
virtual ~BaseSet();
/// obtain a handle on this set for passing to the C api
OfxParamSetHandle getParamSetHandle() const;
/// get the property handle that lives with the set
/// The plugin descriptor/instance that derives from
/// this will provide this.
virtual Property::Set &getParamSetProps() = 0;
};
/// a set of parameters
class SetDescriptor : public BaseSet {
std::map<std::string, Descriptor*> _paramMap;
std::list<Descriptor *> _paramList;
/// CC doesn't exist
SetDescriptor(const SetDescriptor &);
public:
/// default ctor
SetDescriptor();
/// dtor
virtual ~SetDescriptor();
/// get the map of params
const std::map<std::string, Descriptor*> &getParams() const;
/// get the list of params
const std::list<Descriptor *> &getParamList() const;
/// define a param
virtual Descriptor *paramDefine(const char *paramType,
const char *name);
/// add a param in
virtual void addParam(const std::string &name, Descriptor *p);
};
// forward declare
class SetInstance;
/// the description of a plugin parameter
class Instance : public Base, protected Property::NotifyHook {
Instance();
protected:
SetInstance* _paramSetInstance;
Instance* _parentInstance;
public:
virtual ~Instance();
/// make a parameter, with the given type and name
explicit Instance(Descriptor& descriptor, Param::SetInstance* instance = 0);
// OfxStatus instanceChangedAction(const std::string &why,
// OfxTime time,
// double renderScaleX,
// double renderScaleY);
// get the param instance
OFX::Host::Param::SetInstance* getParamSetInstance() { return _paramSetInstance; }
// set/get parent instance
void setParentInstance(Instance* instance);
Instance* getParentInstance();
// copy one parameter to another, with a range (NULL means to copy all animation)
virtual OfxStatus copyFrom(const Instance &instance, OfxTime offset, const OfxRangeD* range);
// callback which should set enabled state as appropriate
virtual void setEnabled();
// callback which should set secret state as appropriate
virtual void setSecret();
/// callback which should update label
virtual void setLabel();
/// callback which should set range
virtual void setRange();
/// callback which should set display range
virtual void setDisplayRange();
/// callback which should set evaluate on change
virtual void setEvaluateOnChange();
// va list calls below turn the var args (oh what a mistake)
// suite functions into virtual function calls on instances
// they are not to be overridden by host implementors by
// by the various typeed param instances so that they can
// deconstruct the var args lists
/// get a value, implemented by instances to deconstruct var args
virtual OfxStatus getV(va_list arg);
/// get a value, implemented by instances to deconstruct var args
virtual OfxStatus getV(OfxTime time, va_list arg);
/// set a value, implemented by instances to deconstruct var args
virtual OfxStatus setV(va_list arg);
/// key a value, implemented by instances to deconstruct var args
virtual OfxStatus setV(OfxTime time, va_list arg);
/// derive a value, implemented by instances to deconstruct var args
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// integrate a value, implemented by instances to deconstruct var args
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
/// overridden from Property::NotifyHook
virtual void notify(const std::string &name, bool single, int num);
};
class KeyframeParam {
public:
virtual OfxStatus getNumKeys(unsigned int &nKeys) const ;
virtual OfxStatus getKeyTime(int nth, OfxTime& time) const ;
virtual OfxStatus getKeyIndex(OfxTime time, int direction, int & index) const ;
virtual OfxStatus deleteKey(OfxTime time) ;
virtual OfxStatus deleteAllKeys() ;
virtual ~KeyframeParam() {
}
};
class GroupInstance : public Instance {
protected:
std::vector<Param::Instance*> _children;
public:
GroupInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
void setChildren(std::vector<Param::Instance*> children);
const std::vector<Param::Instance*> &getChildren() const;
};
class PageInstance : public Instance {
public:
PageInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
const std::map<int,Param::Instance*> &getChildren() const;
protected :
mutable std::map<int,Param::Instance*> _children; // if set in a notify hook, this need not be mutable
};
class IntegerInstance : public Instance, public KeyframeParam {
public:
IntegerInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(int&) = 0;
virtual OfxStatus get(OfxTime time, int&) = 0;
virtual OfxStatus set(int) = 0;
virtual OfxStatus set(OfxTime time, int) = 0;
// probably derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, int&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, int&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class ChoiceInstance : public Instance, public KeyframeParam {
public:
ChoiceInstance(Descriptor& descriptor, Param::SetInstance* instance = 0);
// callback which should set option as appropriate
virtual void setOption(int num);
// Deriving implementatation needs to overide these
virtual OfxStatus get(int&) = 0;
virtual OfxStatus get(OfxTime time, int&) = 0;
virtual OfxStatus set(int) = 0;
virtual OfxStatus set(OfxTime time, int) = 0;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// overridden from Instance
virtual void notify(const std::string &name, bool single, int num);
};
class DoubleInstance : public Instance, public KeyframeParam {
public:
DoubleInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(double&) = 0;
virtual OfxStatus get(OfxTime time, double&) = 0;
virtual OfxStatus set(double) = 0;
virtual OfxStatus set(OfxTime time, double) = 0;
virtual OfxStatus derive(OfxTime time, double&) = 0;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, double&) = 0;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class BooleanInstance : public Instance, public KeyframeParam {
public:
BooleanInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(bool&) = 0;
virtual OfxStatus get(OfxTime time, bool&) = 0;
virtual OfxStatus set(bool) = 0;
virtual OfxStatus set(OfxTime time, bool) = 0;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
};
class RGBAInstance : public Instance, public KeyframeParam {
public:
RGBAInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(double&,double&,double&,double&) = 0;
virtual OfxStatus get(OfxTime time, double&,double&,double&,double&) = 0;
virtual OfxStatus set(double,double,double,double) = 0;
virtual OfxStatus set(OfxTime time, double,double,double,double) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, double&,double&,double&,double&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, double&,double&,double&,double&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class RGBInstance : public Instance, public KeyframeParam {
public:
RGBInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(double&,double&,double&) = 0;
virtual OfxStatus get(OfxTime time, double&,double&,double&) = 0;
virtual OfxStatus set(double,double,double) = 0;
virtual OfxStatus set(OfxTime time, double,double,double) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, double&,double&,double&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, double&,double&,double&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class Double2DInstance : public Instance, public KeyframeParam {
public:
Double2DInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(double&,double&) = 0;
virtual OfxStatus get(OfxTime time, double&,double&) = 0;
virtual OfxStatus set(double,double) = 0;
virtual OfxStatus set(OfxTime time, double,double) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, double&,double&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, double&,double&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class Integer2DInstance : public Instance, public KeyframeParam {
public:
Integer2DInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(int&,int&) = 0;
virtual OfxStatus get(OfxTime time, int&,int&) = 0;
virtual OfxStatus set(int,int) = 0;
virtual OfxStatus set(OfxTime time, int,int) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, int&,int&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, int&,int&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class Double3DInstance : public Instance , public KeyframeParam{
public:
Double3DInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
// Deriving implementatation needs to overide these
virtual OfxStatus get(double&,double&,double&) = 0;
virtual OfxStatus get(OfxTime time, double&,double&,double&) = 0;
virtual OfxStatus set(double,double,double) = 0;
virtual OfxStatus set(OfxTime time, double,double,double) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, double&,double&,double&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, double&,double&,double&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class Integer3DInstance : public Instance, public KeyframeParam {
public:
Integer3DInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
virtual OfxStatus get(int&,int&,int&) = 0;
virtual OfxStatus get(OfxTime time, int&,int&,int&) = 0;
virtual OfxStatus set(int,int,int) = 0;
virtual OfxStatus set(OfxTime time, int,int,int) = 0;
// derived class does not need to implement, default is an approximation
virtual OfxStatus derive(OfxTime time, int&,int&,int&) ;
virtual OfxStatus integrate(OfxTime time1, OfxTime time2, int&,int&,int&) ;
/// implementation of var args function
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus deriveV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus integrateV(OfxTime time1, OfxTime time2, va_list arg);
};
class StringInstance : public Instance, public KeyframeParam {
std::string _returnValue; ///< location to hold temporary return value. Should delegate this to implementation!!!
public:
StringInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
virtual OfxStatus get(std::string &) = 0;
virtual OfxStatus get(OfxTime time, std::string &) = 0;
virtual OfxStatus set(const char*) = 0;
virtual OfxStatus set(OfxTime time, const char*) = 0;
/// implementation of var args function
/// Be careful: the char* is only valid until next API call
/// see http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#ArchitectureStrings
virtual OfxStatus getV(va_list arg);
/// implementation of var args function
/// Be careful: the char* is only valid until next API call
/// see http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#ArchitectureStrings
virtual OfxStatus getV(OfxTime time, va_list arg);
/// implementation of var args function
virtual OfxStatus setV(va_list arg);
/// implementation of var args function
virtual OfxStatus setV(OfxTime time, va_list arg);
};
class CustomInstance : public StringInstance {
public:
CustomInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : StringInstance(descriptor,instance) {}
};
class PushbuttonInstance : public Instance, public KeyframeParam {
public:
PushbuttonInstance(Descriptor& descriptor, Param::SetInstance* instance = 0) : Instance(descriptor,instance) {}
};
/// A set of parameters
///
/// As we are the owning object we delete the params inside ourselves. It was tempting
/// to make params autoref objects and have shared ownership with the client code
/// but that adds complexity for no strong gain.
class SetInstance : public BaseSet {
protected:
std::map<std::string, Instance*> _params; ///< params by name
std::list<Instance *> _paramList; ///< params list
public :
/// ctor
///
/// The propery set being passed in belongs to the owning
/// plugin instance.
explicit SetInstance();
/// dtor.
virtual ~SetInstance();
/// get the params
const std::map<std::string, Instance*> &getParams() const;
/// get the params
const std::list<Instance*> &getParamList() const;
// get the param
Instance* getParam(const std::string &name) const {
std::map<std::string,Instance*>::const_iterator it = _params.find(name);
if(it!=_params.end())
return it->second;
else
return 0;
}
/// The inheriting plugin instance needs to set this up to deal with
/// plug-ins changing their own values.
virtual void paramChangedByPlugin(Param::Instance *param) = 0;
/// add a param
virtual OfxStatus addParam(const std::string& name, Instance* instance);
/// make a parameter instance
///
/// Client host code needs to implement this
virtual Instance* newParam(const std::string& name, Descriptor& Descriptor) = 0;
/// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditBegin
///
/// Client host code needs to implement this
virtual OfxStatus editBegin(const std::string& name) = 0;
/// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditEnd
///
/// Client host code needs to implement this
virtual OfxStatus editEnd() = 0;
};
}
}
}
#endif // OFXH_PARAM_H
@@ -0,0 +1,87 @@
#ifndef OFX_PLUGIN_API_CACHE
#define OFX_PLUGIN_API_CACHE
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <string>
#include <iostream>
#include <ostream>
#include <map>
#include "ofxhPropertySuite.h"
namespace OFX
{
namespace Host {
class Plugin;
class PluginBinary;
class PluginCache;
namespace ImageEffect {
class ImageEffectDescriptor;
}
}
}
namespace OFX
{
namespace Host
{
namespace APICache {
/// this acts as an interface for the Plugin Cache, handling api-specific cacheing
class PluginAPICacheI
{
protected:
std::string _apiName;
int _apiVersionMin, _apiVersionMax;
public:
PluginAPICacheI(const std::string &apiName, int verMin, int verMax)
: _apiName(apiName)
, _apiVersionMin(verMin)
, _apiVersionMax(verMax)
{
}
virtual ~PluginAPICacheI() {}
virtual void loadFromPlugin(Plugin *) const = 0;
/// factory method, to create a new plugin (from binary)
virtual Plugin *newPlugin(PluginBinary *, int pi, OfxPlugin *plug) = 0;
/// factory method, to create a new plugin (from the
virtual Plugin *newPlugin(PluginBinary *pb, int pi, const std::string &api, int apiVersion, const std::string &pluginId,
const std::string &rawId, int pluginMajorVersion, int pluginMinorVersion) = 0;
virtual void beginXmlParsing(Plugin *) = 0;
virtual void xmlElementBegin(const std::string &, std::map<std::string, std::string>) = 0;
virtual void xmlCharacterHandler(const std::string &) = 0;
virtual void xmlElementEnd(const std::string &) = 0;
virtual void endXmlParsing() = 0;
virtual void saveXML(Plugin *, std::ostream &) const = 0;
virtual void confirmPlugin(Plugin *) = 0;
virtual bool pluginSupported(Plugin *, std::string &reason) const = 0;
void registerInCache(OFX::Host::PluginCache &pluginCache);
};
/// helper function to build a property set from XML. Really should be a member of the property set!!!
void propertySetXMLRead(const std::string &el, std::map<std::string, std::string> map, Property::Set &set, Property::Property*&);
/// helper function to write a property set to XML. Really should be a member of the property set!!!
void propertySetXMLWrite(std::ostream &o, const Property::Set &set, int indent=0);
/// helper function to write a single property from a set to XML. Really should be a member of the property set!!!
void propertyXMLWrite(std::ostream &o, const Property::Set &set, const std::string &name, int indent=0);
}
}
}
#endif
+432
View File
@@ -0,0 +1,432 @@
#ifndef OFX_PLUGIN_CACHE_H
#define OFX_PLUGIN_CACHE_H
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <string>
#include <vector>
#include <list>
#include <set>
#include <iostream>
#include <stdio.h>
#include "expat.h"
#include "ofxCore.h"
#include "ofxhPropertySuite.h"
#include "ofxhPluginAPICache.h"
#include "ofxhBinary.h"
namespace OFX {
namespace Host {
class Host;
// forward delcarations
class PluginDesc;
class Plugin;
class PluginBinary;
class PluginCache;
/// C++ version of the information kept inside an OfxPlugin struct
class PluginDesc {
protected :
std::string _pluginApi; ///< the API I implement
int _apiVersion; ///< the version of the API
std::string _identifier; ///< the identifier of the plugin
std::string _rawIdentifier; ///< the original identifier of the plugin
int _versionMajor; ///< the plugin major version
int _versionMinor; ///< the plugin minor version
public:
const std::string &getPluginApi() const {
return _pluginApi;
}
int getApiVersion() const {
return _apiVersion;
}
const std::string &getIdentifier() const {
return _identifier;
}
const std::string &getRawIdentifier() const {
return _rawIdentifier;
}
int getVersionMajor() const {
return _versionMajor;
}
int getVersionMinor() const {
return _versionMinor;
}
PluginDesc() : _apiVersion(-1) {
}
virtual ~PluginDesc() {}
PluginDesc(const std::string &api,
int apiVersion,
const std::string &identifier,
const std::string &rawIdentifier,
int versionMajor,
int versionMinor)
: _pluginApi(api)
, _apiVersion(apiVersion)
, _identifier(identifier)
, _rawIdentifier(rawIdentifier)
, _versionMajor(versionMajor)
, _versionMinor(versionMinor)
{
}
/// constructor for the case where we have already loaded the plugin binary and
/// are populating this object from it
PluginDesc(OfxPlugin *ofxPlugin) {
_pluginApi = ofxPlugin->pluginApi;
_apiVersion = ofxPlugin->apiVersion;
_rawIdentifier = ofxPlugin->pluginIdentifier;
_identifier = ofxPlugin->pluginIdentifier;
// Who says the pluginIdentifier is case-insensitive? OFX 1.3 spec doesn't mention this.
// http://openfx.sourceforge.net/Documentation/1.3/ofxProgrammingReference.html#id472588
//for (size_t i=0;i<_identifier.size();i++) {
// _identifier[i] = tolower(_identifier[i]);
//}
_versionMajor = ofxPlugin->pluginVersionMajor;
_versionMinor = ofxPlugin->pluginVersionMinor;
}
};
/// class that we use to manipulate a plugin
class Plugin : public PluginDesc {
/// owned by the PluginBinary it lives inside
/// Plugins can only be pass about either by pointer or reference
private :
Plugin(const Plugin&) : PluginDesc() {} ///< hidden
Plugin &operator= (const Plugin&) {return *this;} ///< hidden
protected :
PluginBinary *_binary; ///< the file I live inside
int _index; ///< where I live inside that file
public :
Plugin();
PluginBinary *getBinary()
{
return _binary;
}
const PluginBinary *getBinary() const
{
return _binary;
}
int getIndex() const
{
return _index;
}
/// construct this based on the struct returned by the getNthPlugin() in the binary
Plugin(PluginBinary *bin, int idx, OfxPlugin *o) : PluginDesc(o), _binary(bin), _index(idx)
{
}
/// construct me from the cache
Plugin(PluginBinary *bin, int idx, const std::string &api,
int apiVersion, const std::string &identifier,
const std::string &rawIdentifier,
int majorVersion, int minorVersion)
: PluginDesc(api, apiVersion, identifier, rawIdentifier, majorVersion, minorVersion)
, _binary(bin)
, _index(idx)
{
}
virtual ~Plugin() {
}
virtual APICache::PluginAPICacheI &getApiHandler() = 0;
bool trumps(Plugin *other) {
int myMajor = getVersionMajor();
int theirMajor = other->getVersionMajor();
int myMinor = getVersionMinor();
int theirMinor = other->getVersionMinor();
if (myMajor > theirMajor) {
return true;
}
if (myMajor == theirMajor && myMinor > theirMinor) {
return true;
}
return false;
}
};
class PluginHandle;
/// class that represents a binary file which holds plugins
class PluginBinary {
/// has a set of plugins inside it and which it owns
/// These are owned by a PluginCache
friend class PluginHandle;
protected :
Binary _binary; ///< our binary object, abstracted layer ontop of OS calls, defined in ofxhBinary.h
std::string _filePath; ///< full path to the file
std::string _bundlePath; ///< path to the .bundle directory
std::vector<Plugin *> _plugins; ///< my plugins
time_t _fileModificationTime; ///< used as a time stamp to check modification times, used for caching
off_t _fileSize; ///< file size last time we check, used for caching
bool _binaryChanged; ///< whether the timestamp/filesize in this cache is different from that in the actual binary
public :
/// create one from the cache. this will invoke the Binary() constructor which
/// will stat() the file.
explicit PluginBinary(const std::string &file, const std::string &bundlePath, time_t mtime, off_t size)
: _binary(file)
, _filePath(file)
, _bundlePath(bundlePath)
, _fileModificationTime(mtime)
, _fileSize(size)
, _binaryChanged(false)
{
if (isInvalid()) {
return;
}
if (_fileModificationTime != _binary.getTime() || _fileSize != _binary.getSize()) {
_binaryChanged = true;
}
}
/// constructor which will open a library file, call things inside it, and then
/// create Plugin objects as appropriate for the plugins exported therefrom
explicit PluginBinary(const std::string &file, const std::string &bundlePath, PluginCache *cache)
: _binary(file)
, _filePath(file)
, _bundlePath(bundlePath)
, _binaryChanged(false)
{
loadPluginInfo(cache);
}
/// dtor
virtual ~PluginBinary();
time_t getFileModificationTime() const {
return _fileModificationTime;
}
off_t getFileSize() {
return _fileSize;
}
const std::string &getFilePath() const {
return _filePath;
}
const std::string &getBundlePath() const {
return _bundlePath;
}
bool hasBinaryChanged() const {
return _binaryChanged;
}
bool isLoaded() const {
return _binary.isLoaded();
}
bool isInvalid() const {
return _binary.isInvalid();
}
void addPlugin(Plugin *pe) {
_plugins.push_back(pe);
}
void loadPluginInfo(PluginCache *);
/// how many plugins?
int getNPlugins() const {return (int)_plugins.size(); }
/// get a plugin
Plugin &getPlugin(int idx) {return *_plugins[idx];}
/// get a plugin
const Plugin &getPlugin(int idx) const {return *_plugins[idx];}
};
/// wrapper class for Plugin/PluginBinary. use in a RAIA fashion to make sure the binary gets unloaded when needed and not before.
class PluginHandle {
PluginBinary *_b;
OfxPlugin *_op;
public:
PluginHandle(Plugin *p, OFX::Host::Host *_host);
virtual ~PluginHandle();
OfxPlugin *getOfxPlugin() {
return _op;
}
OfxPlugin *operator->() {
return _op;
}
};
/// for later
struct PluginCacheSupportedApi {
std::string api;
int minVersion;
int maxVersion;
APICache::PluginAPICacheI *handler;
PluginCacheSupportedApi(const std::string &_api, int _minVersion, int _maxVersion, APICache::PluginAPICacheI *_handler) :
api(_api), minVersion(_minVersion), maxVersion(_maxVersion), handler(_handler)
{
}
bool matches(const std::string &_api, int _version) const
{
if (_api == api && _version >= minVersion && _version <= maxVersion) {
return true;
}
return false;
}
};
/// Where we keep our plugins.
class PluginCache {
protected :
OFX::Host::Property::PropSpec* _hostSpec;
std::list<std::string> _pluginPath; ///< list of directories to look in
std::set<std::string> _nonrecursePath; ///< list of directories to look in (non-recursively)
std::list<std::string> _pluginDirs; ///< list of directories we found
std::list<PluginBinary *> _binaries; ///< all the binaries we know about, we own these
std::list<Plugin *> _plugins; ///< all the plugins inside the binaries, we don't own these, populated from _binaries
std::set<std::string> _knownBinFiles;
PluginBinary *_xmlCurrentBinary;
Plugin *_xmlCurrentPlugin;
std::list<PluginCacheSupportedApi> _apiHandlers;
void scanDirectory(std::set<std::string> &foundBinFiles, const std::string &dir, bool recurse);
bool _ignoreCache;
std::string _cacheVersion;
bool _dirty;
bool _enablePluginSeek; ///< Turn off to make all seekPluginFile() calls return an empty string
static PluginCache* gPluginCachePtr; ///< singleton plugin cache
public:
/// ctor, which inits _pluginPath to default locations and not much else
PluginCache();
/// dtor
~PluginCache();
/// get our plugin cache
static PluginCache* getPluginCache();
/// clear our plugin cache
static void clearPluginCache();
/// get the list in which plugins are sought
const std::list<std::string> &getPluginPath() {
return _pluginPath;
}
/// was the cache outdated?
bool dirty() const {
return _dirty;
}
/// add a file to the plugin path
void addFileToPath(const std::string &f, bool recurse=true) {
_pluginPath.push_back(f);
if (!recurse) {
_nonrecursePath.insert(f);
}
}
/// prepend a file to the plugin path
void prependFileToPath(const std::string &f, bool recurse=true) {
_pluginPath.push_front(f);
if (!recurse) {
_nonrecursePath.insert(f);
}
}
/// specify which subdirectory of /usr/OFX or equivilant
/// (as well as 'Plugins') to look in for plugins.
void setPluginHostPath(const std::string &hostId);
/// set the version string to write to the cache,
/// and also that we expect on cachess read in
void setCacheVersion(const std::string &cacheVersion) {
_cacheVersion = cacheVersion;
}
// populate the cache. must call scanPluginFiles() after to check for changes.
void readCache(std::istream &is);
// seek a particular file on the OFX plugin path
std::string seekPluginFile(const std::string &baseName) const;
/// Sets behaviour of seekPluginFile().
/// Enable (the default): normal operation; disable: returns an empty string instead
void setPluginSeekEnabled(bool enabled) { _enablePluginSeek = enabled; }
/// scan for plugins
void scanPluginFiles();
// write the plugin cache output file to the given stream
void writePluginCache(std::ostream &os) const;
// callback function for the XML
void elementBeginCallback(void *userData, const XML_Char *name, const XML_Char **attrs);
void elementCharCallback(void *userData, const XML_Char *data, int len);
void elementEndCallback(void *userData, const XML_Char *name);
/// register an API cache handler
void registerAPICache(const std::string &api, int min, int max, APICache::PluginAPICacheI *apiCache) {
_apiHandlers.push_back(PluginCacheSupportedApi(api, min, max, apiCache));
}
/// find the API cache handler for the given api/apiverson
APICache::PluginAPICacheI* findApiHandler(const std::string &api, int apiver);
/// obtain a list of plugins to walk through
const std::list<Plugin *> &getPlugins() const {
return _plugins;
}
};
}
}
#endif
+34
View File
@@ -0,0 +1,34 @@
#ifndef _ofxhProgress_h_
#define _ofxhProgress_h_
#include "ofxProgress.h"
namespace OFX {
namespace Host {
namespace Progress {
/// Things that display progress derive from this ABC and implement the following
/// functions.
class ProgressI {
public :
virtual ~ProgressI() {}
/// Start doing progress.
virtual void progressStart(const std::string &message, const std::string &messageid) = 0;
/// finish yer progress
virtual void progressEnd() = 0;
/// set the progress to some level of completion, returns
/// false if you should abandon processing, true to continue
virtual bool progressUpdate(double t) = 0;
};
} // namespace progress
} // namespace Host
} // namespace OFX
#endif
@@ -0,0 +1,545 @@
#ifndef OFX_PROPERTY_SUITE_H
#define OFX_PROPERTY_SUITE_H
#include "ofxCore.h"
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <sstream>
namespace OFX {
namespace Host {
namespace Property {
/// simple function to turn a thing into a std string
template<class T> inline std::string castToString(T i) {
std::ostringstream o;
o << i;
return o.str();
}
/// simple function to turn a string into an int
inline int stringToInt(const std::string &s) {
std::istringstream is(s);
int number;
is >> number;
return number;
}
/// simple function to turn a string into a double
inline double stringToDouble(const std::string &s) {
std::istringstream is(s);
double number;
is >> number;
return number;
}
// forward declarations
class Property;
class Set;
/// exception, representing an OfxStatus
class Exception {
OfxStatus _stat;
public:
/// ctor
Exception(OfxStatus stat) : _stat(stat)
{
}
/// get the status
OfxStatus getStatus() const
{
return _stat;
}
};
/// type of a property
enum TypeEnum {
eNone = -1,
eInt = 0,
eDouble = 1,
eString = 2,
ePointer = 3
};
/// type holder, for integers, used to template up int properties
struct IntValue {
typedef int APIType; ///< C type of the property that is passed across the raw API
typedef int APITypeConstless; ///< C type of the property that is passed across the raw API, without any const it
typedef int Type; ///< Type we actually hold and deal with the propery in everything by the raw API
typedef int ReturnType; ///< type to return from a function call
static const TypeEnum typeCode = eInt;
static int kEmpty;
};
/// type holder, for doubles, used to template up double properties
struct DoubleValue {
typedef double APIType;
typedef double APITypeConstless;
typedef double Type;
typedef double ReturnType; ///< type to return from a function call
static const TypeEnum typeCode = eDouble;
static double kEmpty;
};
/// type holder, for pointers, used to template up pointer properties
struct PointerValue {
typedef void *APIType;
typedef void *APITypeConstless;
typedef void *Type;
typedef void *ReturnType; ///< type to return from a function call
static const TypeEnum typeCode = ePointer;
static void *kEmpty;
};
/// type holder, for strings, used to template up string properties
struct StringValue {
typedef const char *APIType;
typedef char *APITypeConstless;
typedef std::string Type;
typedef const std::string &ReturnType; ///< type to return from a function call
static const TypeEnum typeCode = eString;
static std::string kEmpty;
};
/// array representing the names of the various types, in order of TypeEnum
extern const char *gTypeNames[];
/// Sits on a property and can override the local property value when a value is being fetched
/// only one of these can be in any property (as the thing has only a single value).
class GetHook {
public :
/// dtor
virtual ~GetHook()
{
}
/// We specialise this to do some magic so that it calls get string/int/double/pointer appropriately
/// this is what is called by the propertytemplate code to fetch values out of a hook.
template<class T> typename T::ReturnType getProperty(const std::string &name, int index=0) const;
/// We specialise this to do some magic so that it calls get int/double/pointer appropriately
/// this is what is called by the propertytemplate code to fetch values out of a hook.
template<class T> void getPropertyN(const std::string &name, typename T::APIType *values, int count) const;
/// override this to fetch a single value at the given index.
virtual const std::string& getStringProperty(const std::string &name, int index = 0) const;
/// override this to fetch a multiple values in a multi-dimension property
virtual void getStringPropertyN(const std::string &name, const char** values, int count) const;
/// override this to fetch a single value at the given index.
virtual int getIntProperty(const std::string &name, int index = 0) const;
/// override this to fetch a multiple values in a multi-dimension property
virtual void getIntPropertyN(const std::string &name, int *values, int count) const;
/// override this to fetch a single value at the given index.
virtual double getDoubleProperty(const std::string &name, int index = 0) const;
/// override this to fetch a multiple values in a multi-dimension property
virtual void getDoublePropertyN(const std::string &name, double *values, int count) const;
/// override this to fetch a single value at the given index.
virtual void *getPointerProperty(const std::string &name, int index = 0) const;
/// override this to fetch a multiple values in a multi-dimension property
virtual void getPointerPropertyN(const std::string &name, void **values, int count) const;
/// override this to fetch the dimension size.
virtual int getDimension(const std::string &name) const;
/// override this to handle a reset().
virtual void reset(const std::string &name);
};
/// Sits on a property and is called when the local property is being set.
/// It notify or notifyN is called whenever the plugin sets a property
/// Many of these can sit on a property, as various objects will need to know when a property
/// has been changed. On notification you should fetch properties with a 'raw' call, rather
/// than the standard calls, as you may be fetching through a getHook and you won't see
/// the local value that has been shoved into the property.
class NotifyHook {
public :
/// dtor
virtual ~NotifyHook() {}
/// override this to be notified when a property changes
/// \arg name is the name of the property just set
/// \arg singleValue is whether setProperty on a single index was call, otherwise N properties were set
/// \arg indexOrN is the index if single value is true, or the count if singleValue is false
virtual void notify(const std::string &name, bool singleValue, int indexOrN) = 0;
};
/// base class for all properties
class Property {
protected :
std::string _name; ///< name of this property
TypeEnum _type; ///< type of this property
int _dimension; ///< the fixed dimension of this property
bool _pluginReadOnly; ///< set is forbidden through suite: value may still change between get() calls
std::vector<NotifyHook *> _notifyHooks; ///< hooks to call whenever the property is set
GetHook *_getHook; ///< if we are not storing props locally, they are stored via fetching from here
friend class Set;
public :
/// ctor
Property(const std::string &name,
TypeEnum type,
int dimension = 1,
bool pluginReadOnly=false);
/// copy ctor
Property(const Property &other);
/// dtor
virtual ~Property()
{
}
/// is it read only?
bool getPluginReadOnly() const {return _pluginReadOnly; }
/// change the state of readonlyness
void setPluginReadOnly(bool v) {_pluginReadOnly = v;}
/// override this to return a clone of the property
virtual Property *deepCopy() = 0;
/// get the name of this property
const std::string &getName()
{
return _name;
}
/// get the type of this property
TypeEnum getType()
{
return _type;
}
/// add a notify hook
void addNotifyHook(NotifyHook *hook)
{
_notifyHooks.push_back(hook);
}
/// set the get hook
void setGetHook(GetHook *hook)
{
_getHook = hook;
}
/// call notify on the contained notify hooks
void notify(bool single, int indexOrN);
// get the current dimension of this property
virtual int getDimension() const = 0;
/// get the fixed dimension of this property
int getFixedDimension() const {
return _dimension;
}
/// are we a fixed dim property
bool isFixedSize() const
{
return _dimension != 0;
}
/// reset this property to the default
virtual void reset() = 0;
// get a string representing the value of this property at element nth
virtual std::string getStringValue(int nth) = 0;
};
/// this represents a generic property.
/// template parameter T is the type descriptor of the
/// type of property to model. the class holds an internal _value vector which can be used
/// to store the values. if set and get hooks are installed, these will be called instead
/// of using this variable.
/// Make sure that T::ReturnType is const if appropriate, as no extra qualifiers are applied here.
template<class T>
class PropertyTemplate : public Property
{
public :
typedef typename T::Type Type;
typedef typename T::ReturnType ReturnType;
typedef typename T::APIType APIType;
protected :
/// this is the present value of the property
std::vector<Type> _value;
/// this is the default value of the property
std::vector<Type> _defaultValue;
public :
/// constructor
PropertyTemplate(const std::string &name,
int dimension,
bool pluginReadOnly,
APIType defaultValue);
PropertyTemplate(const PropertyTemplate<T> &pt);
PropertyTemplate<T> *deepCopy() {
return new PropertyTemplate(*this);
}
virtual ~PropertyTemplate()
{
}
/// get the vector
const std::vector<Type> &getValues()
{
return _value;
}
// get multiple values
void getValueN(APIType *value, int count) const;
#ifdef WINDOWS
#pragma warning( disable : 4181 )
#endif
/// get one value
const ReturnType getValue(int index=0) const;
/// get one value, without going through the getHook
const ReturnType getValueRaw(int index=0) const;
#ifdef WINDOWS
#pragma warning( default : 4181 )
#endif
// get multiple values, without going through the getHook
void getValueNRaw(APIType *value, int count) const;
/// set one value
void setValue(const Type &value, int index=0);
/// set multiple values
void setValueN(const APIType *value, int count);
/// reset
void reset();
/// get the size of the vector
int getDimension() const;
/// return the value as a string
inline std::string getStringValue(int idx) {
return castToString(_value[idx]);
}
};
typedef PropertyTemplate<IntValue> Int; /// Our int property
typedef PropertyTemplate<DoubleValue> Double; /// Our double property
typedef PropertyTemplate<StringValue> String; /// Our string property
typedef PropertyTemplate<PointerValue> Pointer; /// Our pointer property
/// A class that is used to initialise a property set. Feed in an array of these to
/// a property and it will construct a bunch of properties. Terminate such an array
/// with an empty (all zero) set.
struct PropSpec {
const char *name; ///< name of the property
TypeEnum type; ///< type
int dimension; ///< fixed dimension of the property, set to zero if variable dimension
bool readonly; ///< is the property plug-in read only
const char *defaultValue; ///< Default value as a string. Pointers are ignored and always null.
};
static const PropSpec propSpecEnd = {0, eNone, 0, false, 0};
/// A std::map of properties by name
typedef std::map<std::string, Property *> PropertyMap;
//................................................................................
/// Class that holds a set of properties and manipulates them
/// The 'fetch' methods return a property object.
/// The 'get' methods return a property value
class Set {
private :
static const int kMagic = 0x12082007; ///< magic number for property sets, and Connie's birthday :-)
const int _magic; ///< to check for handles being nice
protected :
PropertyMap _props; ///< Our properties.
/// chained property set, which is read only
/// these are searched on a get if not found
/// on a local search
Set *_chainedSet;
/// hide assignment
void operator=(const Set &);
/// set a particular property
template<class T> void setProperty(const std::string &property, int index, const typename T::Type &value);
/// set the first N of a particular property
template<class T> void setPropertyN(const std::string &property, int count, const typename T::APIType *value);
/// get a particular property
template<class T> typename T::ReturnType getProperty(const std::string &property, int index) const;
/// get the first N of a particular property
template<class T> void getPropertyN(const std::string &property, int index, typename T::APIType *v) const;
/// get a particular property without going through any getHook
template<class T> typename T::ReturnType getPropertyRaw(const std::string &property, int index) const;
/// get a particular property without going through any getHook
template<class T> void getPropertyRawN(const std::string &property, int count, typename T::APIType *v) const;
public :
/// take an array of of PropSpecs (which must be terminated with an entry in which
/// ->name is null), and turn these into a Set
explicit Set(const PropSpec *);
/// deep copies the property set
explicit Set(const Set &);
/// empty ctor
explicit Set();
/// destructor
virtual ~Set();
/// adds a bunch of properties from PropSpec
void addProperties(const PropSpec *);
/// add one new property
void createProperty(const PropSpec &s);
/// add one new property
void addProperty(Property *prop);
/// set the chained property set
void setChainedSet(Set *s) {_chainedSet = s;}
/// grab the internal properties map
const PropertyMap &getProperties() const
{
return _props;
}
/// set the get hook for a particular property. users may need to call particular
/// specialised versions of this.
void setGetHook(const std::string &s, GetHook *ghook) const;
/// add a set hook for a particular property. users may need to call particular
/// specialised versions of this.
void addNotifyHook(const std::string &name, NotifyHook *hook) const;
/// Fetchs a pointer to a property of the given name, following the property chain if the
/// 'followChain' arg is not false.
Property *fetchProperty(const std::string &name, bool followChain = false) const;
/// get property with the particular name and type. if the property is
/// missing or is of the wrong type, return an error status. if this is a sloppy
/// property set and the property is missing, a new one will be created of the right
/// type
template<class T> bool fetchTypedProperty(const std::string &name, T *&prop, bool followChain = false) const;
/// retrieve the nameed string property
String *fetchStringProperty(const std::string &name, bool followChain = false) const;
/// retrieve the named double property
Double *fetchDoubleProperty(const std::string &name, bool followChain = false) const;
/// retrieve the named double property
Pointer *fetchPointerProperty(const std::string &name, bool followChain = false) const;
/// retrieve the named double property
Int *fetchIntProperty(const std::string &name, bool followChain = false) const;
/// get a particular int property without fetching via a get hook, useful for notifies
int getIntPropertyRaw(const std::string &property, int index = 0) const;
/// get a particular double property without fetching via a get hook, useful for notifies
double getDoublePropertyRaw(const std::string &property, int index = 0) const;
/// get a particular pointer property without fetching via a get hook, useful for notifies
void *getPointerPropertyRaw(const std::string &property, int index = 0) const;
/// get a particular string property
const std::string &getStringPropertyRaw(const std::string &property, int index = 0) const;
/// get the value of a particular string property
const std::string &getStringProperty(const std::string &property, int index = 0) const;
/// get the value of a particular int property
int getIntProperty(const std::string &property, int index = 0) const;
/// get the value of a particular double property
void getIntPropertyN(const std::string &property, int *v, int N) const;
/// get the value of a particular double property
double getDoubleProperty(const std::string &property, int index = 0) const;
/// get the value of a particular double property
void getDoublePropertyN(const std::string &property, double *v, int N) const;
/// get the value of a particular pointer property
void *getPointerProperty(const std::string &property, int index = 0) const;
/// set a particular string property without fetching via a get hook, useful for notifies
void setStringProperty(const std::string &property, const std::string &value, int index = 0);
/// get a particular int property
void setIntProperty(const std::string &property, int v, int index = 0);
/// get a particular double property
void setIntPropertyN(const std::string &property, const int *v, int N);
/// get a particular double property
void setDoubleProperty(const std::string &property, double v, int index = 0);
/// get a particular double property
void setDoublePropertyN(const std::string &property, const double *v, int N);
/// get a particular double property
void setPointerProperty(const std::string &property, void *v, int index = 0);
/// get the dimension of a particular property
int getDimension(const std::string &property) const;
/// is the given string one of the values of a multi-dimensional string prop
/// this returns a non negative index if it is found, otherwise, -1
int findStringPropValueIndex(const std::string &propName,
const std::string &propValue) const;
/// get a handle on this object for passing to the C API
OfxPropertySetHandle getHandle() const
{
return (OfxPropertySetHandle)this;
}
/// is this a nice property set, or a dodgy pointer passed back to us
bool verifyMagic() { return _magic == kMagic; }
};
/// return the OFX function suite that manages properties
const void *GetSuite(int version);
}
}
}
#endif
+34
View File
@@ -0,0 +1,34 @@
#ifndef _ofxhTimeLine_h_
#define _ofxhTimeLine_h_
#include "ofxTimeLine.h"
namespace OFX::Host::TimeLine {
/// Things that implement timeline controls derive from this ABC and implement the following
/// functions.
class TimeLineI {
public :
virtual ~TimeLineI() = default;
/// get the current time on the timeline. This is not necessarily the same
/// time as being passed to an action (eg render)
virtual double timeLineGetTime() = 0;
/// set the timeline to a specific time
virtual void timeLineGotoTime(double t) = 0;
/// get the first and last times available on the effect's timeline
virtual void timeLineGetBounds(double &t1, double &t2) = 0;
};
} // namespace progress
#endif
+154
View File
@@ -0,0 +1,154 @@
#ifndef _ofxhUtilities_h_
#define _ofxhUtilities_h_
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
#include <string>
#include <list>
#include <vector>
#include "ofxCore.h"
// macro that intercepts any exception that passes through a plugin's entry point, and transforms it into a message on the host using Host::vmessage()
#define CatchAllSetStatus(stat,host,plugin,msg) \
catch ( const std::bad_alloc& ba ) { \
(stat) = kOfxStatErrMemory; \
if (host) { \
try { \
(host)->message(kOfxMessageError, "", \
"%s: Memory allocation error occured in plugin %s (%s)", \
(msg), (plugin)->pluginIdentifier, ba.what()); \
} catch (...) { \
} \
} \
} catch ( const std::exception &e ) { \
(stat) = kOfxStatFailed; \
if (host) { \
try { \
(host)->message(kOfxMessageError, "", \
"%s: Exception occured in plugin %s (%s)", \
(msg), (plugin)->pluginIdentifier, e.what()); \
} catch (...) { \
} \
} \
} catch ( ... ) { \
(stat) = kOfxStatFailed; \
if (host) { \
try { \
(host)->message(kOfxMessageError, "", \
"%s:Exception occured in plugin %s", \
(msg), (plugin)->pluginIdentifier); \
} catch (...) { \
} \
} \
}
namespace OFX {
/// class that is a std::vector of std::strings
typedef std::vector<std::string> StringVec;
/// class that is a std::vector of std::strings
inline void SetStringVecValue(StringVec &sv, const std::string &value, size_t index = 0)
{
size_t size = sv.size();
if(size <= index) {
while(size < index) {
sv.push_back("");
++size;
}
sv.push_back(value);
}
else
sv[index] = value;
}
/// get me deepest bit depth
std::string FindDeepestBitDepth(const std::string &s1, const std::string &s2);
/// get the min value
template<class T> inline T Minimum(const T &a, const T &b)
{
return a < b ? a : b;
}
/// get the min value
template<class T> inline T Maximum(const T &a, const T &b)
{
return a > b ? a : b;
}
/// clamp the value
template<class T> inline T Clamp(const T &v, const T &mn, const T &mx)
{
if(v < mn) return mn;
if(v > mx) return mx;
return v;
}
/// clamp the rect in v to the given bounds
inline OfxRectD Clamp(const OfxRectD &v,
const OfxRectD &bounds)
{
OfxRectD r;
r.x1 = Clamp(v.x1, bounds.x1, bounds.x2);
r.x2 = Clamp(v.x2, bounds.x1, bounds.x2);
r.y1 = Clamp(v.y1, bounds.y1, bounds.y2);
r.y2 = Clamp(v.y2, bounds.y1, bounds.y2);
return r;
}
/// get the union of the two rects
inline OfxRectD Union(const OfxRectD &a,
const OfxRectD &b)
{
OfxRectD r;
r.x1 = Minimum(a.x1, b.x1);
r.x2 = Maximum(a.x2, b.x2);
r.y1 = Minimum(a.y1, b.y1);
r.y2 = Maximum(a.y2, b.y2);
return r;
}
inline const char* StatStr(OfxStatus stat) {
switch(stat) {
case kOfxStatOK:
return "kOfxStatOK";
case kOfxStatFailed:
return "kOfxStatFailed";
case kOfxStatErrFatal:
return "kOfxStatErrFatal";
case kOfxStatErrUnknown:
return "kOfxStatErrUnknown";
case kOfxStatErrMissingHostFeature:
return "kOfxStatErrMissingHostFeature";
case kOfxStatErrUnsupported:
return "kOfxStatErrUnsupported";
case kOfxStatErrExists:
return "kOfxStatErrExists";
case kOfxStatErrFormat:
return "kOfxStatErrFormat";
case kOfxStatErrMemory:
return "kOfxStatErrMemory";
case kOfxStatErrBadHandle:
return "kOfxStatErrBadHandle";
case kOfxStatErrBadIndex:
return "kOfxStatErrBadIndex";
case kOfxStatErrValue:
return "kOfxStatErrValue";
case kOfxStatReplyYes:
return "kOfxStatReplyYes";
case kOfxStatReplyNo:
return "kOfxStatReplyNo";
case kOfxStatReplyDefault:
return "kOfxStatReplyDefault";
default:
return "(unknown error code)";
}
}
}
#endif
+74
View File
@@ -0,0 +1,74 @@
#ifndef OFX_XML_H
#define OFX_XML_H
// Copyright OpenFX and contributors to the OpenFX project.
// SPDX-License-Identifier: BSD-3-Clause
namespace OFX {
namespace XML {
inline std::string escape(const std::string &s) {
std::string ns;
for (size_t i=0;i<s.size();i++) {
// The are exactly five characters which must be escaped
// http://www.w3.org/TR/xml/#syntax
switch (s[i]) {
case '<':
ns += "&lt;";
break;
case '>':
ns += "&gt;";
break;
case '&':
ns += "&amp;";
break;
case '"':
ns += "&quot;";
break;
case '\'':
ns += "&apos;";
break;
default: {
unsigned char c = (unsigned char)(s[i]);
// Escape even the whitespace characters '\n' '\r' '\t', although they are valid
// XML, because they would be converted to space when re-read.
// See http://www.w3.org/TR/xml/#AVNormalize
if ((0x01 <= c && c <= 0x1f) || (0x7F <= c && c <= 0x9F)) {
// these characters must be escaped in XML 1.1
// http://www.w3.org/TR/xml/#sec-references
ns += "&#x";
if (c > 0xf) {
int d = c / 0x10;
ns += d < 10 ? ('0' + d) : ('A' + d - 10);
}
int d = c & 0xf;
ns += d < 10 ? ('0' + d) : ('A' + d - 10);
ns += ';';
} else {
ns += s[i];
}
} break;
}
}
return ns;
}
inline std::string attribute(const std::string &at, const std::string &val)
{
return at + "=" + "\"" + escape(val) + "\" ";
}
inline std::string attribute(const std::string &st, int val)
{
std::ostringstream o;
o << val;
return attribute(st, o.str());
}
}
}
#endif