change: Switch to offical OpenFX Support. Still can't compile.
This commit is contained in:
Vendored
-1
Submodule third_party/openfx deleted from 6aa45d8179
+37
@@ -0,0 +1,37 @@
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Dependent upon the following
|
||||
|
||||
*the expat library (expat.h) - to parse XML
|
||||
*ofx header files
|
||||
|
||||
How to build the library
|
||||
------------------------
|
||||
|
||||
UNIX
|
||||
- simply type 'make' in this directory, it will create 'libofxHost.a' in directory ./lib
|
||||
- the Makefile assumes expat is installed in a standard system location, if it is not,
|
||||
you need to do the following
|
||||
|
||||
make EXPAT_INCLUDE=-IDIRECTORY_WITH_EXPAT
|
||||
|
||||
WINDOWS
|
||||
- use the vc8 projects
|
||||
|
||||
|
||||
How to build the examples
|
||||
------------------------
|
||||
|
||||
UNIX
|
||||
- make the ofxHostLib.a library
|
||||
- in the examples directory type 'make',
|
||||
- the Makefile assumes expat is installed in a standard system location, if it is not,
|
||||
you need to do the following
|
||||
|
||||
make EXPAT_INCLUDE=-IDIRECTORY_WITH_EXPAT EXPAT_LIB=SOMEWHERE/libexpat.a
|
||||
|
||||
WINDOWS
|
||||
- use the vc8 projects
|
||||
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
set(OFX_HOSTSUPPORT_HEADER_DIR "include")
|
||||
set(OFX_HOSTSUPPORT_LIBRARY_DIR "src")
|
||||
set(OFX_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../include")
|
||||
aux_source_directory(OFX_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../include")
|
||||
file(GLOB_RECURSE OFX_HOSTSUPPORT_HEADER_FILES "${OFX_HOSTSUPPORT_HEADER_DIR}/*.h")
|
||||
file(GLOB_RECURSE OFX_HOSTSUPPORT_LIBRARY_FILES "${OFX_HOSTSUPPORT_LIBRARY_DIR}/*.cpp")
|
||||
add_library(OfxHost STATIC
|
||||
${OFX_HEADER_FILES}
|
||||
${OFX_HOSTSUPPORT_HEADER_FILES}
|
||||
${OFX_HOSTSUPPORT_LIBRARY_FILES})
|
||||
|
||||
set_target_properties(OfxHost PROPERTIES LINKER_LANGUAGE CXX)
|
||||
if(NOT MSVC)
|
||||
set_target_properties(OfxHost PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
endif()
|
||||
|
||||
target_link_libraries(OfxHost PUBLIC expat::expat)
|
||||
|
||||
target_include_directories(OfxHost PUBLIC
|
||||
${OFX_HEADER_DIR}
|
||||
${OFX_HOSTSUPPORT_HEADER_DIR}
|
||||
${expat_INCLUDE_DIR})
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
This directory contains source to an implementation of an OFX host C++ support library.
|
||||
This library skins the raw C API with a C++ layer, which is easy to program and abstracts
|
||||
the base API.
|
||||
|
||||
It does several things,
|
||||
- skins the C API with C++ classes, the host application 'only' needs to
|
||||
- derive several classes
|
||||
- implement a bunch of virtual methods
|
||||
- set some OFX properties
|
||||
- does most of the complicated logic in OFX,
|
||||
- regions of interest calls
|
||||
- clip preferences calls
|
||||
- provides a persistent plug-in caching mechanism so that
|
||||
- newly installed plug-ins are described into a cache file,
|
||||
- the cache persists as an XML file with enough information
|
||||
to construct simple menus etc..
|
||||
- once cached, plug-ins need only be loaded on demand.
|
||||
- is extensible beyond the base API,
|
||||
- allows hosts to provide extra suites and properties fairly easily.
|
||||
- it is generic beyond ImageEffects APIs, so other APIs can be implemented
|
||||
on the core sections of it.
|
||||
|
||||
Apart from standard C and C++ libraries it is dependent on the expat XML library.
|
||||
|
||||
You'll still need to understand what the API actually does, its just that the implementation details that become easier.
|
||||
|
||||
The layer could do with some improvement, specifically,
|
||||
- support for the external XML resource file,
|
||||
- a degree more tidying up,
|
||||
- parameter interacts
|
||||
- more documentation.
|
||||
|
||||
Released under a BSD-style licence: see source.
|
||||
|
||||
Authors:
|
||||
Abigail Brady <abigail@thefoundry.co.uk>
|
||||
Andrew Whitmore <andy@thefoundry.co.uk>
|
||||
Bruno Nicoletti <bruno@thefoundry.co.uk>
|
||||
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
26/03/2007
|
||||
|
||||
Minimum implementation, which allows plugin descriptions to be cached. Includes property sets and
|
||||
property suite and implementation of plugin description. Support for describing in context and
|
||||
parameters not fully enabled.
|
||||
|
||||
29/03/2007
|
||||
|
||||
Support for describing in contexts and parameters. These are cached as well.
|
||||
|
||||
25/06/2007
|
||||
|
||||
Major overhaul of the thing,
|
||||
- propertys made simpler to use
|
||||
- re-namespaced several classes so that anything to do with image effects are
|
||||
in the ImageEffect namespace
|
||||
- made the host layer do the logic for several Image Effect actions
|
||||
- clip preferences
|
||||
- regions of interest
|
||||
- simplified the function signatures of the actions
|
||||
- the 'Host' class now acts as,
|
||||
- a factory,
|
||||
- a filter for constructed objects,
|
||||
- a description of the host application to the plugin.
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
Things to do. This is a wish list of features to add to the host layer...
|
||||
|
||||
Common Base Class for All Plugin Instances
|
||||
- currently using a void * to pass instance pointers to components that do not
|
||||
need to know about image effects (eg: interact base classes).
|
||||
- Should have a base 'Plugin::Instance' class that ImageEffect::Instance and any
|
||||
other kind of plugin instance should derive from.
|
||||
|
||||
XML Resource Support
|
||||
- have the host layer manage the external XML resource file and relabel things appropriately.
|
||||
|
||||
Support for Custom Params
|
||||
- not there yet
|
||||
- should have the host layer manage most of the custom param animation stuff as well.
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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 <= X < x2 Y values are y1 <= Y < 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 <= X < x2 Y values are y1 <= Y < 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 <= X < x2 Y values are y1 <= Y < 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 <= X < x2 Y values are y1 <= Y < 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 <= X < x2 Y values are y1 <= Y < 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 <= X < x2 Y values are y1 <= Y < 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
|
||||
@@ -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
@@ -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 ¶mName,
|
||||
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
@@ -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
@@ -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
@@ -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 ¶mType);
|
||||
|
||||
bool isIntParam(const std::string ¶mType);
|
||||
|
||||
/// 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 += "<";
|
||||
break;
|
||||
case '>':
|
||||
ns += ">";
|
||||
break;
|
||||
case '&':
|
||||
ns += "&";
|
||||
break;
|
||||
case '"':
|
||||
ns += """;
|
||||
break;
|
||||
case '\'':
|
||||
ns += "'";
|
||||
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
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
|
||||
|
||||
#include "ofxhBinary.h"
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
Binary::Binary(const std::string &binaryPath): _binaryPath(binaryPath), _invalid(false), _dlHandle(0), _users(0)
|
||||
{
|
||||
struct stat sb;
|
||||
if (stat(binaryPath.c_str(), &sb) != 0) {
|
||||
_invalid = true;
|
||||
_time = 0;
|
||||
_size = 0;
|
||||
}
|
||||
else {
|
||||
_time = sb.st_mtime;
|
||||
_size = sb.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// actually open the binary.
|
||||
void Binary::load()
|
||||
{
|
||||
if(_invalid)
|
||||
return;
|
||||
|
||||
#if defined (UNIX)
|
||||
_dlHandle = dlopen(_binaryPath.c_str(), RTLD_LAZY|RTLD_LOCAL);
|
||||
#else
|
||||
_dlHandle = LoadLibrary(_binaryPath.c_str());
|
||||
#endif
|
||||
if (_dlHandle == 0) {
|
||||
#if defined (UNIX)
|
||||
std::cerr << "couldn't open library " << _binaryPath << " because " << dlerror() << std::endl;
|
||||
#else
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
DWORD err = GetLastError();
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0, NULL);
|
||||
|
||||
std::cerr << "couldn't open library " << _binaryPath << " because " << (char*)lpMsgBuf << " was returned" << std::endl;
|
||||
if (lpMsgBuf != NULL) {
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
#endif
|
||||
_invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// close the binary
|
||||
void Binary::unload() {
|
||||
if (_dlHandle != 0) {
|
||||
#if defined (UNIX)
|
||||
dlclose(_dlHandle);
|
||||
#elif defined (WINDOWS)
|
||||
FreeLibrary(_dlHandle);
|
||||
#endif
|
||||
_dlHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 *Binary::findSymbol(const std::string &symbol) {
|
||||
if (_dlHandle != 0) {
|
||||
#if defined(UNIX)
|
||||
return dlsym(_dlHandle, symbol.c_str());
|
||||
#elif defined (WINDOWS)
|
||||
return (void*)GetProcAddress(_dlHandle, symbol.c_str());
|
||||
#endif
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Binary::ref()
|
||||
{
|
||||
if (_users == 0) {
|
||||
load();
|
||||
}
|
||||
_users++;
|
||||
}
|
||||
|
||||
void Binary::unref()
|
||||
{
|
||||
_users--;
|
||||
if (_users == 0) {
|
||||
unload();
|
||||
}
|
||||
if (_users < 0) {
|
||||
_users = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+654
@@ -0,0 +1,654 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// ofx
|
||||
#include "ofxCore.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhBinary.h"
|
||||
#include "ofxhPropertySuite.h"
|
||||
#include "ofxhClip.h"
|
||||
#include "ofxhImageEffect.h"
|
||||
#ifdef OFX_SUPPORTS_OPENGLRENDER
|
||||
#include "ofxGPURender.h"
|
||||
#endif
|
||||
|
||||
namespace OFX {
|
||||
|
||||
namespace Host {
|
||||
|
||||
namespace ImageEffect {
|
||||
|
||||
/// properties common to the desciptor and instance
|
||||
/// the desc and set them, the instance cannot
|
||||
static const Property::PropSpec clipDescriptorStuffs[] = {
|
||||
{ kOfxPropType, Property::eString, 1, true, kOfxTypeClip },
|
||||
{ kOfxPropName, Property::eString, 1, true, "SET ME ON CONSTRUCTION" },
|
||||
{ kOfxPropLabel, Property::eString, 1, false, "" } ,
|
||||
{ kOfxPropShortLabel, Property::eString, 1, false, "" },
|
||||
{ kOfxPropLongLabel, Property::eString, 1, false, "" },
|
||||
{ kOfxImageEffectPropSupportedComponents, Property::eString, 0, false, "" },
|
||||
{ kOfxImageEffectPropTemporalClipAccess, Property::eInt, 1, false, "0" },
|
||||
{ kOfxImageClipPropOptional, Property::eInt, 1, false, "0" },
|
||||
{ kOfxImageClipPropIsMask, Property::eInt, 1, false, "0" },
|
||||
{ kOfxImageClipPropFieldExtraction, Property::eString, 1, false, kOfxImageFieldDoubled },
|
||||
{ kOfxImageEffectPropSupportsTiles, Property::eInt, 1, false, "1" },
|
||||
Property::propSpecEnd,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// props to clips descriptors and instances
|
||||
|
||||
// base ctor, for a descriptor
|
||||
ClipBase::ClipBase()
|
||||
: _properties(clipDescriptorStuffs)
|
||||
{
|
||||
}
|
||||
|
||||
/// props to clips and
|
||||
ClipBase::ClipBase(const ClipBase &v)
|
||||
: _properties(v._properties)
|
||||
{
|
||||
/// we are an instance, we need to reset the props to read only
|
||||
const Property::PropertyMap &map = _properties.getProperties();
|
||||
Property::PropertyMap::const_iterator i;
|
||||
for(i = map.begin(); i != map.end(); ++i) {
|
||||
(*i).second->setPluginReadOnly(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// name of the clip
|
||||
const std::string &ClipBase::getShortLabel() const
|
||||
{
|
||||
const std::string &s = _properties.getStringProperty(kOfxPropShortLabel);
|
||||
if(s == "") {
|
||||
return getLabel();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// name of the clip
|
||||
const std::string &ClipBase::getLabel() const
|
||||
{
|
||||
const std::string &s = _properties.getStringProperty(kOfxPropLabel);
|
||||
if(s == "") {
|
||||
return getName();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// name of the clip
|
||||
const std::string &ClipBase::getLongLabel() const
|
||||
{
|
||||
const std::string &s = _properties.getStringProperty(kOfxPropLongLabel);
|
||||
if(s == "") {
|
||||
return getLabel();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// return a std::vector of supported comp
|
||||
const std::vector<std::string> &ClipBase::getSupportedComponents() const
|
||||
{
|
||||
Property::String *p = _properties.fetchStringProperty(kOfxImageEffectPropSupportedComponents);
|
||||
assert(p != NULL);
|
||||
return p->getValues();
|
||||
}
|
||||
|
||||
/// is the given component supported
|
||||
bool ClipBase::isSupportedComponent(const std::string &comp) const
|
||||
{
|
||||
return _properties.findStringPropValueIndex(kOfxImageEffectPropSupportedComponents, comp) != -1;
|
||||
}
|
||||
|
||||
/// does the clip do random temporal access
|
||||
bool ClipBase::temporalAccess() const
|
||||
{
|
||||
return _properties.getIntProperty(kOfxImageEffectPropTemporalClipAccess) != 0;
|
||||
}
|
||||
|
||||
/// is the clip optional
|
||||
bool ClipBase::isOptional() const
|
||||
{
|
||||
return _properties.getIntProperty(kOfxImageClipPropOptional) != 0;
|
||||
}
|
||||
|
||||
/// is the clip a nominal 'mask' clip
|
||||
bool ClipBase::isMask() const
|
||||
{
|
||||
return _properties.getIntProperty(kOfxImageClipPropIsMask) != 0;
|
||||
}
|
||||
|
||||
/// how does this clip like fielded images to be presented to it
|
||||
const std::string &ClipBase::getFieldExtraction() const
|
||||
{
|
||||
return _properties.getStringProperty(kOfxImageClipPropFieldExtraction);
|
||||
}
|
||||
|
||||
/// is the clip a nominal 'mask' clip
|
||||
bool ClipBase::supportsTiles() const
|
||||
{
|
||||
return _properties.getIntProperty(kOfxImageEffectPropSupportsTiles) != 0;
|
||||
}
|
||||
|
||||
const Property::Set& ClipBase::getProps() const
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
Property::Set& ClipBase::getProps()
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
/// get a handle on the properties of the clip descriptor for the C api
|
||||
OfxPropertySetHandle ClipBase::getPropHandle() const
|
||||
{
|
||||
return _properties.getHandle();
|
||||
}
|
||||
|
||||
/// get a handle on the clip descriptor for the C api
|
||||
OfxImageClipHandle ClipBase::getHandle() const
|
||||
{
|
||||
return (OfxImageClipHandle)this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// descriptor
|
||||
ClipDescriptor::ClipDescriptor(const std::string &name)
|
||||
: ClipBase()
|
||||
{
|
||||
_properties.setStringProperty(kOfxPropName,name);
|
||||
}
|
||||
|
||||
/// extra properties for the instance, these are fetched from the host
|
||||
/// via a get hook and some virtuals
|
||||
static const Property::PropSpec clipInstanceStuffs[] = {
|
||||
{ kOfxImageEffectPropPixelDepth, Property::eString, 1, true, kOfxBitDepthNone },
|
||||
{ kOfxImageEffectPropComponents, Property::eString, 1, true, kOfxImageComponentNone },
|
||||
{ kOfxImageClipPropUnmappedPixelDepth, Property::eString, 1, true, kOfxBitDepthNone },
|
||||
{ kOfxImageClipPropUnmappedComponents, Property::eString, 1, true, kOfxImageComponentNone },
|
||||
{ kOfxImageEffectPropPreMultiplication, Property::eString, 1, true, kOfxImageOpaque },
|
||||
{ kOfxImagePropPixelAspectRatio, Property::eDouble, 1, true, "1.0" },
|
||||
{ kOfxImageEffectPropFrameRate, Property::eDouble, 1, true, "25.0" },
|
||||
{ kOfxImageEffectPropFrameRange, Property::eDouble, 2, true, "0" },
|
||||
{ kOfxImageClipPropFieldOrder, Property::eString, 1, true, kOfxImageFieldNone },
|
||||
{ kOfxImageClipPropConnected, Property::eInt, 1, true, "0" },
|
||||
{ kOfxImageEffectPropUnmappedFrameRange, Property::eDouble, 2, true, "0" },
|
||||
{ kOfxImageEffectPropUnmappedFrameRate, Property::eDouble, 1, true, "25.0" },
|
||||
{ kOfxImageClipPropContinuousSamples, Property::eInt, 1, true, "0" },
|
||||
Property::propSpecEnd,
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// instance
|
||||
ClipInstance::ClipInstance(ImageEffect::Instance* effectInstance, ClipDescriptor& desc)
|
||||
: ClipBase(desc)
|
||||
, _effectInstance(effectInstance)
|
||||
, _isOutput(desc.isOutput())
|
||||
, _pixelDepth(kOfxBitDepthNone)
|
||||
, _components(kOfxImageComponentNone)
|
||||
{
|
||||
// this will a parameters that are needed in an instance but not a
|
||||
// Descriptor
|
||||
_properties.addProperties(clipInstanceStuffs);
|
||||
int i = 0;
|
||||
while(clipInstanceStuffs[i].name) {
|
||||
const Property::PropSpec& spec = clipInstanceStuffs[i];
|
||||
|
||||
switch (spec.type) {
|
||||
case Property::eDouble:
|
||||
case Property::eString:
|
||||
case Property::eInt:
|
||||
_properties.setGetHook(spec.name, this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing
|
||||
int ClipInstance::getDimension(const std::string &name) const
|
||||
{
|
||||
if(name == kOfxImageEffectPropUnmappedFrameRange || name == kOfxImageEffectPropFrameRange)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// don't know what to do
|
||||
void ClipInstance::reset(const std::string &/*name*/) {
|
||||
//printf("failing in %s\n", __PRETTY_FUNCTION__);
|
||||
throw Property::Exception(kOfxStatErrMissingHostFeature);
|
||||
}
|
||||
|
||||
const std::string &ClipInstance::getComponents() const
|
||||
{
|
||||
return _components;
|
||||
}
|
||||
|
||||
/// set the current set of components
|
||||
/// called by clip preferences action
|
||||
void ClipInstance::setComponents(const std::string &s)
|
||||
{
|
||||
_components = s;
|
||||
}
|
||||
|
||||
// get the virutals for viewport size, pixel scale, background colour
|
||||
void ClipInstance::getDoublePropertyN(const std::string &name, double *values, int n) const
|
||||
{
|
||||
if(name==kOfxImagePropPixelAspectRatio){
|
||||
if(n>1) throw Property::Exception(kOfxStatErrValue);
|
||||
*values = getAspectRatio();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropFrameRate){
|
||||
if(n>1) throw Property::Exception(kOfxStatErrValue);
|
||||
*values = getFrameRate();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropFrameRange){
|
||||
if(n>2) throw Property::Exception(kOfxStatErrValue);
|
||||
getFrameRange(values[0], values[1]);
|
||||
}
|
||||
else if(name==kOfxImageEffectPropUnmappedFrameRate){
|
||||
if(n>1) throw Property::Exception(kOfxStatErrValue);
|
||||
*values = getUnmappedFrameRate();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropUnmappedFrameRange){
|
||||
if(n>2) throw Property::Exception(kOfxStatErrValue);
|
||||
getUnmappedFrameRange(values[0], values[1]);
|
||||
}
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// get the virutals for viewport size, pixel scale, background colour
|
||||
double ClipInstance::getDoubleProperty(const std::string &name, int n) const
|
||||
{
|
||||
if(name==kOfxImagePropPixelAspectRatio){
|
||||
if(n!=0) throw Property::Exception(kOfxStatErrValue);
|
||||
return getAspectRatio();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropFrameRate){
|
||||
if(n!=0) throw Property::Exception(kOfxStatErrValue);
|
||||
return getFrameRate();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropFrameRange){
|
||||
if(n>1) throw Property::Exception(kOfxStatErrValue);
|
||||
double range[2];
|
||||
getFrameRange(range[0], range[1]);
|
||||
return range[n];
|
||||
}
|
||||
else if(name==kOfxImageEffectPropUnmappedFrameRate){
|
||||
if(n>0) throw Property::Exception(kOfxStatErrValue);
|
||||
return getUnmappedFrameRate();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropUnmappedFrameRange){
|
||||
if(n>1) throw Property::Exception(kOfxStatErrValue);
|
||||
double range[2];
|
||||
getUnmappedFrameRange(range[0], range[1]);
|
||||
return range[n];
|
||||
}
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// get the virutals for viewport size, pixel scale, background colour
|
||||
int ClipInstance::getIntProperty(const std::string &name, int n) const
|
||||
{
|
||||
if(n!=0) throw Property::Exception(kOfxStatErrValue);
|
||||
if(name==kOfxImageClipPropConnected){
|
||||
return getConnected();
|
||||
}
|
||||
else if(name==kOfxImageClipPropContinuousSamples){
|
||||
return getContinuousSamples();
|
||||
}
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// get the virutals for viewport size, pixel scale, background colour
|
||||
void ClipInstance::getIntPropertyN(const std::string &name, int *values, int n) const
|
||||
{
|
||||
if(n!=0) throw Property::Exception(kOfxStatErrValue);
|
||||
*values = getIntProperty(name, 0);
|
||||
}
|
||||
|
||||
// get the virutals for viewport size, pixel scale, background colour
|
||||
const std::string &ClipInstance::getStringProperty(const std::string &name, int n) const
|
||||
{
|
||||
if(n!=0) throw Property::Exception(kOfxStatErrValue);
|
||||
if(name==kOfxImageEffectPropPixelDepth){
|
||||
return getPixelDepth();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropComponents){
|
||||
return getComponents();
|
||||
}
|
||||
else if(name==kOfxImageClipPropUnmappedComponents){
|
||||
return getUnmappedComponents();
|
||||
}
|
||||
else if(name==kOfxImageClipPropUnmappedPixelDepth){
|
||||
return getUnmappedBitDepth();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropPreMultiplication){
|
||||
return getPremult();
|
||||
}
|
||||
else if(name==kOfxImageClipPropFieldOrder){
|
||||
return getFieldOrder();
|
||||
}
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// fetch multiple values in a multi-dimension property
|
||||
void ClipInstance::getStringPropertyN(const std::string &name, const char** values, int count) const
|
||||
{
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
if(count!=1) throw Property::Exception(kOfxStatErrValue);
|
||||
if(name==kOfxImageEffectPropPixelDepth){
|
||||
values[0] = getPixelDepth().c_str();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropComponents){
|
||||
values[0] = getComponents().c_str();
|
||||
}
|
||||
else if(name==kOfxImageClipPropUnmappedComponents){
|
||||
values[0] = getUnmappedComponents().c_str();
|
||||
}
|
||||
else if(name==kOfxImageClipPropUnmappedPixelDepth){
|
||||
values[0] = getUnmappedBitDepth().c_str();
|
||||
}
|
||||
else if(name==kOfxImageEffectPropPreMultiplication){
|
||||
values[0] = getPremult().c_str();
|
||||
}
|
||||
else if(name==kOfxImageClipPropFieldOrder){
|
||||
values[0] = getFieldOrder().c_str();
|
||||
}
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// notify override properties
|
||||
void ClipInstance::notify(const std::string &/*name*/, bool /*isSingle*/, int /*indexOrN*/)
|
||||
{
|
||||
}
|
||||
|
||||
OfxStatus ClipInstance::instanceChangedAction(const std::string &why,
|
||||
OfxTime time,
|
||||
OfxPointD renderScale)
|
||||
{
|
||||
Property::PropSpec stuff[] = {
|
||||
{ kOfxPropType, Property::eString, 1, true, kOfxTypeClip },
|
||||
{ kOfxPropName, Property::eString, 1, true, getName().c_str() },
|
||||
{ kOfxPropChangeReason, Property::eString, 1, true, why.c_str() },
|
||||
{ kOfxPropTime, Property::eDouble, 1, true, "0" },
|
||||
{ kOfxImageEffectPropRenderScale, Property::eDouble, 2, true, "0" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
Property::Set inArgs(stuff);
|
||||
|
||||
// add the second dimension of the render scale
|
||||
inArgs.setDoubleProperty(kOfxPropTime,time);
|
||||
inArgs.setDoublePropertyN(kOfxImageEffectPropRenderScale, &renderScale.x, 2);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)_effectInstance<<"->"<<kOfxActionInstanceChanged<<"("<<kOfxTypeClip<<","<<getName()<<","<<why<<","<<time<<",("<<renderScale.x<<","<<renderScale.y<<"))"<<std::endl;
|
||||
# endif
|
||||
|
||||
OfxStatus st;
|
||||
if(_effectInstance){
|
||||
st = _effectInstance->mainEntry(kOfxActionInstanceChanged, _effectInstance->getHandle(), &inArgs, 0);
|
||||
} else {
|
||||
st = kOfxStatFailed;
|
||||
}
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)_effectInstance<<"->"<<kOfxActionInstanceChanged<<"("<<kOfxTypeClip<<","<<getName()<<","<<why<<","<<time<<",("<<renderScale.x<<","<<renderScale.y<<"))->"<<StatStr(st)<<std::endl;
|
||||
# endif
|
||||
return st;
|
||||
}
|
||||
|
||||
/// given the colour component, find the nearest set of supported colour components
|
||||
const std::string &ClipInstance::findSupportedComp(const std::string &s) const
|
||||
{
|
||||
static const std::string none(kOfxImageComponentNone);
|
||||
static const std::string rgba(kOfxImageComponentRGBA);
|
||||
static const std::string rgb(kOfxImageComponentRGB);
|
||||
static const std::string alpha(kOfxImageComponentAlpha);
|
||||
/// is it there
|
||||
if(isSupportedComponent(s))
|
||||
return s;
|
||||
|
||||
/// were we fed some custom non chromatic component by getUnmappedComponents? Return it.
|
||||
/// we should never be here mind, so a bit weird
|
||||
if(!_effectInstance->isChromaticComponent(s))
|
||||
return s;
|
||||
|
||||
/// Means we have RGBA or Alpha being passed in and the clip
|
||||
/// only supports the other one, so return that
|
||||
if(s == rgba) {
|
||||
if(isSupportedComponent(rgb))
|
||||
return rgb;
|
||||
if(isSupportedComponent(alpha))
|
||||
return alpha;
|
||||
} else if(s == alpha) {
|
||||
if(isSupportedComponent(rgba))
|
||||
return rgba;
|
||||
if(isSupportedComponent(rgb))
|
||||
return rgb;
|
||||
}
|
||||
|
||||
/// wierd, must be some custom bit , if only one, choose that, otherwise no idea
|
||||
/// how to map, you need to derive to do so.
|
||||
const std::vector<std::string> &supportedComps = getSupportedComponents();
|
||||
if(supportedComps.size() == 1)
|
||||
return supportedComps[0];
|
||||
|
||||
return none;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Image
|
||||
//
|
||||
|
||||
static const Property::PropSpec imageBaseStuffs[] = {
|
||||
{ kOfxPropType, Property::eString, 1, false, kOfxTypeImage },
|
||||
{ kOfxImageEffectPropPixelDepth, Property::eString, 1, true, kOfxBitDepthNone },
|
||||
{ kOfxImageEffectPropComponents, Property::eString, 1, true, kOfxImageComponentNone },
|
||||
{ kOfxImageEffectPropPreMultiplication, Property::eString, 1, true, kOfxImageOpaque },
|
||||
{ kOfxImageEffectPropRenderScale, Property::eDouble, 2, true, "1.0" },
|
||||
{ kOfxImagePropPixelAspectRatio, Property::eDouble, 1, true, "1.0" },
|
||||
{ kOfxImagePropBounds, Property::eInt, 4, true, "0" },
|
||||
{ kOfxImagePropRegionOfDefinition, Property::eInt, 4, true, "0", },
|
||||
{ kOfxImagePropRowBytes, Property::eInt, 1, true, "0", },
|
||||
{ kOfxImagePropField, Property::eString, 1, true, "", },
|
||||
{ kOfxImagePropUniqueIdentifier, Property::eString, 1, true, "" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
ImageBase::ImageBase()
|
||||
: Property::Set(imageBaseStuffs)
|
||||
, _referenceCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
/// called during ctor to get bits from the clip props into ours
|
||||
void ImageBase::getClipBits(ClipInstance& instance)
|
||||
{
|
||||
Property::Set& clipProperties = instance.getProps();
|
||||
|
||||
// get and set the clip instance pixel depth
|
||||
const std::string &depth = clipProperties.getStringProperty(kOfxImageEffectPropPixelDepth);
|
||||
setStringProperty(kOfxImageEffectPropPixelDepth, depth);
|
||||
|
||||
// get and set the clip instance components
|
||||
const std::string &comps = clipProperties.getStringProperty(kOfxImageEffectPropComponents);
|
||||
setStringProperty(kOfxImageEffectPropComponents, comps);
|
||||
|
||||
// get and set the clip instance premultiplication
|
||||
setStringProperty(kOfxImageEffectPropPreMultiplication, clipProperties.getStringProperty(kOfxImageEffectPropPreMultiplication));
|
||||
|
||||
// get and set the clip instance pixel aspect ratio
|
||||
setDoubleProperty(kOfxImagePropPixelAspectRatio, clipProperties.getDoubleProperty(kOfxImagePropPixelAspectRatio));
|
||||
}
|
||||
|
||||
/// make an image from a clip instance
|
||||
ImageBase::ImageBase(ClipInstance& instance)
|
||||
: Property::Set(imageBaseStuffs)
|
||||
, _referenceCount(1)
|
||||
{
|
||||
getClipBits(instance);
|
||||
}
|
||||
|
||||
// construction based on clip instance
|
||||
ImageBase::ImageBase(ClipInstance& instance,
|
||||
double renderScaleX,
|
||||
double renderScaleY,
|
||||
const OfxRectI &bounds,
|
||||
const OfxRectI &rod,
|
||||
int rowBytes,
|
||||
std::string field,
|
||||
std::string uniqueIdentifier)
|
||||
: Property::Set(imageBaseStuffs)
|
||||
, _referenceCount(1)
|
||||
{
|
||||
getClipBits(instance);
|
||||
|
||||
// set other data
|
||||
setDoubleProperty(kOfxImageEffectPropRenderScale,renderScaleX, 0);
|
||||
setDoubleProperty(kOfxImageEffectPropRenderScale,renderScaleY, 1);
|
||||
setIntProperty(kOfxImagePropBounds,bounds.x1, 0);
|
||||
setIntProperty(kOfxImagePropBounds,bounds.y1, 1);
|
||||
setIntProperty(kOfxImagePropBounds,bounds.x2, 2);
|
||||
setIntProperty(kOfxImagePropBounds,bounds.y2, 3);
|
||||
setIntProperty(kOfxImagePropRegionOfDefinition,rod.x1, 0);
|
||||
setIntProperty(kOfxImagePropRegionOfDefinition,rod.y1, 1);
|
||||
setIntProperty(kOfxImagePropRegionOfDefinition,rod.x2, 2);
|
||||
setIntProperty(kOfxImagePropRegionOfDefinition,rod.y2, 3);
|
||||
setIntProperty(kOfxImagePropRowBytes,rowBytes);
|
||||
|
||||
setStringProperty(kOfxImagePropField,field);
|
||||
setStringProperty(kOfxImageClipPropFieldOrder,field);
|
||||
setStringProperty(kOfxImagePropUniqueIdentifier,uniqueIdentifier);
|
||||
}
|
||||
|
||||
OfxRectI ImageBase::getBounds() const
|
||||
{
|
||||
OfxRectI bounds = {0, 0, 0, 0};
|
||||
getIntPropertyN(kOfxImagePropBounds, &bounds.x1, 4);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
OfxRectI ImageBase::getROD() const
|
||||
{
|
||||
OfxRectI rod = {0, 0, 0, 0};
|
||||
getIntPropertyN(kOfxImagePropRegionOfDefinition, &rod.x1, 4);
|
||||
return rod;
|
||||
}
|
||||
|
||||
ImageBase::~ImageBase() {
|
||||
//assert(_referenceCount <= 0);
|
||||
}
|
||||
|
||||
// release the reference
|
||||
void ImageBase::releaseReference()
|
||||
{
|
||||
_referenceCount -= 1;
|
||||
if(_referenceCount <= 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
static const Property::PropSpec imageStuffs[] = {
|
||||
{ kOfxImagePropData, Property::ePointer, 1, true, NULL },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
Image::Image()
|
||||
: ImageBase()
|
||||
{
|
||||
addProperties(imageStuffs);
|
||||
}
|
||||
|
||||
/// make an image from a clip instance
|
||||
Image::Image(ClipInstance& instance)
|
||||
: ImageBase(instance)
|
||||
{
|
||||
addProperties(imageStuffs);
|
||||
}
|
||||
|
||||
// construction based on clip instance
|
||||
Image::Image(ClipInstance& instance,
|
||||
double renderScaleX,
|
||||
double renderScaleY,
|
||||
void* data,
|
||||
const OfxRectI &bounds,
|
||||
const OfxRectI &rod,
|
||||
int rowBytes,
|
||||
std::string field,
|
||||
std::string uniqueIdentifier)
|
||||
: ImageBase(instance, renderScaleX, renderScaleY, bounds, rod, rowBytes, field, uniqueIdentifier)
|
||||
{
|
||||
addProperties(imageStuffs);
|
||||
|
||||
// set other data
|
||||
setPointerProperty(kOfxImagePropData,data);
|
||||
}
|
||||
|
||||
Image::~Image() {
|
||||
//assert(_referenceCount <= 0);
|
||||
}
|
||||
# ifdef OFX_SUPPORTS_OPENGLRENDER
|
||||
static const Property::PropSpec textureStuffs[] = {
|
||||
{ kOfxImageEffectPropOpenGLTextureIndex, Property::eInt, 1, true, "-1" },
|
||||
{ kOfxImageEffectPropOpenGLTextureTarget, Property::eInt, 1, true, "-1" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
Texture::Texture()
|
||||
: ImageBase()
|
||||
{
|
||||
addProperties(textureStuffs);
|
||||
}
|
||||
|
||||
/// make an image from a clip instance
|
||||
Texture::Texture(ClipInstance& instance)
|
||||
: ImageBase(instance)
|
||||
{
|
||||
addProperties(textureStuffs);
|
||||
}
|
||||
|
||||
// construction based on clip instance
|
||||
Texture::Texture(ClipInstance& instance,
|
||||
double renderScaleX,
|
||||
double renderScaleY,
|
||||
int index,
|
||||
int target,
|
||||
const OfxRectI &bounds,
|
||||
const OfxRectI &rod,
|
||||
int rowBytes,
|
||||
std::string field,
|
||||
std::string uniqueIdentifier)
|
||||
: ImageBase(instance, renderScaleX, renderScaleY, bounds, rod, rowBytes, field, uniqueIdentifier)
|
||||
{
|
||||
addProperties(textureStuffs);
|
||||
|
||||
// set other data
|
||||
setIntProperty(kOfxImageEffectPropOpenGLTextureIndex, index);
|
||||
setIntProperty(kOfxImageEffectPropOpenGLTextureTarget, target);
|
||||
}
|
||||
|
||||
|
||||
Texture::~Texture() {
|
||||
//assert(_referenceCount <= 0);
|
||||
}
|
||||
# endif
|
||||
} // Clip
|
||||
|
||||
} // Host
|
||||
|
||||
} // OFX
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
// ofx
|
||||
#include "ofxCore.h"
|
||||
#include "ofxProperty.h"
|
||||
#include "ofxMultiThread.h"
|
||||
#include "ofxMemory.h"
|
||||
|
||||
#include "ofxhHost.h"
|
||||
|
||||
typedef OfxPlugin* (*OfxGetPluginType)(int);
|
||||
|
||||
namespace OFX {
|
||||
|
||||
namespace Host {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// simple memory suite
|
||||
namespace Memory {
|
||||
static OfxStatus memoryAlloc(void */*handle*/, size_t bytes, void **data)
|
||||
{
|
||||
*data = malloc(bytes);
|
||||
if (*data) {
|
||||
return kOfxStatOK;
|
||||
} else {
|
||||
return kOfxStatErrMemory;
|
||||
}
|
||||
}
|
||||
|
||||
static OfxStatus memoryFree(void *data)
|
||||
{
|
||||
free(data);
|
||||
return kOfxStatOK;
|
||||
}
|
||||
|
||||
static const struct OfxMemorySuiteV1 gMallocSuite = {
|
||||
memoryAlloc,
|
||||
memoryFree
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace OFX {
|
||||
namespace Host {
|
||||
/// our own internal property for storing away our private pointer to our host descriptor
|
||||
#define kOfxHostSupportHostPointer "sf.openfx.net.OfxHostSupportHostPointer"
|
||||
|
||||
static const Property::PropSpec hostStuffs[] = {
|
||||
{ kOfxPropAPIVersion, Property::eInt, 0, false, "" },
|
||||
{ kOfxPropType, Property::eString, 1, false, "Host" },
|
||||
{ kOfxPropName, Property::eString, 1, false, "UNKNOWN" },
|
||||
{ kOfxPropLabel, Property::eString, 1, false, "UNKNOWN" },
|
||||
{ kOfxPropVersion, Property::eInt, 0, false, "0" },
|
||||
{ kOfxPropVersionLabel, Property::eString, 1, false, "" },
|
||||
{ kOfxHostSupportHostPointer, Property::ePointer, 0, false, NULL },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
static const void *fetchSuite(OfxPropertySetHandle hostProps, const char *suiteName, int suiteVersion)
|
||||
{
|
||||
Property::Set* properties = reinterpret_cast<Property::Set*>(hostProps);
|
||||
|
||||
Host* host = (Host*)properties->getPointerProperty(kOfxHostSupportHostPointer);
|
||||
|
||||
if(host)
|
||||
return host->fetchSuite(suiteName,suiteVersion);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Base Host
|
||||
Host::Host() : _properties(hostStuffs)
|
||||
{
|
||||
_host.host = _properties.getHandle();
|
||||
_host.fetchSuite = OFX::Host::fetchSuite;
|
||||
|
||||
// record the host descriptor in the propert set
|
||||
_properties.setPointerProperty(kOfxHostSupportHostPointer,this);
|
||||
}
|
||||
|
||||
OfxHost *Host::getHandle() {
|
||||
return &_host;
|
||||
}
|
||||
|
||||
OfxStatus Host::message(const char* type,
|
||||
const char* id,
|
||||
const char* format,
|
||||
...) {
|
||||
try {
|
||||
OfxStatus stat;
|
||||
va_list args;
|
||||
va_start(args,format);
|
||||
stat = vmessage(type,id,format,args);
|
||||
va_end(args);
|
||||
return stat;
|
||||
} catch (...) {
|
||||
return kOfxStatFailed;
|
||||
}
|
||||
}
|
||||
|
||||
const void *Host::fetchSuite(const char *suiteName, int suiteVersion)
|
||||
{
|
||||
if (strcmp(suiteName, kOfxPropertySuite)==0 && suiteVersion == 1) {
|
||||
return Property::GetSuite(suiteVersion);
|
||||
}
|
||||
else if (strcmp(suiteName, kOfxMemorySuite)==0 && suiteVersion == 1) {
|
||||
return (void*)&Memory::gMallocSuite;
|
||||
}
|
||||
|
||||
///printf("fetchSuite failed with host = %p, name = %s, version = %i\n", this, suiteName, suiteVersion);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // Host
|
||||
|
||||
} // OFX
|
||||
+2809
File diff suppressed because it is too large
Load Diff
+592
@@ -0,0 +1,592 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <ctype.h>
|
||||
|
||||
// ofx
|
||||
#include "ofxImageEffect.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhBinary.h"
|
||||
#include "ofxhPropertySuite.h"
|
||||
#include "ofxhClip.h"
|
||||
#include "ofxhParam.h"
|
||||
#include "ofxhMemory.h"
|
||||
#include "ofxhImageEffect.h"
|
||||
#include "ofxhPluginAPICache.h"
|
||||
#include "ofxhPluginCache.h"
|
||||
#include "ofxhHost.h"
|
||||
#include "ofxhImageEffectAPI.h"
|
||||
#include "ofxhXml.h"
|
||||
|
||||
// Disable the "this pointer used in base member initialiser list" warning in Windows
|
||||
namespace OFX {
|
||||
|
||||
namespace Host {
|
||||
|
||||
namespace ImageEffect {
|
||||
|
||||
/// our global host bobject, set when the cache is created
|
||||
OFX::Host::ImageEffect::Host *gImageEffectHost;
|
||||
|
||||
/// ctor
|
||||
#ifdef WINDOWS
|
||||
#pragma warning( disable : 4355 )
|
||||
#endif
|
||||
ImageEffectPlugin::ImageEffectPlugin(PluginCache &pc, PluginBinary *pb, int pi, OfxPlugin *pl)
|
||||
: Plugin(pb, pi, pl)
|
||||
, _pc(pc)
|
||||
, _baseDescriptor(NULL)
|
||||
, _madeKnownContexts(false)
|
||||
{
|
||||
_baseDescriptor = gImageEffectHost->makeDescriptor(this);
|
||||
}
|
||||
|
||||
ImageEffectPlugin::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)
|
||||
: Plugin(pb, pi, api, apiVersion, pluginId, rawId, pluginMajorVersion, pluginMinorVersion)
|
||||
, _pc(pc)
|
||||
, _baseDescriptor(NULL)
|
||||
, _madeKnownContexts(false)
|
||||
{
|
||||
_baseDescriptor = gImageEffectHost->makeDescriptor(this);
|
||||
}
|
||||
|
||||
#ifdef WINDOWS
|
||||
#pragma warning( default : 4355 )
|
||||
#endif
|
||||
|
||||
ImageEffectPlugin::~ImageEffectPlugin()
|
||||
{
|
||||
_contexts.clear();
|
||||
if(_pluginHandle) {
|
||||
OfxPlugin *op = _pluginHandle->getOfxPlugin();
|
||||
OfxStatus stat;
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionUnload<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = op->mainEntry(kOfxActionUnload, 0, 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionUnload<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, op, kOfxActionUnload);
|
||||
(void)stat;
|
||||
}
|
||||
delete _baseDescriptor;
|
||||
}
|
||||
|
||||
APICache::PluginAPICacheI &ImageEffectPlugin::getApiHandler()
|
||||
{
|
||||
return _pc;
|
||||
}
|
||||
|
||||
|
||||
/// get the image effect descriptor
|
||||
Descriptor &ImageEffectPlugin::getDescriptor() {
|
||||
return *_baseDescriptor;
|
||||
}
|
||||
|
||||
/// get the image effect descriptor const version
|
||||
const Descriptor &ImageEffectPlugin::getDescriptor() const {
|
||||
return *_baseDescriptor;
|
||||
}
|
||||
|
||||
void ImageEffectPlugin::addContext(const std::string &context, std::unique_ptr<Descriptor> ied)
|
||||
{
|
||||
_contexts[context] = std::move(ied);
|
||||
_knownContexts.insert(context);
|
||||
_madeKnownContexts = true;
|
||||
}
|
||||
|
||||
void ImageEffectPlugin::addContext(const std::string &context)
|
||||
{
|
||||
_knownContexts.insert(context);
|
||||
_madeKnownContexts = true;
|
||||
}
|
||||
|
||||
void ImageEffectPlugin::addContextInternal(const std::string &context) const
|
||||
{
|
||||
_knownContexts.insert(context);
|
||||
_madeKnownContexts = true;
|
||||
}
|
||||
|
||||
void ImageEffectPlugin::saveXML(std::ostream &os)
|
||||
{
|
||||
APICache::propertySetXMLWrite(os, getDescriptor().getProps(), 6);
|
||||
}
|
||||
|
||||
const std::set<std::string> &ImageEffectPlugin::getContexts() const {
|
||||
if (_madeKnownContexts) {
|
||||
return _knownContexts;
|
||||
}
|
||||
else {
|
||||
const OFX::Host::Property::Set &eProps = getDescriptor().getProps();
|
||||
int size = eProps.getDimension(kOfxImageEffectPropSupportedContexts);
|
||||
for (int j=0;j<size;j++) {
|
||||
std::string context = eProps.getStringProperty(kOfxImageEffectPropSupportedContexts, j);
|
||||
addContextInternal(context);
|
||||
}
|
||||
return _knownContexts;
|
||||
}
|
||||
}
|
||||
|
||||
PluginHandle *ImageEffectPlugin::getPluginHandle()
|
||||
{
|
||||
if(!_pluginHandle) {
|
||||
_pluginHandle.reset(new OFX::Host::PluginHandle(this, _pc.getHost()));
|
||||
|
||||
OfxPlugin *op = _pluginHandle->getOfxPlugin();
|
||||
|
||||
if (!op) {
|
||||
_pluginHandle.reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OfxStatus stat;
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionLoad<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = op->mainEntry(kOfxActionLoad, 0, 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionLoad<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, op, kOfxActionLoad);
|
||||
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
_pluginHandle.reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionDescribe<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = op->mainEntry(kOfxActionDescribe, getDescriptor().getHandle(), 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)op<<"->"<<kOfxActionDescribe<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, op, kOfxActionDescribe);
|
||||
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
_pluginHandle.reset();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return _pluginHandle.get();
|
||||
}
|
||||
|
||||
Descriptor *ImageEffectPlugin::getContext(const std::string &context)
|
||||
{
|
||||
std::map<std::string, std::unique_ptr<Descriptor>>::iterator it = _contexts.find(context);
|
||||
|
||||
if (it != _contexts.end()) {
|
||||
//printf("found context description.\n");
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
if (_knownContexts.find(context) == _knownContexts.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// printf("doing context description.\n");
|
||||
|
||||
OFX::Host::Property::PropSpec inargspec[] = {
|
||||
{ kOfxImageEffectPropContext, OFX::Host::Property::eString, 1, true, context.c_str() },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
OFX::Host::Property::Set inarg(inargspec);
|
||||
|
||||
PluginHandle *ph = getPluginHandle();
|
||||
std::unique_ptr<ImageEffect::Descriptor> newContext( gImageEffectHost->makeDescriptor(getDescriptor(), this));
|
||||
|
||||
OfxStatus stat;
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)ph->getOfxPlugin()<<"->"<<kOfxImageEffectActionDescribeInContext<<"("<<context<<")"<<std::endl;
|
||||
# endif
|
||||
stat = ph->getOfxPlugin()->mainEntry(kOfxImageEffectActionDescribeInContext, newContext->getHandle(), inarg.getHandle(), 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)ph->getOfxPlugin()<<"->"<<kOfxImageEffectActionDescribeInContext<<"("<<context<<")->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, ph->getOfxPlugin(), kOfxImageEffectActionDescribeInContext);
|
||||
|
||||
if (stat == kOfxStatOK || stat == kOfxStatReplyDefault) {
|
||||
_contexts[context] = std::move(newContext);
|
||||
return _contexts[context].get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImageEffect::Instance* ImageEffectPlugin::createInstance(const std::string &context, void *clientData)
|
||||
{
|
||||
|
||||
/// todo - we need to make sure action:load is called, then action:describe again
|
||||
/// (not because we are expecting the results to change, but because plugin
|
||||
/// might get confused otherwise), then a describe_in_context
|
||||
|
||||
getPluginHandle();
|
||||
|
||||
Descriptor *desc = getContext(context);
|
||||
|
||||
if (desc) {
|
||||
ImageEffect::Instance *instance = gImageEffectHost->newInstance(clientData,
|
||||
this,
|
||||
*desc,
|
||||
context);
|
||||
instance->populate();
|
||||
return instance;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ImageEffectPlugin::unload() {
|
||||
if (_pluginHandle) {
|
||||
OfxStatus stat;
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)_pluginHandle->getOfxPlugin()<<"->"<<kOfxActionUnload<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = (*_pluginHandle)->mainEntry(kOfxActionUnload, 0, 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)_pluginHandle->getOfxPlugin()<<"->"<<kOfxActionUnload<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, (*_pluginHandle), kOfxActionUnload);
|
||||
(void)stat;
|
||||
}
|
||||
}
|
||||
|
||||
PluginCache::PluginCache(OFX::Host::ImageEffect::Host &host)
|
||||
: PluginAPICacheI(kOfxImageEffectPluginApi, 1, 1)
|
||||
, _currentPlugin(0)
|
||||
, _currentProp(0)
|
||||
, _currentContext(0)
|
||||
, _currentParam(0)
|
||||
, _currentClip(0)
|
||||
, _host(&host)
|
||||
{
|
||||
gImageEffectHost = &host;
|
||||
}
|
||||
|
||||
PluginCache::~PluginCache() {}
|
||||
|
||||
/// get the plugin by id. vermaj and vermin can be specified. if they are not it will
|
||||
/// pick the highest found version.
|
||||
ImageEffectPlugin *PluginCache::getPluginById(const std::string &id, int vermaj, int vermin)
|
||||
{
|
||||
// return the highest version one, which fits the pattern provided
|
||||
ImageEffectPlugin *sofar = 0;
|
||||
std::string identifier = id;
|
||||
|
||||
// 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]);
|
||||
//}
|
||||
|
||||
for (std::vector<ImageEffectPlugin *>::iterator i=_plugins.begin();i!=_plugins.end();i++) {
|
||||
ImageEffectPlugin *p = *i;
|
||||
|
||||
if (p->getIdentifier() != identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vermaj != -1 && p->getVersionMajor() != vermaj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vermin != -1 && p->getVersionMinor() != vermin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sofar || p->trumps(sofar)) {
|
||||
sofar = p;
|
||||
}
|
||||
}
|
||||
|
||||
return sofar;
|
||||
}
|
||||
|
||||
/// whether we support this plugin.
|
||||
bool PluginCache::pluginSupported(OFX::Host::Plugin *p, std::string &reason) const {
|
||||
return gImageEffectHost->pluginSupported(dynamic_cast<OFX::Host::ImageEffect::ImageEffectPlugin *>(p), reason);
|
||||
}
|
||||
|
||||
/// get the plugin by label. vermaj and vermin can be specified. if they are not it will
|
||||
/// pick the highest found version.
|
||||
ImageEffectPlugin *PluginCache::getPluginByLabel(const std::string &label, int vermaj, int vermin)
|
||||
{
|
||||
// return the highest version one, which fits the pattern provided
|
||||
ImageEffectPlugin *sofar = 0;
|
||||
|
||||
for (std::vector<ImageEffectPlugin *>::iterator i=_plugins.begin();i!=_plugins.end();i++) {
|
||||
ImageEffectPlugin *p = *i;
|
||||
|
||||
if (p->getDescriptor().getProps().getStringProperty(kOfxPropLabel) != label) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vermaj != -1 && p->getVersionMajor() != vermaj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vermin != -1 && p->getVersionMinor() != vermin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sofar || p->trumps(sofar)) {
|
||||
sofar = p;
|
||||
}
|
||||
}
|
||||
|
||||
return sofar;
|
||||
}
|
||||
|
||||
const std::vector<ImageEffectPlugin *>& PluginCache::getPlugins() const
|
||||
{
|
||||
return _plugins;
|
||||
}
|
||||
|
||||
const std::map<std::string, ImageEffectPlugin *>& PluginCache::getPluginsByID() const
|
||||
{
|
||||
return _pluginsByID;
|
||||
}
|
||||
|
||||
/// handle the case where the info needs filling in from the file. runs the "describe" action on the plugin.
|
||||
void PluginCache::loadFromPlugin(Plugin *op) const {
|
||||
std::string msg = "loading ";
|
||||
msg += op->getRawIdentifier();
|
||||
|
||||
_host->loadingStatus(msg);
|
||||
|
||||
ImageEffectPlugin *p = dynamic_cast<ImageEffectPlugin*>(op);
|
||||
assert(p);
|
||||
|
||||
PluginHandle plug(p, _host);
|
||||
|
||||
OfxStatus stat;
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionLoad<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = plug->mainEntry(kOfxActionLoad, 0, 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionLoad<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, plug, kOfxActionLoad);
|
||||
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
std::cerr << "load failed on plugin " << op->getIdentifier() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionDescribe<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = plug->mainEntry(kOfxActionDescribe, p->getDescriptor().getHandle(), 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionDescribe<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, plug, kOfxActionDescribe);
|
||||
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
std::cerr << "describe failed on plugin " << op->getIdentifier() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ImageEffect::Descriptor &e = p->getDescriptor();
|
||||
Property::Set &eProps = e.getProps();
|
||||
|
||||
int size = eProps.getDimension(kOfxImageEffectPropSupportedContexts);
|
||||
|
||||
for (int j=0;j<size;j++) {
|
||||
std::string context = eProps.getStringProperty(kOfxImageEffectPropSupportedContexts, j);
|
||||
p->addContext(context);
|
||||
}
|
||||
|
||||
try {
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionUnload<<"()"<<std::endl;
|
||||
# endif
|
||||
stat = plug->mainEntry(kOfxActionUnload, 0, 0, 0);
|
||||
# ifdef OFX_DEBUG_ACTIONS
|
||||
std::cout << "OFX: "<<(void*)plug.getOfxPlugin()<<"->"<<kOfxActionUnload<<"()->"<<StatStr(stat)<<std::endl;
|
||||
# endif
|
||||
} CatchAllSetStatus(stat, gImageEffectHost, plug, kOfxActionUnload);
|
||||
|
||||
if (stat != kOfxStatOK && stat != kOfxStatReplyDefault) {
|
||||
std::cerr << "unload failed on plugin " << op->getIdentifier() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// handler for preparing to read in a chunk of XML from the cache, set up context to do this
|
||||
void PluginCache::beginXmlParsing(Plugin *p) {
|
||||
_currentPlugin = dynamic_cast<ImageEffectPlugin*>(p);
|
||||
}
|
||||
|
||||
/// XML handler : element begins (everything is stored in elements and attributes)
|
||||
void PluginCache::xmlElementBegin(const std::string &el, std::map<std::string, std::string> map)
|
||||
{
|
||||
if (el == "apiproperties") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (el == "context") {
|
||||
std::unique_ptr<Descriptor> newContext(gImageEffectHost->makeDescriptor(_currentPlugin->getBinary()->getBundlePath(), _currentPlugin));
|
||||
_currentContext = newContext.get();
|
||||
_currentPlugin->addContext(map["name"], std::move(newContext));
|
||||
return;
|
||||
}
|
||||
|
||||
if (el == "param" && _currentContext) {
|
||||
std::string pname = map["name"];
|
||||
std::string ptype = map["type"];
|
||||
|
||||
_currentParam = _currentContext->paramDefine(ptype.c_str(), pname.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (el == "clip" && _currentContext) {
|
||||
std::string cname = map["name"];
|
||||
|
||||
_currentClip = new ClipDescriptor(cname);
|
||||
_currentContext->addClip(cname, _currentClip);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentContext && _currentParam) {
|
||||
APICache::propertySetXMLRead(el, map, _currentParam->getProperties(), _currentProp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentContext && _currentClip) {
|
||||
APICache::propertySetXMLRead(el, map, _currentClip->getProps(), _currentProp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_currentContext && !_currentParam) {
|
||||
APICache::propertySetXMLRead(el, map, _currentPlugin->getDescriptor().getProps(), _currentProp);
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "element " << el << "\n";
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void PluginCache::xmlCharacterHandler(const std::string &) {
|
||||
}
|
||||
|
||||
void PluginCache::xmlElementEnd(const std::string &el) {
|
||||
if (el == "param") {
|
||||
_currentParam = 0;
|
||||
}
|
||||
|
||||
if (el == "context") {
|
||||
_currentContext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PluginCache::endXmlParsing() {
|
||||
_currentPlugin = 0;
|
||||
}
|
||||
|
||||
void PluginCache::saveXML(Plugin *ip, std::ostream &os) const {
|
||||
ImageEffectPlugin *p = dynamic_cast<ImageEffectPlugin*>(ip);
|
||||
if (p) {
|
||||
p->saveXML(os);
|
||||
}
|
||||
}
|
||||
|
||||
void PluginCache::confirmPlugin(Plugin *p) {
|
||||
ImageEffectPlugin *plugin = dynamic_cast<ImageEffectPlugin*>(p);
|
||||
if (!plugin) {
|
||||
return;
|
||||
}
|
||||
_plugins.push_back(plugin);
|
||||
|
||||
if (_pluginsByID.find(plugin->getIdentifier()) != _pluginsByID.end()) {
|
||||
ImageEffectPlugin *otherPlugin = _pluginsByID[plugin->getIdentifier()];
|
||||
if (plugin->trumps(otherPlugin)) {
|
||||
_pluginsByID[plugin->getIdentifier()] = plugin;
|
||||
}
|
||||
} else {
|
||||
_pluginsByID[plugin->getIdentifier()] = plugin;
|
||||
}
|
||||
|
||||
MajorPlugin maj(plugin);
|
||||
|
||||
if (_pluginsByIDMajor.find(maj) != _pluginsByIDMajor.end()) {
|
||||
ImageEffectPlugin *otherPlugin = _pluginsByIDMajor[maj];
|
||||
if (plugin->trumps(otherPlugin)) {
|
||||
_pluginsByIDMajor[maj] = plugin;
|
||||
}
|
||||
} else {
|
||||
_pluginsByIDMajor[maj] = plugin;
|
||||
}
|
||||
}
|
||||
|
||||
Plugin *PluginCache::newPlugin(PluginBinary *pb,
|
||||
int pi,
|
||||
OfxPlugin *pl) {
|
||||
ImageEffectPlugin *plugin = new ImageEffectPlugin(*this, pb, pi, pl);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
Plugin *PluginCache::newPlugin(PluginBinary *pb,
|
||||
int pi,
|
||||
const std::string &api,
|
||||
int apiVersion,
|
||||
const std::string &pluginId,
|
||||
const std::string &rawId,
|
||||
int pluginMajorVersion,
|
||||
int pluginMinorVersion)
|
||||
{
|
||||
ImageEffectPlugin *plugin = new ImageEffectPlugin(*this, pb, pi, api, apiVersion, pluginId, rawId, pluginMajorVersion, pluginMinorVersion);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
void PluginCache::dumpToStdOut()
|
||||
{
|
||||
if (_pluginsByID.empty())
|
||||
std::cout << "No Plug-ins Found." << std::endl;
|
||||
|
||||
for(std::map<std::string, ImageEffectPlugin *>::const_iterator it = _pluginsByID.begin(); it != _pluginsByID.end(); ++it)
|
||||
{
|
||||
std::cout << "Plug-in:" << it->first << std::endl;
|
||||
std::cout << "\t" << "Filepath: " << it->second->getBinary()->getFilePath();
|
||||
std::cout<< "(" << it->second->getIndex() << ")" << std::endl;
|
||||
|
||||
std::cout << "Contexts:" << std::endl;
|
||||
const std::set<std::string>& contexts = it->second->getContexts();
|
||||
for (std::set<std::string>::const_iterator it2 = contexts.begin(); it2 != contexts.end(); ++it2)
|
||||
std::cout << "\t* " << *it2 << std::endl;
|
||||
const Descriptor& d = it->second->getDescriptor();
|
||||
std::cout << "Inputs:" << std::endl;
|
||||
const std::map<std::string, ClipDescriptor*>& inputs = d.getClips();
|
||||
for (std::map<std::string, ClipDescriptor*>::const_iterator it2 = inputs.begin(); it2 != inputs.end(); ++it2)
|
||||
std::cout << "\t\t* " << it2->first << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
} // ImageEffect
|
||||
|
||||
} // Host
|
||||
|
||||
} // OFX
|
||||
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
|
||||
|
||||
// ofx
|
||||
#include "ofxKeySyms.h"
|
||||
#include "ofxCore.h"
|
||||
#include "ofxImageEffect.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhBinary.h"
|
||||
#include "ofxhPropertySuite.h"
|
||||
#include "ofxhClip.h"
|
||||
#include "ofxhParam.h"
|
||||
#include "ofxhMemory.h"
|
||||
#include "ofxhImageEffect.h"
|
||||
#include "ofxhInteract.h"
|
||||
#include "ofxOld.h" // old plugins may rely on deprecated properties being present
|
||||
|
||||
namespace OFX {
|
||||
|
||||
namespace Host {
|
||||
|
||||
namespace Interact {
|
||||
|
||||
//
|
||||
// descriptor
|
||||
//
|
||||
static const Property::PropSpec interactDescriptorStuffs[] = {
|
||||
{ kOfxInteractPropHasAlpha , Property::eInt, 1, true, "0" },
|
||||
{ kOfxInteractPropBitDepth , Property::eInt, 1, true, "0" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
Descriptor::Descriptor()
|
||||
: _properties(interactDescriptorStuffs)
|
||||
, _state(eUninitialised)
|
||||
, _entryPoint(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Descriptor::~Descriptor()
|
||||
{
|
||||
}
|
||||
|
||||
/// call describe on this descriptor
|
||||
bool Descriptor::describe(int bitDepthPerComponent, bool hasAlpha)
|
||||
{
|
||||
if(_state == eUninitialised) {
|
||||
_properties.setIntProperty(kOfxInteractPropBitDepth, bitDepthPerComponent);
|
||||
_properties.setIntProperty(kOfxInteractPropHasAlpha, (int)(hasAlpha));
|
||||
|
||||
OfxStatus stat = callEntry(kOfxActionDescribe, getHandle(), NULL, NULL);
|
||||
if(stat == kOfxStatOK || stat == kOfxStatReplyDefault) {
|
||||
_state = eDescribed;
|
||||
}
|
||||
else {
|
||||
_state = eFailed;
|
||||
}
|
||||
}
|
||||
return _state == eDescribed;
|
||||
}
|
||||
|
||||
// call the interactive entry point
|
||||
OfxStatus Descriptor::callEntry(const char *action,
|
||||
void *handle,
|
||||
OfxPropertySetHandle inArgs,
|
||||
OfxPropertySetHandle outArgs)
|
||||
{
|
||||
if(_entryPoint && _state != eFailed) {
|
||||
return _entryPoint(action, handle, inArgs, outArgs);
|
||||
}
|
||||
else
|
||||
return kOfxStatFailed;
|
||||
|
||||
return kOfxStatOK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static const Property::PropSpec interactInstanceStuffs[] = {
|
||||
{ kOfxPropEffectInstance, Property::ePointer, 1, true, NULL },
|
||||
{ kOfxPropInstanceData, Property::ePointer, 1, false, NULL },
|
||||
{ kOfxInteractPropPixelScale, Property::eDouble, 2, true, "1.0f" },
|
||||
{ kOfxInteractPropBackgroundColour , Property::eDouble, 3, true, "0.0f" },
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
{ kOfxInteractPropViewportSize, Property::eDouble, 2, true, "100.0f" },
|
||||
#endif
|
||||
{ kOfxInteractPropSlaveToParam , Property::eString, 0, false, ""},
|
||||
{ kOfxInteractPropSuggestedColour , Property::eDouble, 3, true, "1.0f" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
static const Property::PropSpec interactArgsStuffs[] = {
|
||||
{ kOfxPropEffectInstance, Property::ePointer, 1, false, NULL },
|
||||
{ kOfxPropTime, Property::eDouble, 1, false, "0.0" },
|
||||
{ kOfxImageEffectPropRenderScale, Property::eDouble, 2, false, "0.0" },
|
||||
{ kOfxInteractPropBackgroundColour , Property::eDouble, 3, false, "0.0f" },
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
{ kOfxInteractPropViewportSize, Property::eDouble, 2, false, "0.0f" },
|
||||
#endif
|
||||
{ kOfxInteractPropPixelScale, Property::eDouble, 2, false, "1.0f" },
|
||||
{ kOfxInteractPropPenPosition, Property::eDouble, 2, false, "0.0" },
|
||||
{ kOfxInteractPropPenViewportPosition, Property::eInt, 2, false, "0" }, // new in OFX 1.2
|
||||
{ kOfxInteractPropPenPressure, Property::eDouble, 1, false, "0.0" },
|
||||
{ kOfxPropKeyString, Property::eString, 1, false, "" },
|
||||
{ kOfxPropKeySym, Property::eInt, 1, false, "0" },
|
||||
Property::propSpecEnd
|
||||
};
|
||||
|
||||
// instance
|
||||
|
||||
Instance::Instance(Descriptor& desc, void *effectInstance)
|
||||
: _descriptor(desc)
|
||||
, _properties(interactInstanceStuffs)
|
||||
, _state(desc.getState())
|
||||
, _effectInstance(effectInstance)
|
||||
, _argProperties(interactArgsStuffs)
|
||||
{
|
||||
_properties.setPointerProperty(kOfxPropEffectInstance, effectInstance);
|
||||
_properties.setChainedSet(&desc.getProperties()); /// chain it into the descriptor props
|
||||
_properties.setGetHook(kOfxInteractPropPixelScale, this);
|
||||
_properties.setGetHook(kOfxInteractPropBackgroundColour,this);
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
_properties.setGetHook(kOfxInteractPropViewportSize,this);
|
||||
#endif
|
||||
_properties.setGetHook(kOfxInteractPropSuggestedColour,this);
|
||||
|
||||
_argProperties.setGetHook(kOfxInteractPropPixelScale, this);
|
||||
_argProperties.setGetHook(kOfxInteractPropBackgroundColour,this);
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
_argProperties.setGetHook(kOfxInteractPropViewportSize,this);
|
||||
#endif
|
||||
}
|
||||
|
||||
Instance::~Instance()
|
||||
{
|
||||
/// call it directly incase CI failed and we should always tidy up after create instance
|
||||
callEntry(kOfxActionDestroyInstance, NULL);
|
||||
}
|
||||
|
||||
/// call the entry point in the descriptor with action and the given args
|
||||
OfxStatus Instance::callEntry(const char *action, Property::Set *inArgs)
|
||||
{
|
||||
if(_state != eFailed) {
|
||||
OfxPropertySetHandle inHandle = inArgs ? inArgs->getHandle() : NULL ;
|
||||
return _descriptor.callEntry(action, getHandle(), inHandle, NULL);
|
||||
}
|
||||
return kOfxStatFailed;
|
||||
}
|
||||
|
||||
// do nothing
|
||||
int Instance::getDimension(const std::string &name) const
|
||||
{
|
||||
if(name == kOfxInteractPropPixelScale){
|
||||
return 2;
|
||||
}
|
||||
else if(name == kOfxInteractPropBackgroundColour){
|
||||
return 3;
|
||||
}
|
||||
else if(name == kOfxInteractPropSuggestedColour
|
||||
){
|
||||
return 3;
|
||||
}
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
else if(name == kOfxInteractPropViewportSize){
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
// do nothing function
|
||||
void Instance::reset(const std::string &/*name*/)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
double Instance::getDoubleProperty(const std::string &name, int index) const
|
||||
{
|
||||
if(name == kOfxInteractPropPixelScale){
|
||||
if(index>=2) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
double first[2];
|
||||
getPixelScale(first[0],first[1]);
|
||||
return first[index];
|
||||
}
|
||||
else if(name == kOfxInteractPropBackgroundColour){
|
||||
if(index>=3) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
double first[3];
|
||||
getBackgroundColour(first[0],first[1],first[2]);
|
||||
return first[index];
|
||||
}
|
||||
else if(name == kOfxInteractPropSuggestedColour
|
||||
){
|
||||
if(index>=3) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
double first[3];
|
||||
bool stat = getSuggestedColour(first[0],first[1],first[2]);
|
||||
if (!stat) throw Property::Exception(kOfxStatReplyDefault);
|
||||
return first[index];
|
||||
}
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
else if(name == kOfxInteractPropViewportSize){
|
||||
if(index>=2) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
double first[2];
|
||||
getViewportSize(first[0],first[1]);
|
||||
return first[index];
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrUnknown);
|
||||
}
|
||||
|
||||
void Instance::getDoublePropertyN(const std::string &name, double *first, int n) const
|
||||
{
|
||||
if(name == kOfxInteractPropPixelScale){
|
||||
if(n>2) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
getPixelScale(first[0],first[1]);
|
||||
}
|
||||
else if(name == kOfxInteractPropBackgroundColour){
|
||||
if(n>3) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
getBackgroundColour(first[0],first[1],first[2]);
|
||||
}
|
||||
else if(name == kOfxInteractPropSuggestedColour
|
||||
){
|
||||
if(n>3) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
bool stat = getSuggestedColour(first[0],first[1],first[2]);
|
||||
if (!stat) throw Property::Exception(kOfxStatReplyDefault);
|
||||
}
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
else if(name == kOfxInteractPropViewportSize){
|
||||
if(n>2) throw Property::Exception(kOfxStatErrBadIndex);
|
||||
getViewportSize(first[0],first[1]);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw Property::Exception(kOfxStatErrUnknown);
|
||||
}
|
||||
|
||||
void Instance::getSlaveToParam(std::vector<std::string>& params) const
|
||||
{
|
||||
int nSlaveParams = _properties.getDimension(kOfxInteractPropSlaveToParam);
|
||||
|
||||
for (int i=0; i<nSlaveParams; i++) {
|
||||
std::string param = _properties.getStringProperty(kOfxInteractPropSlaveToParam, i);
|
||||
params.push_back(param);
|
||||
}
|
||||
}
|
||||
|
||||
/// initialise the argument properties
|
||||
void Instance::initArgProp(OfxTime time,
|
||||
const OfxPointD &renderScale)
|
||||
{
|
||||
double pixelScale[2];
|
||||
getPixelScale(pixelScale[0], pixelScale[1]);
|
||||
_argProperties.setDoublePropertyN(kOfxInteractPropPixelScale, pixelScale, 2);
|
||||
_argProperties.setPointerProperty(kOfxPropEffectInstance, _effectInstance);
|
||||
_argProperties.setPointerProperty(kOfxPropInstanceData, _properties.getPointerProperty(kOfxPropInstanceData));
|
||||
_argProperties.setDoubleProperty(kOfxPropTime,time);
|
||||
_argProperties.setDoublePropertyN(kOfxImageEffectPropRenderScale, &renderScale.x, 2);
|
||||
}
|
||||
|
||||
void Instance::setPenArgProps(const OfxPointD &penPos,
|
||||
const OfxPointI &penPosViewport,
|
||||
double pressure)
|
||||
{
|
||||
_argProperties.setDoublePropertyN(kOfxInteractPropPenPosition, &penPos.x, 2);
|
||||
_argProperties.setIntPropertyN(kOfxInteractPropPenViewportPosition, &penPosViewport.x, 2); // new in OFX 1.2
|
||||
_argProperties.setDoubleProperty(kOfxInteractPropPenPressure, pressure);
|
||||
}
|
||||
|
||||
void Instance::setKeyArgProps(int key,
|
||||
char* keyString)
|
||||
{
|
||||
_argProperties.setIntProperty(kOfxPropKeySym,key);
|
||||
_argProperties.setStringProperty(kOfxPropKeyString,keyString);
|
||||
}
|
||||
|
||||
OfxStatus Instance::createInstanceAction()
|
||||
{
|
||||
OfxStatus stat = callEntry(kOfxActionCreateInstance, NULL);
|
||||
if(stat == kOfxStatOK || stat == kOfxStatReplyDefault) {
|
||||
_state = eCreated;
|
||||
}
|
||||
else {
|
||||
_state = eFailed;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
OfxStatus Instance::drawAction(OfxTime time,
|
||||
const OfxPointD &renderScale)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
return callEntry(kOfxInteractActionDraw, &_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::penMotionAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
const OfxPointD &penPos,
|
||||
const OfxPointI &penPosViewport,
|
||||
double pressure)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setPenArgProps(penPos, penPosViewport, pressure);
|
||||
return callEntry(kOfxInteractActionPenMotion,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::penUpAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
const OfxPointD &penPos,
|
||||
const OfxPointI &penPosViewport,
|
||||
double pressure)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setPenArgProps(penPos, penPosViewport, pressure);
|
||||
return callEntry(kOfxInteractActionPenUp,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::penDownAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
const OfxPointD &penPos,
|
||||
const OfxPointI &penPosViewport,
|
||||
double pressure)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setPenArgProps(penPos, penPosViewport, pressure);
|
||||
return callEntry(kOfxInteractActionPenDown,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::keyDownAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
int key,
|
||||
char* keyString)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setKeyArgProps(key, keyString);
|
||||
return callEntry(kOfxInteractActionKeyDown,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::keyUpAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
int key,
|
||||
char* keyString)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setKeyArgProps(key, keyString);
|
||||
return callEntry(kOfxInteractActionKeyUp,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::keyRepeatAction(OfxTime time,
|
||||
const OfxPointD &renderScale,
|
||||
int key,
|
||||
char* keyString)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
setKeyArgProps(key, keyString);
|
||||
return callEntry(kOfxInteractActionKeyRepeat,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::gainFocusAction(OfxTime time,
|
||||
const OfxPointD &renderScale)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
return callEntry(kOfxInteractActionGainFocus,&_argProperties);
|
||||
}
|
||||
|
||||
OfxStatus Instance::loseFocusAction(OfxTime time,
|
||||
const OfxPointD &renderScale)
|
||||
{
|
||||
initArgProp(time, renderScale);
|
||||
return callEntry(kOfxInteractActionLoseFocus,&_argProperties);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interact suite functions
|
||||
|
||||
static OfxStatus interactSwapBuffers(OfxInteractHandle handle)
|
||||
{
|
||||
try {
|
||||
Interact::Instance *interactInstance = reinterpret_cast<Interact::Instance*>(handle);
|
||||
if(interactInstance)
|
||||
return interactInstance->swapBuffers();
|
||||
else
|
||||
return kOfxStatErrBadHandle;
|
||||
} catch (...) {
|
||||
return kOfxStatFailed;
|
||||
}
|
||||
}
|
||||
|
||||
static OfxStatus interactRedraw(OfxInteractHandle handle)
|
||||
{
|
||||
try {
|
||||
Interact::Instance *interactInstance = reinterpret_cast<Interact::Instance*>(handle);
|
||||
if(interactInstance)
|
||||
return interactInstance->redraw();
|
||||
else
|
||||
return kOfxStatErrBadHandle;
|
||||
} catch (...) {
|
||||
return kOfxStatFailed;
|
||||
}
|
||||
}
|
||||
|
||||
static OfxStatus interactGetPropertySet(OfxInteractHandle handle, OfxPropertySetHandle *property)
|
||||
{
|
||||
try {
|
||||
Interact::Base *interact = reinterpret_cast<Interact::Base*>(handle);
|
||||
if (!property) {
|
||||
return kOfxStatErrBadHandle;
|
||||
}
|
||||
|
||||
if (interact) {
|
||||
*property = interact->getPropHandle();
|
||||
|
||||
return kOfxStatOK;
|
||||
}
|
||||
*property = NULL;
|
||||
|
||||
return kOfxStatErrBadHandle;
|
||||
} catch (...) {
|
||||
return kOfxStatFailed;
|
||||
}
|
||||
}
|
||||
|
||||
/// the interact suite
|
||||
static const OfxInteractSuiteV1 gSuite = {
|
||||
interactSwapBuffers,
|
||||
interactRedraw,
|
||||
interactGetPropertySet
|
||||
};
|
||||
|
||||
/// function to get the sutie
|
||||
const void *GetSuite(int version) {
|
||||
if(version == 1)
|
||||
return (void *) &gSuite;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // Interact
|
||||
|
||||
} // Host
|
||||
|
||||
} // OFX
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
// ofx host
|
||||
|
||||
// ofx
|
||||
#include "ofxCore.h"
|
||||
#include "ofxImageEffect.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhMemory.h"
|
||||
|
||||
namespace OFX {
|
||||
|
||||
namespace Host {
|
||||
|
||||
namespace Memory {
|
||||
|
||||
Instance::Instance() : _ptr(0), _locked(0) {}
|
||||
|
||||
Instance::~Instance() {
|
||||
delete [] _ptr;
|
||||
}
|
||||
|
||||
bool Instance::alloc(size_t nBytes) {
|
||||
if(!_locked){
|
||||
if(_ptr)
|
||||
freeMem();
|
||||
_ptr = new char[nBytes];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
OfxImageMemoryHandle Instance::getHandle(){
|
||||
return (OfxImageMemoryHandle)this;
|
||||
}
|
||||
|
||||
void Instance::freeMem(){
|
||||
delete [] _ptr;
|
||||
_ptr = 0;
|
||||
_locked = 0;
|
||||
}
|
||||
|
||||
void* Instance::getPtr() {
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
void Instance::lock() {
|
||||
++_locked;
|
||||
}
|
||||
|
||||
void Instance::unlock() {
|
||||
if (_locked > 0) {
|
||||
--_locked;
|
||||
}
|
||||
}
|
||||
|
||||
} // Memory
|
||||
|
||||
} // Host
|
||||
|
||||
} // OFX
|
||||
|
||||
+2300
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// ofx
|
||||
#include "ofxCore.h"
|
||||
#include "ofxImageEffect.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhBinary.h"
|
||||
#include "ofxhPropertySuite.h"
|
||||
#include "ofxhClip.h"
|
||||
#include "ofxhParam.h"
|
||||
#include "ofxhMemory.h"
|
||||
#include "ofxhImageEffect.h"
|
||||
#include "ofxhPluginAPICache.h"
|
||||
#include "ofxhPluginCache.h"
|
||||
#include "ofxhHost.h"
|
||||
#include "ofxhImageEffectAPI.h"
|
||||
#include "ofxhXml.h"
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Host
|
||||
{
|
||||
namespace APICache
|
||||
{
|
||||
void PluginAPICacheI::registerInCache(OFX::Host::PluginCache &pluginCache) {
|
||||
pluginCache.registerAPICache(_apiName, _apiVersionMin, _apiVersionMax, this);
|
||||
}
|
||||
|
||||
void propertySetXMLRead(const std::string &el,
|
||||
std::map<std::string, std::string> map,
|
||||
Property::Set &set,
|
||||
Property::Property *¤tProp) {
|
||||
if (el == "property") {
|
||||
std::string propName = map["name"];
|
||||
std::string propType = map["type"];
|
||||
int dimension = atoi(map["dimension"].c_str());
|
||||
|
||||
currentProp = set.fetchProperty(propName, false);
|
||||
|
||||
if(!currentProp) {
|
||||
if (propType == "int") {
|
||||
currentProp = new Property::Int(propName, dimension, false, 0);
|
||||
} else if (propType == "string") {
|
||||
currentProp = new Property::String(propName, dimension, false, "");
|
||||
} else if (propType == "double") {
|
||||
currentProp = new Property::Double(propName, dimension, false, 0);
|
||||
} else if (propType == "pointer") {
|
||||
currentProp = new Property::Pointer(propName, dimension, false, 0);
|
||||
}
|
||||
set.addProperty(currentProp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (el == "value" && currentProp) {
|
||||
int index = atoi(map["index"].c_str());
|
||||
std::string value = map["value"];
|
||||
|
||||
switch (currentProp->getType()) {
|
||||
case Property::eInt:
|
||||
set.setIntProperty(currentProp->getName(), atoi(value.c_str()), index);
|
||||
break;
|
||||
case Property::eString:
|
||||
set.setStringProperty(currentProp->getName(), value, index);
|
||||
break;
|
||||
case Property::eDouble:
|
||||
set.setDoubleProperty(currentProp->getName(), atof(value.c_str()), index);
|
||||
break;
|
||||
case Property::ePointer:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "got unrecognised key " << el << "\n";
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
static void propertyXMLWrite(std::ostream &o, Property::Property *prop, const std::string &indent="")
|
||||
{
|
||||
if (prop->getType() != Property::ePointer) {
|
||||
|
||||
o << indent << "<property "
|
||||
<< XML::attribute("name", prop->getName())
|
||||
<< XML::attribute("type", Property::gTypeNames[prop->getType()])
|
||||
<< XML::attribute("dimension", prop->getFixedDimension())
|
||||
<< ">\n";
|
||||
|
||||
for (int i=0;i<prop->getDimension();i++) {
|
||||
o << indent << " <value "
|
||||
<< XML::attribute("index", i)
|
||||
<< XML::attribute("value", prop->getStringValue(i))
|
||||
<< "/>\n";
|
||||
}
|
||||
|
||||
o << indent << "</property>\n";
|
||||
}
|
||||
}
|
||||
|
||||
void propertyXMLWrite(std::ostream &o, const Property::Set &set, const std::string &name, int indent)
|
||||
{
|
||||
Property::Property *prop = set.fetchProperty(name);
|
||||
|
||||
if(prop) {
|
||||
std::string indent_prefix(indent, ' ');
|
||||
propertyXMLWrite(o, prop, indent_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void propertySetXMLWrite(std::ostream &o, const Property::Set &set, int indent)
|
||||
{
|
||||
std::string indent_prefix(indent, ' ');
|
||||
|
||||
for (Property::PropertyMap::const_iterator i = set.getProperties().begin();
|
||||
i != set.getProperties().end();
|
||||
i++)
|
||||
{
|
||||
Property::Property *prop = i->second;
|
||||
propertyXMLWrite(o, prop, indent_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,694 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "expat.h"
|
||||
|
||||
// ofx
|
||||
#include "ofxCore.h"
|
||||
#include "ofxImageEffect.h"
|
||||
|
||||
// ofx host
|
||||
#include "ofxhBinary.h"
|
||||
#include "ofxhPropertySuite.h"
|
||||
#include "ofxhMemory.h"
|
||||
#include "ofxhPluginAPICache.h"
|
||||
#include "ofxhPluginCache.h"
|
||||
#include "ofxhHost.h"
|
||||
#include "ofxhXml.h"
|
||||
|
||||
#if defined (__linux__) || defined (__FreeBSD__)
|
||||
|
||||
#define DIRLIST_SEP_CHARS ":;"
|
||||
#define DIRSEP "/"
|
||||
#include <dirent.h>
|
||||
|
||||
static const char *getArchStr()
|
||||
{
|
||||
if(sizeof(void *) == 4) {
|
||||
#if defined(__linux__)
|
||||
return "Linux-x86";
|
||||
#else
|
||||
return "FreeBSD-x86";
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if defined(__linux__)
|
||||
return "Linux-x86-64";
|
||||
#else
|
||||
return "FreeBSD-x86-64";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#define ARCHSTR getArchStr()
|
||||
|
||||
#elif defined (__APPLE__)
|
||||
|
||||
#define DIRLIST_SEP_CHARS ";:"
|
||||
#if defined(__x86_64) || defined(__x86_64__)
|
||||
#define ARCHSTR "MacOS-x86-64"
|
||||
#else
|
||||
#define ARCHSTR "MacOS"
|
||||
#endif
|
||||
#define DIRSEP "/"
|
||||
#include <dirent.h>
|
||||
|
||||
#elif defined (WINDOWS)
|
||||
#define DIRLIST_SEP_CHARS ";"
|
||||
#ifdef _WIN64
|
||||
#define ARCHSTR "win64"
|
||||
#else
|
||||
#define ARCHSTR "win32"
|
||||
#endif
|
||||
#define DIRSEP "\\"
|
||||
|
||||
#include "shlobj.h"
|
||||
#include "tchar.h"
|
||||
#endif
|
||||
|
||||
OFX::Host::PluginCache* OFX::Host::PluginCache::gPluginCachePtr = 0;
|
||||
|
||||
// Define this to enable ofx plugin cache debug messages.
|
||||
//#define CACHE_DEBUG
|
||||
|
||||
using namespace OFX::Host;
|
||||
|
||||
|
||||
/// try to open the plugin bundle object and query it for plugins
|
||||
void PluginBinary::loadPluginInfo(PluginCache *cache) {
|
||||
if (isInvalid()) {
|
||||
return;
|
||||
}
|
||||
_fileModificationTime = _binary.getTime();
|
||||
_fileSize = _binary.getSize();
|
||||
_binaryChanged = false;
|
||||
|
||||
// Take a reference to load the binary only once per session. It will
|
||||
// eventually be unloaded in the destructor (see below).
|
||||
// This avoid lots of useless calls to dlopen()/dlclose().
|
||||
if (!_binary.isLoaded()) {
|
||||
_binary.ref();
|
||||
}
|
||||
|
||||
int (*getNo)(void) = (int(*)()) _binary.findSymbol("OfxGetNumberOfPlugins");
|
||||
OfxPlugin* (*getPlug)(int) = (OfxPlugin*(*)(int)) _binary.findSymbol("OfxGetPlugin");
|
||||
|
||||
if (getNo == 0 || getPlug == 0) {
|
||||
|
||||
_binary.setInvalid(true);
|
||||
|
||||
} else {
|
||||
int pluginCount = (*getNo)();
|
||||
|
||||
_plugins.reserve(pluginCount);
|
||||
|
||||
for (int i=0;i<pluginCount;i++) {
|
||||
OfxPlugin *plug = (*getPlug)(i);
|
||||
|
||||
APICache::PluginAPICacheI *api = cache->findApiHandler(plug->pluginApi, plug->apiVersion);
|
||||
assert(api);
|
||||
|
||||
_plugins.push_back(api->newPlugin(this, i, plug));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PluginBinary::~PluginBinary() {
|
||||
std::vector<Plugin*>::iterator i = _plugins.begin();
|
||||
while (i != _plugins.end()) {
|
||||
delete *i;
|
||||
i++;
|
||||
}
|
||||
// release the last reference to the binary, which should unload it
|
||||
// if this reference was taken by loadPluginInfo().
|
||||
if (_binary.isLoaded()) {
|
||||
_binary.unref();
|
||||
}
|
||||
assert(!_binary.isLoaded());
|
||||
}
|
||||
|
||||
PluginHandle::PluginHandle(Plugin *p, OFX::Host::Host *host)
|
||||
{
|
||||
_b = p->getBinary();
|
||||
_b->_binary.ref();
|
||||
_op = 0;
|
||||
OfxPlugin* (*getPlug)(int) = (OfxPlugin*(*)(int)) _b->_binary.findSymbol("OfxGetPlugin");
|
||||
if (getPlug) {
|
||||
_op = getPlug(p->getIndex());
|
||||
if (_op) {
|
||||
_op->setHost(host->getHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PluginHandle::~PluginHandle() {
|
||||
_b->_binary.unref();
|
||||
}
|
||||
|
||||
|
||||
#if defined (WINDOWS)
|
||||
const TCHAR *getStdOFXPluginPath(const std::string &hostId = "Plugins")
|
||||
{
|
||||
static TCHAR buffer[MAX_PATH];
|
||||
static int gotIt = 0;
|
||||
if(!gotIt) {
|
||||
gotIt = 1;
|
||||
SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, SHGFP_TYPE_CURRENT, buffer);
|
||||
strcat_s(buffer, MAX_PATH, __T("\\OFX\\Plugins"));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
std::string OFXGetEnv(const char* e)
|
||||
{
|
||||
#if defined(WINDOWS) && !defined(__MINGW32__)
|
||||
size_t requiredSize;
|
||||
getenv_s(&requiredSize, 0, 0, e);
|
||||
std::vector<char> buffer(requiredSize);
|
||||
if(requiredSize >0)
|
||||
{
|
||||
getenv_s(&requiredSize, &buffer.front(), requiredSize, e);
|
||||
return &buffer.front();
|
||||
}
|
||||
return "";
|
||||
#else
|
||||
if(getenv(e))
|
||||
return getenv(e);
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
PluginCache* PluginCache::getPluginCache()
|
||||
{
|
||||
if(!gPluginCachePtr)
|
||||
gPluginCachePtr = new PluginCache();
|
||||
return gPluginCachePtr;
|
||||
}
|
||||
|
||||
void PluginCache::clearPluginCache()
|
||||
{
|
||||
delete gPluginCachePtr;
|
||||
gPluginCachePtr = 0;
|
||||
}
|
||||
|
||||
PluginCache::~PluginCache()
|
||||
{
|
||||
for(std::list<PluginBinary *>::iterator it=_binaries.begin(); it != _binaries.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
_binaries.clear();
|
||||
}
|
||||
|
||||
PluginCache::PluginCache() : _hostSpec(0), _xmlCurrentBinary(0), _xmlCurrentPlugin(0) {
|
||||
|
||||
_cacheVersion = "";
|
||||
_ignoreCache = false;
|
||||
_dirty = false;
|
||||
_enablePluginSeek = true;
|
||||
|
||||
std::string s = OFXGetEnv("OFX_PLUGIN_PATH");
|
||||
|
||||
|
||||
while (s.length()) {
|
||||
|
||||
int spos = int(s.find_first_of(DIRLIST_SEP_CHARS));
|
||||
|
||||
std::string path;
|
||||
|
||||
if (spos != -1) {
|
||||
path = s.substr(0, spos);
|
||||
s = s.substr(spos+1);
|
||||
}
|
||||
else {
|
||||
path = s;
|
||||
s = "";
|
||||
}
|
||||
|
||||
_pluginPath.push_back(path);
|
||||
}
|
||||
|
||||
#if defined(WINDOWS)
|
||||
_pluginPath.push_back(getStdOFXPluginPath());
|
||||
_pluginPath.push_back("C:\\Program Files\\Common Files\\OFX\\Plugins");
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
_pluginPath.push_back("/usr/OFX/Plugins");
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
_pluginPath.push_back("/Library/OFX/Plugins");
|
||||
#endif
|
||||
}
|
||||
|
||||
void PluginCache::setPluginHostPath(const std::string &hostId) {
|
||||
#if defined(WINDOWS)
|
||||
_pluginPath.push_back(getStdOFXPluginPath(hostId));
|
||||
_pluginPath.push_back("C:\\Program Files\\Common Files\\OFX\\" + hostId);
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
_pluginPath.push_back("/usr/OFX/" + hostId);
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
_pluginPath.push_back("/Library/OFX/" + hostId);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PluginCache::scanDirectory(std::set<std::string> &foundBinFiles, const std::string &dir, bool recurse)
|
||||
{
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("looking in %s for plugins\n", dir.c_str());
|
||||
#endif
|
||||
|
||||
#if defined (WINDOWS)
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE findHandle;
|
||||
#else
|
||||
DIR *d = opendir(dir.c_str());
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
_pluginDirs.push_back(dir.c_str());
|
||||
|
||||
#if defined (UNIX)
|
||||
while (dirent *de = readdir(d))
|
||||
#elif defined (WINDOWS)
|
||||
findHandle = FindFirstFile((dir + "\\*").c_str(), &findData);
|
||||
|
||||
if (findHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
#endif
|
||||
{
|
||||
#if defined (UNIX)
|
||||
std::string name = de->d_name;
|
||||
bool isdir = true;
|
||||
#else
|
||||
std::string name = findData.cFileName;
|
||||
bool isdir = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
#endif
|
||||
if (name.find(".ofx.bundle") != std::string::npos) {
|
||||
std::string barename = name.substr(0, name.length() - strlen(".bundle"));
|
||||
std::string bundlename = dir + DIRSEP + name;
|
||||
std::string binpath = dir + DIRSEP + name + DIRSEP "Contents" DIRSEP + ARCHSTR + DIRSEP + barename;
|
||||
|
||||
// don't insert binpath yet, do it later because of Mac OS X Universal stuff
|
||||
//foundBinFiles.insert(binpath);
|
||||
|
||||
#if defined(__APPLE__) && (defined(__x86_64) || defined(__x86_64__))
|
||||
/* From the OpenFX specification:
|
||||
|
||||
MacOS-x86-64 - for Apple Macintosh OS X, specifically on
|
||||
intel x86 CPUs running AMD's 64 bit extensions. 64 bit host
|
||||
applications should check this first, and if it doesn't
|
||||
exist or is empty, fall back to "MacOS" looking for a
|
||||
universal binary.
|
||||
*/
|
||||
|
||||
std::string binpath_universal = dir + DIRSEP + name + DIRSEP "Contents" DIRSEP + "MacOS" + DIRSEP + barename;
|
||||
if (_knownBinFiles.find(binpath_universal) != _knownBinFiles.end()) {
|
||||
binpath = binpath_universal;
|
||||
}
|
||||
#endif
|
||||
if (_knownBinFiles.find(binpath) == _knownBinFiles.end()) {
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("found non-cached binary %s\n", binpath.c_str());
|
||||
#endif
|
||||
_dirty = true;
|
||||
|
||||
// the binary was not in the cache
|
||||
|
||||
PluginBinary *pb = 0;
|
||||
#if defined(__x86_64) || defined(__x86_64__)
|
||||
pb = new PluginBinary(binpath, bundlename, this);
|
||||
# if defined(__APPLE__)
|
||||
if (pb->isInvalid()) {
|
||||
// fallback to "MacOS"
|
||||
delete pb;
|
||||
binpath = binpath_universal;
|
||||
pb = new PluginBinary(binpath, bundlename, this);
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
pb = new PluginBinary(binpath, bundlename, this);
|
||||
#endif
|
||||
_binaries.push_back(pb);
|
||||
_knownBinFiles.insert(binpath);
|
||||
foundBinFiles.insert(binpath);
|
||||
|
||||
for (int j=0;j<pb->getNPlugins();j++) {
|
||||
Plugin *plug = &pb->getPlugin(j);
|
||||
const APICache::PluginAPICacheI &api = plug->getApiHandler();
|
||||
api.loadFromPlugin(plug);
|
||||
}
|
||||
} else {
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("found cached binary %s\n", binpath.c_str());
|
||||
#endif
|
||||
}
|
||||
// insert final path (universal or not) in the list of found files
|
||||
foundBinFiles.insert(binpath);
|
||||
} else {
|
||||
if (isdir && (recurse && name[0] != '@' && name != "." && name != "..")) {
|
||||
scanDirectory(foundBinFiles, dir + DIRSEP + name, recurse);
|
||||
}
|
||||
}
|
||||
#if defined(WINDOWS)
|
||||
int rval = FindNextFile(findHandle, &findData);
|
||||
|
||||
if (rval == 0) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UNIX)
|
||||
closedir(d);
|
||||
#else
|
||||
FindClose(findHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PluginCache::seekPluginFile(const std::string &baseName) const {
|
||||
// Exit early if disabled
|
||||
if (!_enablePluginSeek)
|
||||
return "";
|
||||
|
||||
for (std::list<std::string>::const_iterator paths= _pluginDirs.begin();
|
||||
paths != _pluginDirs.end();
|
||||
paths++) {
|
||||
std::string candidate = *paths + DIRSEP + baseName;
|
||||
FILE *f = fopen(candidate.c_str(), "r");
|
||||
if (f) {
|
||||
fclose(f);
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void PluginCache::scanPluginFiles()
|
||||
{
|
||||
std::set<std::string> foundBinFiles;
|
||||
|
||||
for (std::list<std::string>::iterator paths= _pluginPath.begin();
|
||||
paths != _pluginPath.end();
|
||||
paths++) {
|
||||
scanDirectory(foundBinFiles, *paths, _nonrecursePath.find(*paths) == _nonrecursePath.end());
|
||||
}
|
||||
|
||||
std::list<PluginBinary *>::iterator i=_binaries.begin();
|
||||
while (i!=_binaries.end()) {
|
||||
PluginBinary *pb = *i;
|
||||
|
||||
if (foundBinFiles.find(pb->getFilePath()) == foundBinFiles.end()) {
|
||||
|
||||
// the binary was in the cache, but was not on the path
|
||||
|
||||
_dirty = true;
|
||||
i = _binaries.erase(i);
|
||||
delete pb;
|
||||
|
||||
} else {
|
||||
|
||||
bool binChanged = pb->hasBinaryChanged();
|
||||
|
||||
// the binary was in the cache, but the binary has changed and thus we need to reload
|
||||
if (binChanged) {
|
||||
pb->loadPluginInfo(this);
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
for (int j=0;j<pb->getNPlugins();j++) {
|
||||
Plugin *plug = &pb->getPlugin(j);
|
||||
APICache::PluginAPICacheI &api = plug->getApiHandler();
|
||||
|
||||
if (binChanged) {
|
||||
api.loadFromPlugin(plug);
|
||||
}
|
||||
|
||||
std::string reason;
|
||||
|
||||
if (api.pluginSupported(plug, reason)) {
|
||||
_plugins.push_back(plug);
|
||||
api.confirmPlugin(plug);
|
||||
} else {
|
||||
std::cerr << "ignoring plugin " << plug->getIdentifier() <<
|
||||
" as unsupported (" << reason << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// callback for XML parser
|
||||
static void elementBeginHandler(void *userData, const XML_Char *name, const XML_Char **atts) {
|
||||
PluginCache::getPluginCache()->elementBeginCallback(userData, name, atts);
|
||||
}
|
||||
|
||||
/// callback for XML parser
|
||||
static void elementCharHandler(void *userData, const XML_Char *data, int len) {
|
||||
PluginCache::getPluginCache()->elementCharCallback(userData, data, len);
|
||||
}
|
||||
|
||||
/// callback for XML parser
|
||||
static void elementEndHandler(void *userData, const XML_Char *name) {
|
||||
PluginCache::getPluginCache()->elementEndCallback(userData, name);
|
||||
}
|
||||
|
||||
static bool mapHasAll(const std::map<std::string, std::string> &attmap, const char **atts) {
|
||||
while (*atts) {
|
||||
if (attmap.find(*atts) == attmap.end()) {
|
||||
return false;
|
||||
}
|
||||
atts++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginCache::elementBeginCallback(void */*userData*/, const XML_Char *name, const XML_Char **atts) {
|
||||
if (_ignoreCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ename = name;
|
||||
std::map<std::string, std::string> attmap;
|
||||
|
||||
while (*atts) {
|
||||
attmap[atts[0]] = atts[1];
|
||||
atts += 2;
|
||||
}
|
||||
|
||||
/// XXX: validate in general
|
||||
|
||||
if (ename == "cache") {
|
||||
std::string cacheversion = attmap["version"];
|
||||
if (cacheversion != _cacheVersion) {
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("mismatched version, ignoring cache (got '%s', wanted '%s')\n",
|
||||
cacheversion.c_str(),
|
||||
_cacheVersion.c_str());
|
||||
#endif
|
||||
_ignoreCache = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ename == "binary") {
|
||||
const char *binAtts[] = {"path", "bundle_path", "mtime", "size", NULL};
|
||||
|
||||
if (!mapHasAll(attmap, binAtts)) {
|
||||
// no path: bad XML
|
||||
}
|
||||
|
||||
std::string fname = attmap["path"];
|
||||
std::string bname = attmap["bundle_path"];
|
||||
time_t mtime = OFX::Host::Property::stringToInt(attmap["mtime"]);
|
||||
size_t size = OFX::Host::Property::stringToInt(attmap["size"]);
|
||||
|
||||
_xmlCurrentBinary = new PluginBinary(fname, bname, mtime, size);
|
||||
_binaries.push_back(_xmlCurrentBinary);
|
||||
_knownBinFiles.insert(fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ename == "plugin" && _xmlCurrentBinary && !_xmlCurrentBinary->hasBinaryChanged()) {
|
||||
const char *plugAtts[] = {"api", "name", "index", "api_version", "major_version", "minor_version", NULL};
|
||||
|
||||
if (!mapHasAll(attmap, plugAtts)) {
|
||||
// no path: bad XML
|
||||
}
|
||||
|
||||
std::string api = attmap["api"];
|
||||
std::string rawIdentifier = attmap["name"];
|
||||
|
||||
std::string identifier = rawIdentifier;
|
||||
|
||||
// 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]);
|
||||
//}
|
||||
|
||||
int idx = OFX::Host::Property::stringToInt(attmap["index"]);
|
||||
int api_version = OFX::Host::Property::stringToInt(attmap["api_version"]);
|
||||
int major_version = OFX::Host::Property::stringToInt(attmap["major_version"]);
|
||||
int minor_version = OFX::Host::Property::stringToInt(attmap["minor_version"]);
|
||||
|
||||
APICache::PluginAPICacheI *apiCache = findApiHandler(api, api_version);
|
||||
if (apiCache) {
|
||||
|
||||
Plugin *pe = apiCache->newPlugin(_xmlCurrentBinary, idx, api, api_version, identifier, rawIdentifier, major_version, minor_version);
|
||||
_xmlCurrentBinary->addPlugin(pe);
|
||||
_xmlCurrentPlugin = pe;
|
||||
apiCache->beginXmlParsing(pe);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_xmlCurrentPlugin) {
|
||||
APICache::PluginAPICacheI &api = _xmlCurrentPlugin->getApiHandler();
|
||||
api.xmlElementBegin(name, attmap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PluginCache::elementCharCallback(void */*userData*/, const XML_Char *data, int size)
|
||||
{
|
||||
if (_ignoreCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string s(data, size);
|
||||
if (_xmlCurrentPlugin) {
|
||||
APICache::PluginAPICacheI &api = _xmlCurrentPlugin->getApiHandler();
|
||||
api.xmlCharacterHandler(s);
|
||||
} else {
|
||||
/// XXX: we only want whitespace
|
||||
}
|
||||
}
|
||||
|
||||
void PluginCache::elementEndCallback(void */*userData*/, const XML_Char *name) {
|
||||
if (_ignoreCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ename = name;
|
||||
|
||||
/// XXX: validation?
|
||||
|
||||
if (ename == "plugin") {
|
||||
if (_xmlCurrentPlugin) {
|
||||
APICache::PluginAPICacheI &api = _xmlCurrentPlugin->getApiHandler();
|
||||
api.endXmlParsing();
|
||||
}
|
||||
_xmlCurrentPlugin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ename == "bundle") {
|
||||
_xmlCurrentBinary = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_xmlCurrentPlugin) {
|
||||
APICache::PluginAPICacheI &api = _xmlCurrentPlugin->getApiHandler();
|
||||
api.xmlElementEnd(name);
|
||||
}
|
||||
}
|
||||
|
||||
void PluginCache::readCache(std::istream &ifs) {
|
||||
XML_Parser xP = XML_ParserCreate(NULL);
|
||||
XML_SetElementHandler(xP, elementBeginHandler, elementEndHandler);
|
||||
XML_SetCharacterDataHandler(xP, elementCharHandler);
|
||||
|
||||
while (ifs.good()) {
|
||||
char buf[1001] = {0};
|
||||
ifs.read(buf, 1000);
|
||||
|
||||
if (buf[0] == 0) {
|
||||
XML_Parse(xP, "", 0, XML_TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
int p = XML_Parse(xP, buf, int(strlen(buf)), XML_FALSE);
|
||||
|
||||
if (p == XML_STATUS_ERROR) {
|
||||
std::cout << "xml error : " << XML_GetErrorCode(xP) << std::endl;
|
||||
/// XXX: do something here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XML_ParserFree(xP);
|
||||
}
|
||||
|
||||
void PluginCache::writePluginCache(std::ostream &os) const {
|
||||
#ifdef CACHE_DEBUG
|
||||
printf("writing pluginCache with version = %s\n", _cacheVersion.c_str());
|
||||
#endif
|
||||
|
||||
os << "<cache version=\"" << _cacheVersion << "\">\n";
|
||||
for (std::list<PluginBinary *>::const_iterator i=_binaries.begin();i!=_binaries.end();i++) {
|
||||
PluginBinary *b = *i;
|
||||
os << "<bundle>\n";
|
||||
os << " <binary "
|
||||
<< XML::attribute("bundle_path", b->getBundlePath())
|
||||
<< XML::attribute("path", b->getFilePath())
|
||||
<< XML::attribute("mtime", int(b->getFileModificationTime()))
|
||||
<< XML::attribute("size", int(b->getFileSize())) << "/>\n";
|
||||
|
||||
for (int j=0;j<b->getNPlugins();j++) {
|
||||
Plugin *p = &b->getPlugin(j);
|
||||
|
||||
|
||||
os << " <plugin "
|
||||
<< XML::attribute("name", p->getRawIdentifier())
|
||||
<< XML::attribute("index", p->getIndex())
|
||||
<< XML::attribute("api", p->getPluginApi())
|
||||
<< XML::attribute("api_version", p->getApiVersion())
|
||||
<< XML::attribute("major_version", p->getVersionMajor())
|
||||
<< XML::attribute("minor_version", p->getVersionMinor())
|
||||
<< ">\n";
|
||||
|
||||
const APICache::PluginAPICacheI &api = p->getApiHandler();
|
||||
os << " <apiproperties>\n";
|
||||
api.saveXML(p, os);
|
||||
os << " </apiproperties>\n";
|
||||
|
||||
os << " </plugin>\n";
|
||||
}
|
||||
os << "</bundle>\n";
|
||||
}
|
||||
os << "</cache>\n";
|
||||
}
|
||||
|
||||
|
||||
APICache::PluginAPICacheI *PluginCache::findApiHandler(const std::string &api, int version) {
|
||||
std::list<PluginCacheSupportedApi>::iterator i = _apiHandlers.begin();
|
||||
while (i != _apiHandlers.end()) {
|
||||
if (i->matches(api, version)) {
|
||||
return i->handler;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
#include "ofxCore.h"
|
||||
#include "ofxhUtilities.h"
|
||||
|
||||
namespace OFX {
|
||||
|
||||
/// get me deepest bit depth
|
||||
std::string FindDeepestBitDepth(const std::string &s1, const std::string &s2)
|
||||
{
|
||||
if(s1 == kOfxBitDepthNone) {
|
||||
return s2;
|
||||
}
|
||||
else if(s1 == kOfxBitDepthByte) {
|
||||
if(s2 == kOfxBitDepthShort || s2 == kOfxBitDepthFloat)
|
||||
return s2;
|
||||
return s1;
|
||||
}
|
||||
else if(s1 == kOfxBitDepthShort) {
|
||||
if(s2 == kOfxBitDepthFloat)
|
||||
return s2;
|
||||
return s1;
|
||||
}
|
||||
else if(s1 == kOfxBitDepthHalf) {
|
||||
if(s2 == kOfxBitDepthFloat)
|
||||
return s2;
|
||||
return s1;
|
||||
}
|
||||
else if(s1 == kOfxBitDepthFloat) {
|
||||
return s1;
|
||||
}
|
||||
else {
|
||||
return s2; // oooh this might be bad dad.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
set(OFX_SUPPORT_HEADER_DIR "include")
|
||||
file(GLOB_RECURSE OFX_SUPPORT_HEADER_FILES "${OFX_SUPPORT_HEADER_DIR}/*.h")
|
||||
|
||||
add_subdirectory(Library)
|
||||
if(BUILD_EXAMPLE_PLUGINS)
|
||||
add_subdirectory(Plugins)
|
||||
add_subdirectory(PropTester)
|
||||
endif()
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
Software License :
|
||||
|
||||
Copyright OpenFX and contributors to the OpenFX project.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
run tmpPlugin.bundle
|
||||
where
|
||||
l
|
||||
q
|
||||
run tmpPlugin.bundle
|
||||
where
|
||||
l
|
||||
l
|
||||
p myBundle
|
||||
up
|
||||
p myBundle
|
||||
q
|
||||
run blah.bundle
|
||||
up
|
||||
w
|
||||
where
|
||||
ls
|
||||
w
|
||||
down
|
||||
down
|
||||
up
|
||||
l
|
||||
p myBundle
|
||||
q
|
||||
break main
|
||||
run blah
|
||||
n
|
||||
n
|
||||
p myBundle
|
||||
n
|
||||
q
|
||||
q
|
||||
l
|
||||
l
|
||||
break 17
|
||||
run
|
||||
n
|
||||
p bundleURL
|
||||
n
|
||||
p myBundle
|
||||
n
|
||||
where
|
||||
p myBundle
|
||||
up
|
||||
w
|
||||
l
|
||||
p myBundle
|
||||
q
|
||||
break main
|
||||
run
|
||||
n
|
||||
n
|
||||
p myBundle
|
||||
n
|
||||
n
|
||||
p nPluginsFunc
|
||||
q
|
||||
@@ -0,0 +1,16 @@
|
||||
set(OFX_SUPPORT_LIBRARY_DIR ".")
|
||||
file(GLOB_RECURSE OFX_SUPPORT_LIBRARY_FILES "${OFX_SUPPORT_LIBRARY_DIR}/*.cpp")
|
||||
|
||||
add_library(OfxSupport STATIC
|
||||
${OFX_HEADER_FILES}
|
||||
${OFX_SUPPORT_HEADER_FILES}
|
||||
${OFX_SUPPORT_LIBRARY_FILES})
|
||||
|
||||
set_target_properties(OfxSupport PROPERTIES LINKER_LANGUAGE CXX)
|
||||
if(NOT MSVC)
|
||||
set_target_properties(OfxSupport PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
endif()
|
||||
|
||||
target_include_directories(OfxSupport PUBLIC
|
||||
${OFX_HEADER_DIR}
|
||||
${OFX_SUPPORT_HEADER_DIR})
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
# Microsoft Developer Studio Project File - Name="ofxsupport" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=ofxsupport - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ofxsupport.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ofxsupport.mak" CFG="ofxsupport - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ofxsupport - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ofxsupport - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ofxsupport - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"ofxSupport.lib"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ofxsupport - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo /out:"ofxSupport.lib"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ofxsupport - Win32 Release"
|
||||
# Name "ofxsupport - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsCore.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsImageEffect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsInteract.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsLog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsMultiThread.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsParams.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsProperty.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsPropertyValidation.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ofxsSupportPrivate.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
|
||||
|
||||
#include "ofxsSupportPrivate.h"
|
||||
#ifdef DEBUG
|
||||
#include <iostream>
|
||||
#if defined(__APPLE__) || defined(linux)
|
||||
#include <execinfo.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ofxsMemory.h"
|
||||
|
||||
namespace OFX {
|
||||
/** @brief Throws an @ref OFX::Exception depending on the status flag passed in */
|
||||
void throwSuiteStatusException(OfxStatus stat)
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case kOfxStatOK :
|
||||
case kOfxStatReplyYes :
|
||||
case kOfxStatReplyNo :
|
||||
case kOfxStatReplyDefault :
|
||||
break;
|
||||
|
||||
case kOfxStatErrMemory :
|
||||
throw std::bad_alloc();
|
||||
|
||||
default :
|
||||
# ifdef DEBUG
|
||||
std::cout << "Threw suite exception!" << std::endl;
|
||||
# if defined(__APPLE__) || defined(linux)
|
||||
void* callstack[128];
|
||||
int i, frames = backtrace(callstack, 128);
|
||||
char** strs = backtrace_symbols(callstack, frames);
|
||||
for (i = 0; i < frames; ++i) {
|
||||
std::cout << strs[i] << std::endl;
|
||||
}
|
||||
free(strs);
|
||||
# endif
|
||||
# endif
|
||||
throw OFX::Exception::Suite(stat);
|
||||
}
|
||||
}
|
||||
|
||||
void throwHostMissingSuiteException(std::string name)
|
||||
{
|
||||
# ifdef DEBUG
|
||||
std::cout << "Threw suite exception! Host missing '" << name << "' suite." << std::endl;
|
||||
# if defined(__APPLE__) || defined(linux)
|
||||
void* callstack[128];
|
||||
int i, frames = backtrace(callstack, 128);
|
||||
char** strs = backtrace_symbols(callstack, frames);
|
||||
for (i = 0; i < frames; ++i) {
|
||||
std::cout << strs[i] << std::endl;
|
||||
}
|
||||
free(strs);
|
||||
# endif
|
||||
# endif
|
||||
throw OFX::Exception::Suite(kOfxStatErrUnsupported);
|
||||
}
|
||||
|
||||
|
||||
/** @brief maps status to a string */
|
||||
const char* mapStatusToString(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";
|
||||
case kOfxStatErrImageFormat : return "kOfxStatErrImageFormat";
|
||||
}
|
||||
return "UNKNOWN STATUS CODE";
|
||||
}
|
||||
|
||||
|
||||
/** @brief namespace for memory allocation that is done via wrapping the ofx memory suite */
|
||||
namespace Memory {
|
||||
/** @brief allocate n bytes, returns a pointer to it */
|
||||
void *allocate(size_t nBytes, ImageEffect *effect)
|
||||
{
|
||||
void *data = 0;
|
||||
OfxStatus stat = OFX::Private::gMemorySuite->memoryAlloc((void *)(effect ? effect->getHandle() : 0), nBytes, &data);
|
||||
if(stat != kOfxStatOK)
|
||||
throw std::bad_alloc();
|
||||
return data;
|
||||
}
|
||||
|
||||
/** @brief free n previously allocated memory */
|
||||
void free(void *ptr) throw()
|
||||
{
|
||||
if(ptr)
|
||||
// note we are ignore errors, this could be bad, but we don't throw on a destruction
|
||||
OFX::Private::gMemorySuite->memoryFree(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}; // namespace OFX
|
||||
|
||||
+3078
File diff suppressed because it is too large
Load Diff
+546
@@ -0,0 +1,546 @@
|
||||
|
||||
|
||||
/** @brief This file contains code that skins the ofx interact suite (for image effects) */
|
||||
|
||||
|
||||
#include "ofxsSupportPrivate.h"
|
||||
#include <algorithm> // for find
|
||||
|
||||
/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
|
||||
*/
|
||||
namespace OFX {
|
||||
|
||||
/** @brief fetch a pixel scale out of the property set */
|
||||
static OfxPointD getPixelScale(const PropertySet &props)
|
||||
{
|
||||
OfxPointD pixelScale;
|
||||
pixelScale.x = props.propGetDouble(kOfxInteractPropPixelScale, 0);
|
||||
pixelScale.y = props.propGetDouble(kOfxInteractPropPixelScale, 1);
|
||||
return pixelScale;
|
||||
}
|
||||
|
||||
/** @brief fetch a render scale out of the property set */
|
||||
static OfxPointD getRenderScale(const PropertySet &props)
|
||||
{
|
||||
OfxPointD v;
|
||||
v.x = props.propGetDouble(kOfxImageEffectPropRenderScale, 0);
|
||||
v.y = props.propGetDouble(kOfxImageEffectPropRenderScale, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** @brief fetch a background colour out of the property set */
|
||||
static OfxRGBColourD getBackgroundColour(const PropertySet &props)
|
||||
{
|
||||
OfxRGBColourD backGroundColour;
|
||||
backGroundColour.r = props.propGetDouble(kOfxInteractPropBackgroundColour, 0);
|
||||
backGroundColour.g = props.propGetDouble(kOfxInteractPropBackgroundColour, 1);
|
||||
backGroundColour.b = props.propGetDouble(kOfxInteractPropBackgroundColour, 2);
|
||||
return backGroundColour;
|
||||
}
|
||||
|
||||
/** @brief retrieves the image effect pointer from the interact handle */
|
||||
static ImageEffect *retrieveEffectFromInteractHandle(OfxInteractHandle handle)
|
||||
{
|
||||
// get the properties set on this handle
|
||||
OfxPropertySetHandle propHandle;
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
PropertySet interactProperties(propHandle);
|
||||
|
||||
// get the effect handle from this handle
|
||||
OfxImageEffectHandle effectHandle = (OfxImageEffectHandle) interactProperties.propGetPointer(kOfxPropEffectInstance);
|
||||
|
||||
// get the effect properties
|
||||
return OFX::Private::retrieveImageEffectPointer(effectHandle);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
Interact::Interact(OfxInteractHandle handle)
|
||||
: _interactHandle(handle)
|
||||
, _effect(0)
|
||||
{
|
||||
// get the properties set on this handle
|
||||
OfxPropertySetHandle propHandle;
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
_interactProperties.propSetHandle(propHandle);
|
||||
|
||||
// set othe instance data on the property handle to point to this interact
|
||||
_interactProperties.propSetPointer(kOfxPropInstanceData, (void *)this);
|
||||
|
||||
// get the effect handle from this handle
|
||||
_effect = retrieveEffectFromInteractHandle(handle);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
Interact::~Interact()
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief The bitdepth of each component in the openGL frame buffer */
|
||||
int
|
||||
Interact::getBitDepth(void) const
|
||||
{
|
||||
return _interactProperties.propGetInt(kOfxInteractPropBitDepth);
|
||||
}
|
||||
|
||||
/** @brief Does the openGL frame buffer have an alpha */
|
||||
bool
|
||||
Interact::hasAlpha(void) const
|
||||
{
|
||||
return _interactProperties.propGetInt(kOfxInteractPropHasAlpha) != 0;
|
||||
}
|
||||
|
||||
/** @brief Returns the size of a real screen pixel under the interact's cannonical projection */
|
||||
OfxPointD
|
||||
Interact::getPixelScale(void) const
|
||||
{
|
||||
OfxPointD v;
|
||||
v.x = _interactProperties.propGetDouble(kOfxInteractPropPixelScale, 0);
|
||||
v.y = _interactProperties.propGetDouble(kOfxInteractPropPixelScale, 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
/** @brief The suggested colour to draw a widget in an interact */
|
||||
bool
|
||||
Interact::getSuggestedColour(OfxRGBColourD &c) const
|
||||
{
|
||||
// OFX 1.2/1.3 specs say that the host should return kOfxStatReplyDefault if there is no suggested color
|
||||
OfxStatus stat = OFX::Private::gPropSuite->propGetDouble(_interactProperties.propSetHandle(), kOfxInteractPropSuggestedColour, 0, &c.r);
|
||||
if (stat != kOfxStatOK) {
|
||||
return false; // host gave no suggestion (replied kOfxStatReplyDefault or property is unknown to host)
|
||||
}
|
||||
stat = OFX::Private::gPropSuite->propGetDouble(_interactProperties.propSetHandle(), kOfxInteractPropSuggestedColour, 1, &c.g);
|
||||
if (stat != kOfxStatOK) {
|
||||
return false; // host gave no suggestion (replied kOfxStatReplyDefault or property is unknown to host)
|
||||
}
|
||||
stat = OFX::Private::gPropSuite->propGetDouble(_interactProperties.propSetHandle(), kOfxInteractPropSuggestedColour, 2, &c.b);
|
||||
if (stat != kOfxStatOK) {
|
||||
return false; // host gave no suggestion (replied kOfxStatReplyDefault or property is unknown to host)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @brief Request a redraw */
|
||||
void
|
||||
Interact::requestRedraw(void) const
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactRedraw(_interactHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
|
||||
/** @brief Swap a buffer in the case of a double bufferred interact, this is possibly a silly one */
|
||||
void
|
||||
Interact::swapBuffers(void) const
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactSwapBuffers(_interactHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
|
||||
/** @brief Set a param that the interact should be redrawn on if its value changes */
|
||||
void
|
||||
Interact::addParamToSlaveTo(Param *p)
|
||||
{
|
||||
// do we have it already ?
|
||||
std::list<Param *>::iterator i;
|
||||
i = std::find(_slaveParams.begin(), _slaveParams.end(), p);
|
||||
if(i == _slaveParams.end()) {
|
||||
// we have a new one to add in here
|
||||
_slaveParams.push_back(p);
|
||||
|
||||
// and set the property
|
||||
int n = _interactProperties.propGetDimension(kOfxInteractPropSlaveToParam);
|
||||
_interactProperties.propSetString(kOfxInteractPropSlaveToParam, p->getName(), n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @brief Remova a param that the interact should be redrawn on if its value changes */
|
||||
void
|
||||
Interact::removeParamToSlaveTo(Param *p)
|
||||
{
|
||||
// do we have it already ?
|
||||
std::list<Param *>::iterator i;
|
||||
i = std::find(_slaveParams.begin(), _slaveParams.end(), p);
|
||||
if(i != _slaveParams.end()) {
|
||||
// clobber it from the list
|
||||
_slaveParams.erase(i);
|
||||
|
||||
// reset the property to remove our dead one
|
||||
_interactProperties.propReset(kOfxInteractPropSlaveToParam);
|
||||
|
||||
// and add them all in again
|
||||
int n = 0;
|
||||
for(i = _slaveParams.begin(); i != _slaveParams.end(); ++i, ++n) {
|
||||
_interactProperties.propSetString(kOfxInteractPropSlaveToParam, (*i)->getName(), n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief the background colour */
|
||||
OfxRGBColourD Interact::getBackgroundColour(void) const
|
||||
{
|
||||
return OFX::getBackgroundColour(_interactProperties);
|
||||
}
|
||||
|
||||
/** @brief the function called to draw in the interact */
|
||||
bool
|
||||
Interact::draw(const DrawArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle pen motion in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::penMotion(const PenArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle pen down events in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::penDown(const PenArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle pen up events in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::penUp(const PenArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle key down events in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::keyDown(const KeyArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle key up events in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::keyUp(const KeyArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief the function called to handle key down repeat events in the interact
|
||||
|
||||
returns true if the interact trapped the action in some sense. This will block the action being passed to
|
||||
any other interact that may share the viewer.
|
||||
*/
|
||||
bool
|
||||
Interact::keyRepeat(const KeyArgs &/*args*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Called when the interact is given input focus */
|
||||
void
|
||||
Interact::gainFocus(const FocusArgs &/*args*/)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Called when the interact is loses input focus */
|
||||
void
|
||||
Interact::loseFocus(const FocusArgs &/*args*/)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// overlay interact guff
|
||||
|
||||
/** @brief ctor */
|
||||
OverlayInteract::OverlayInteract(OfxInteractHandle handle)
|
||||
: Interact(handle)
|
||||
{
|
||||
// add this interact into the list of overlays that the effect knows about
|
||||
if(_effect)
|
||||
_effect->addOverlayInteract(this);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
OverlayInteract::~OverlayInteract()
|
||||
{
|
||||
// add this interact into the list of overlays that the effect knows about
|
||||
if(_effect)
|
||||
_effect->removeOverlayInteract(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief ctor */
|
||||
InteractArgs::InteractArgs(const PropertySet &props)
|
||||
{
|
||||
time = props.propGetDouble(kOfxPropTime);
|
||||
renderScale = getRenderScale(props);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
DrawArgs::DrawArgs(const PropertySet &props)
|
||||
: InteractArgs(props)
|
||||
{
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
viewportSize.x = props.propGetDouble(kOfxInteractPropViewportSize, 0, false);
|
||||
viewportSize.y = props.propGetDouble(kOfxInteractPropViewportSize, 1, false);
|
||||
#endif
|
||||
backGroundColour = getBackgroundColour(props);
|
||||
pixelScale = getPixelScale(props);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
PenArgs::PenArgs(const PropertySet &props)
|
||||
: InteractArgs(props)
|
||||
{
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
viewportSize.x = props.propGetDouble(kOfxInteractPropViewportSize, 0, false);
|
||||
viewportSize.y = props.propGetDouble(kOfxInteractPropViewportSize, 1, false);
|
||||
#endif
|
||||
pixelScale = getPixelScale(props);
|
||||
backGroundColour = getBackgroundColour(props);
|
||||
penPosition.x = props.propGetDouble(kOfxInteractPropPenPosition, 0);
|
||||
penPosition.y = props.propGetDouble(kOfxInteractPropPenPosition, 1);
|
||||
try {
|
||||
penViewportPosition.x = props.propGetInt(kOfxInteractPropPenViewportPosition, 0);
|
||||
penViewportPosition.y = props.propGetInt(kOfxInteractPropPenViewportPosition, 1);
|
||||
} catch (OFX::Exception::PropertyUnknownToHost&) {
|
||||
// Introduced in OFX 1.2. Return (-1,-1) if not available
|
||||
penViewportPosition.x = penViewportPosition.y = -1.;
|
||||
}
|
||||
penPressure = props.propGetDouble(kOfxInteractPropPenPressure);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
KeyArgs::KeyArgs(const PropertySet &props)
|
||||
: InteractArgs(props)
|
||||
{
|
||||
time = props.propGetDouble(kOfxPropTime);
|
||||
renderScale = getRenderScale(props);
|
||||
keyString = props.propGetString(kOfxPropKeyString);
|
||||
keySymbol = props.propGetInt(kOfxPropKeySym);
|
||||
}
|
||||
|
||||
/** @brief ctor */
|
||||
FocusArgs::FocusArgs(const PropertySet &props)
|
||||
: InteractArgs(props)
|
||||
{
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
viewportSize.x = props.propGetDouble(kOfxInteractPropViewportSize, 0, false);
|
||||
viewportSize.y = props.propGetDouble(kOfxInteractPropViewportSize, 1, false);
|
||||
#endif
|
||||
pixelScale = getPixelScale(props);
|
||||
backGroundColour = getBackgroundColour(props);
|
||||
}
|
||||
|
||||
|
||||
void ParamInteractDescriptor::setInteractSizeAspect(double asp)
|
||||
{
|
||||
_props->propSetDouble(kOfxParamPropInteractSizeAspect , asp);
|
||||
}
|
||||
|
||||
void ParamInteractDescriptor::setInteractMinimumSize(int x, int y)
|
||||
{
|
||||
_props->propSetInt(kOfxParamPropInteractMinimumSize, x, 0);
|
||||
_props->propSetInt(kOfxParamPropInteractMinimumSize, y, 1);
|
||||
}
|
||||
|
||||
void ParamInteractDescriptor::setInteractPreferredSize(int x, int y)
|
||||
{
|
||||
_props->propSetInt(kOfxParamPropInteractPreferedSize, x, 0);
|
||||
_props->propSetInt(kOfxParamPropInteractPreferedSize, y, 1);
|
||||
}
|
||||
|
||||
ParamInteract::ParamInteract(OfxInteractHandle handle, ImageEffect* effect):Interact(handle), _effect(effect)
|
||||
{}
|
||||
|
||||
OfxPointI ParamInteract::getInteractSize() const
|
||||
{
|
||||
OfxPointI ret;
|
||||
ret.x = _interactProperties.propGetInt(kOfxParamPropInteractSize, 0);
|
||||
ret.y = _interactProperties.propGetInt(kOfxParamPropInteractSize, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace Private {
|
||||
/** @brief fetches our pointer out of the props on the handle */
|
||||
static
|
||||
Interact *retrieveInteractPointer(OfxInteractHandle handle)
|
||||
{
|
||||
Interact *instance;
|
||||
|
||||
// get the prop set on the handle
|
||||
OfxPropertySetHandle propHandle;
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
|
||||
// make our wrapper object
|
||||
PropertySet props(propHandle);
|
||||
|
||||
// fetch the instance data out of the properties
|
||||
instance = (Interact *) props.propGetPointer(kOfxPropInstanceData);
|
||||
|
||||
OFX::Log::error(instance == 0, "Instance data handle in effect instance properties is NULL!");
|
||||
|
||||
// need to throw something here
|
||||
|
||||
// and dance to the music
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** @brief The common entry point used by all interacts */
|
||||
static
|
||||
OfxStatus
|
||||
interactMainEntry(const std::string &action,
|
||||
OfxInteractHandle handle,
|
||||
PropertySet inArgs,
|
||||
PropertySet /*outArgs*/)
|
||||
{
|
||||
OfxStatus stat = kOfxStatReplyDefault;
|
||||
|
||||
// get the interact pointer
|
||||
Interact *interact = retrieveInteractPointer(handle);
|
||||
|
||||
// if one was not made, return and do nothing
|
||||
if(!interact)
|
||||
return stat;
|
||||
|
||||
if(action == kOfxActionDestroyInstance) {
|
||||
delete interact;
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionDraw) {
|
||||
// make the draw args
|
||||
DrawArgs drawArgs(inArgs);
|
||||
if(interact->draw(drawArgs))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionPenMotion) {
|
||||
|
||||
// make the draw args
|
||||
PenArgs args(inArgs);
|
||||
if(interact->penMotion(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionPenDown) {
|
||||
// make the draw args
|
||||
PenArgs args(inArgs);
|
||||
if(interact->penDown(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionPenUp) {
|
||||
// make the draw args
|
||||
PenArgs args(inArgs);
|
||||
if(interact->penUp(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionKeyDown) {
|
||||
// make the draw args
|
||||
KeyArgs args(inArgs);
|
||||
if(interact->keyDown(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionKeyUp) {
|
||||
// make the draw args
|
||||
KeyArgs args(inArgs);
|
||||
if(interact->keyUp(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionKeyRepeat) {
|
||||
// make the draw args
|
||||
KeyArgs args(inArgs);
|
||||
if(interact->keyRepeat(args))
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else if(action == kOfxInteractActionGainFocus) {
|
||||
// make the draw args
|
||||
FocusArgs args(inArgs);
|
||||
interact->gainFocus(args);
|
||||
}
|
||||
else if(action == kOfxInteractActionLoseFocus) {
|
||||
// make the draw args
|
||||
FocusArgs args(inArgs);
|
||||
interact->loseFocus(args);
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
/** @brief The main entry for image effect overlays */
|
||||
OfxStatus interactMainEntry(const char *actionRaw,
|
||||
const void *handleRaw,
|
||||
OfxPropertySetHandle inArgsRaw,
|
||||
OfxPropertySetHandle outArgsRaw,
|
||||
InteractDescriptor& desc)
|
||||
{
|
||||
OFX::Log::print("********************************************************************************");
|
||||
OFX::Log::print("START overlayInteractMainEntry (%s)", actionRaw);
|
||||
OFX::Log::indent();
|
||||
OfxStatus stat = kOfxStatReplyDefault;
|
||||
|
||||
try {
|
||||
// Cast the raw handle to be an image effect handle, because that is what it is
|
||||
OfxInteractHandle handle = (OfxInteractHandle) handleRaw;
|
||||
|
||||
// Turn the arguments into wrapper objects to make our lives easier
|
||||
OFX::PropertySet inArgs(inArgsRaw);
|
||||
OFX::PropertySet outArgs(outArgsRaw);
|
||||
|
||||
// turn the action into a std::string
|
||||
std::string action(actionRaw);
|
||||
|
||||
// figure the actions
|
||||
if (action == kOfxActionDescribe) {
|
||||
OfxPropertySetHandle propHandle;
|
||||
OfxStatus stat = OFX::Private::gInteractSuite->interactGetPropertySet(handle, &propHandle);
|
||||
throwSuiteStatusException(stat);
|
||||
PropertySet interactProperties(propHandle);
|
||||
desc.setPropertySet(&interactProperties);
|
||||
desc.describe();
|
||||
}
|
||||
else if (action == kOfxActionCreateInstance)
|
||||
{
|
||||
// fetch the image effect we are being made for out of the interact's property handle
|
||||
ImageEffect *effect = retrieveEffectFromInteractHandle(handle);
|
||||
OFX::Interact* interact = desc.createInstance(handle, effect);
|
||||
(void)interact;
|
||||
// and all was well
|
||||
stat = kOfxStatOK;
|
||||
}
|
||||
else {
|
||||
stat = interactMainEntry(action, handle, inArgs, outArgs);
|
||||
}
|
||||
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
stat = kOfxStatFailed;
|
||||
}
|
||||
|
||||
OFX::Log::outdent();
|
||||
OFX::Log::print("STOP overlayInteractMainEntry (%s)", actionRaw);
|
||||
return stat;
|
||||
}
|
||||
|
||||
}; // end namespace private
|
||||
|
||||
}; // end of namespace
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
|
||||
|
||||
/** @file This file contains the body of functions used for logging ofx problems etc...
|
||||
|
||||
The log file is written to using printf style functions, rather than via c++ iostreams.
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include "ofxsLog.h"
|
||||
|
||||
namespace OFX {
|
||||
namespace Log {
|
||||
|
||||
/** @brief log file */
|
||||
static FILE *gLogFP = 0;
|
||||
|
||||
/// environment variable for the log file
|
||||
#define kLogFileEnvVar "OFX_PLUGIN_LOGFILE"
|
||||
|
||||
/** @brief the global logfile name */
|
||||
static std::string gLogFileName(getenv(kLogFileEnvVar) ? getenv(kLogFileEnvVar) : "ofxPluginLog.txt");
|
||||
|
||||
/** @brief global indent level, not MP sane */
|
||||
static int gIndent = 0;
|
||||
|
||||
/** @brief Sets the name of the log file. */
|
||||
void setFileName(const std::string &value)
|
||||
{
|
||||
gLogFileName = value;
|
||||
}
|
||||
|
||||
/** @brief Opens the log file, returns whether this was sucessful or not. */
|
||||
bool open(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(!gLogFP) {
|
||||
gLogFP = fopen(gLogFileName.c_str(), "a");
|
||||
return gLogFP != 0;
|
||||
}
|
||||
#endif
|
||||
return gLogFP != 0;
|
||||
}
|
||||
|
||||
/** @brief Closes the log file. */
|
||||
void close(void)
|
||||
{
|
||||
if(gLogFP) {
|
||||
fclose(gLogFP);
|
||||
}
|
||||
gLogFP = 0;
|
||||
}
|
||||
|
||||
/** @brief Indent it, not MP sane at the moment */
|
||||
void indent(void)
|
||||
{
|
||||
++gIndent;
|
||||
}
|
||||
|
||||
/** @brief Outdent it, not MP sane at the moment */
|
||||
void outdent(void)
|
||||
{
|
||||
--gIndent;
|
||||
}
|
||||
|
||||
/** @brief do the indenting */
|
||||
static void doIndent(void)
|
||||
{
|
||||
if(open()) {
|
||||
for(int i = 0; i < gIndent; i++) {
|
||||
fputs(" ", gLogFP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Prints to the log file. */
|
||||
void print(const char *format, ...)
|
||||
{
|
||||
if(open()) {
|
||||
doIndent();
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(gLogFP, format, args);
|
||||
fputc('\n', gLogFP);
|
||||
fflush(gLogFP);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Prints to the log file only if the condition is true and prepends a warning notice. */
|
||||
void warning(bool condition, const char *format, ...)
|
||||
{
|
||||
if(condition && open()) {
|
||||
doIndent();
|
||||
fputs("WARNING : ", gLogFP);
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(gLogFP, format, args);
|
||||
fputc('\n', gLogFP);
|
||||
va_end(args);
|
||||
|
||||
fflush(gLogFP);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Prints to the log file only if the condition is true and prepends an error notice. */
|
||||
void error(bool condition, const char *format, ...)
|
||||
{
|
||||
if(condition && open()) {
|
||||
doIndent();
|
||||
fputs("ERROR : ", gLogFP);
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(gLogFP, format, args);
|
||||
fputc('\n', gLogFP);
|
||||
va_end(args);
|
||||
|
||||
fflush(gLogFP);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
|
||||
|
||||
#include "ofxsSupportPrivate.h"
|
||||
|
||||
namespace OFX {
|
||||
|
||||
namespace MultiThread {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SMP class
|
||||
|
||||
/** @brief ctor */
|
||||
Processor::Processor(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief dtor */
|
||||
Processor::~Processor()
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Function to pass to the multi thread suite */
|
||||
void Processor::staticMultiThreadFunction(unsigned int threadIndex, unsigned int threadMax, void *customArg)
|
||||
{
|
||||
// cast the custom arg to one of me
|
||||
Processor *me = (Processor *) customArg;
|
||||
|
||||
// and call my thread function
|
||||
me->multiThreadFunction(threadIndex, threadMax);
|
||||
}
|
||||
|
||||
/** @brief Function to pass to the multi thread suite */
|
||||
void Processor::multiThread(unsigned int nCPUs)
|
||||
{
|
||||
// if 0, use all the CPUs we can
|
||||
if(nCPUs == 0)
|
||||
nCPUs = OFX::MultiThread::getNumCPUs();
|
||||
|
||||
// if 1 cpu, don't bother with the threading
|
||||
if(nCPUs == 1) {
|
||||
multiThreadFunction(0, 1);
|
||||
}
|
||||
else {
|
||||
// OK do it
|
||||
OfxStatus stat = kOfxStatFailed;
|
||||
if(OFX::Private::gThreadSuite){
|
||||
stat = OFX::Private::gThreadSuite->multiThread(staticMultiThreadFunction, nCPUs, (void *)this);
|
||||
}
|
||||
|
||||
// did we do it?
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// futility functions
|
||||
|
||||
/** @brief Has the current thread been spawned from an MP */
|
||||
bool isSpawnedThread(void)
|
||||
{
|
||||
if(OFX::Private::gThreadSuite){
|
||||
int v = OFX::Private::gThreadSuite->multiThreadIsSpawnedThread();
|
||||
return v != 0;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief The number of CPUs that can be used for MP-ing */
|
||||
unsigned int getNumCPUs(void)
|
||||
{
|
||||
unsigned int n = 1;
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->multiThreadNumCPUs(&n) : kOfxStatFailed;
|
||||
|
||||
if(stat != kOfxStatOK) n = 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
/** @brief The index of the current thread. From 0 to numCPUs() - 1 */
|
||||
unsigned int getThreadIndex(void)
|
||||
{
|
||||
unsigned int n = 0;
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->multiThreadIndex(&n) : kOfxStatFailed;
|
||||
if(stat != kOfxStatOK) n = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// MUTEX class
|
||||
|
||||
/** @brief ctor */
|
||||
Mutex::Mutex(int lockCount)
|
||||
: _handle(0)
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->mutexCreate(&_handle, lockCount) : kOfxStatReplyDefault;
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
|
||||
/** @brief dtor */
|
||||
Mutex::~Mutex(void)
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->mutexDestroy(_handle) : kOfxStatReplyDefault;
|
||||
(void)stat;
|
||||
}
|
||||
|
||||
/** @brief lock it, blocks until lock is gained */
|
||||
void Mutex::lock()
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->mutexLock(_handle) : kOfxStatReplyDefault;
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
|
||||
/** @brief unlock it */
|
||||
void Mutex::unlock()
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->mutexUnLock(_handle) : kOfxStatReplyDefault;
|
||||
throwSuiteStatusException(stat);
|
||||
}
|
||||
|
||||
/** @brief attempt to lock, non-blocking */
|
||||
bool Mutex::tryLock()
|
||||
{
|
||||
OfxStatus stat = OFX::Private::gThreadSuite ? OFX::Private::gThreadSuite->mutexTryLock(_handle) : kOfxStatReplyDefault;
|
||||
return stat == kOfxStatOK;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
+3226
File diff suppressed because it is too large
Load Diff
+230
@@ -0,0 +1,230 @@
|
||||
|
||||
|
||||
#include "ofxsSupportPrivate.h"
|
||||
|
||||
using namespace OFX::Private;
|
||||
|
||||
namespace OFX {
|
||||
|
||||
static
|
||||
void throwPropertyException(OfxStatus stat,
|
||||
const std::string &propName)
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case kOfxStatOK :
|
||||
case kOfxStatReplyYes :
|
||||
case kOfxStatReplyNo :
|
||||
case kOfxStatReplyDefault :
|
||||
// Throw nothing!
|
||||
break;
|
||||
|
||||
case kOfxStatErrUnknown :
|
||||
case kOfxStatErrUnsupported : // unsupported implies unknow here
|
||||
if(OFX::PropertySet::getThrowOnUnsupportedProperties()) // are we suppressing this?
|
||||
throw OFX::Exception::PropertyUnknownToHost(propName.c_str());
|
||||
break;
|
||||
|
||||
case kOfxStatErrMemory :
|
||||
throw std::bad_alloc();
|
||||
break;
|
||||
|
||||
case kOfxStatErrValue :
|
||||
throw OFX::Exception::PropertyValueIllegalToHost(propName.c_str());
|
||||
break;
|
||||
|
||||
case kOfxStatErrBadHandle :
|
||||
case kOfxStatErrBadIndex :
|
||||
default :
|
||||
throwSuiteStatusException(stat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief are we logging property get/set */
|
||||
int PropertySet::_gPropLogging = 1;
|
||||
|
||||
/** @brief Do we throw an exception if a host returns 'unsupported' when setting a property */
|
||||
bool PropertySet::_gThrowOnUnsupported = true;
|
||||
|
||||
/** @brief Virtual destructor */
|
||||
PropertySet::~PropertySet() {}
|
||||
|
||||
/** @brief, returns the dimension of the given property from this property set */
|
||||
int PropertySet::propGetDimension(const char* property, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
int dimension = 0;
|
||||
OfxStatus stat = gPropSuite->propGetDimension(_propHandle, property, &dimension);
|
||||
Log::error(stat != kOfxStatOK, "Failed on fetching dimension for property %s, host returned status %s.", property, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0)
|
||||
Log::print("Fetched dimension of property %s, returned %d.", property, dimension);
|
||||
|
||||
return dimension;
|
||||
}
|
||||
|
||||
/** @brief, resets the property to it's default value */
|
||||
void PropertySet::propReset(const char* property)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propReset(_propHandle, property);
|
||||
Log::error(stat != kOfxStatOK, "Failed on reseting property %s to its defaults, host returned status %s.", property, mapStatusToString(stat));
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Reset property %s.", property);
|
||||
}
|
||||
|
||||
/** @brief, Set a single dimension pointer property */
|
||||
void PropertySet::propSetPointer(const char* property, void *value, int idx, bool throwOnFailure)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propSetPointer(_propHandle, property, idx, value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on setting pointer property %s[%d] to %p, host returned status %s;",
|
||||
property, idx, value, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Set pointer property %s[%d] to be %p.", property, idx, value);
|
||||
}
|
||||
|
||||
/** @brief, Set a single dimension string property */
|
||||
void PropertySet::propSetString(const char* property, const std::string &value, int idx, bool throwOnFailure)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propSetString(_propHandle, property, idx, value.c_str());
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on setting string property %s[%d] to %s, host returned status %s;",
|
||||
property, idx, value.c_str(), mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Set string property %s[%d] to be %s.", property, idx, value.c_str());
|
||||
}
|
||||
|
||||
/** @brief, Set a single dimension double property */
|
||||
void PropertySet::propSetDouble(const char* property, double value, int idx, bool throwOnFailure)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propSetDouble(_propHandle, property, idx, value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on setting double property %s[%d] to %lf, host returned status %s;",
|
||||
property, idx, value, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Set double property %s[%d] to be %lf.", property, idx, value);
|
||||
}
|
||||
|
||||
/** @brief, Set a single dimension int property */
|
||||
void PropertySet::propSetInt(const char* property, int value, int idx, bool throwOnFailure)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propSetInt(_propHandle, property, idx, value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on setting int property %s[%d] to %d, host returned status %s (%d);",
|
||||
property, idx, value, mapStatusToString(stat), stat);
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Set int property %s[%d] to be %d.", property, idx, value);
|
||||
}
|
||||
|
||||
/** @brief, Set a multiple dimension double property */
|
||||
void PropertySet::propSetDoubleN(const char* property, const double* values, int count, bool throwOnFailure)
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
OfxStatus stat = gPropSuite->propSetDoubleN(_propHandle, property, count, values);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on setting double property %s[0..%d], host returned status %s;",
|
||||
property, count-1, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Set double property %s[0..%d].", property, count-1);
|
||||
}
|
||||
|
||||
/** @brief Get single pointer property */
|
||||
void* PropertySet::propGetPointer(const char* property, int idx, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
void *value = 0;
|
||||
OfxStatus stat = gPropSuite->propGetPointer(_propHandle, property, idx, &value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on getting pointer property %s[%d], host returned status %s;",
|
||||
property, idx, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Retrieved pointer property %s[%d], was given %p.", property, idx, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @brief Get single string property */
|
||||
std::string PropertySet::propGetString(const char* property, int idx, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
char *value = NULL;
|
||||
OfxStatus stat = gPropSuite->propGetString(_propHandle, property, idx, &value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on getting string property %s[%d], host returned status %s;",
|
||||
property, idx, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Retrieved string property %s[%d], was given %s.", property, idx, value);
|
||||
return value != NULL ? std::string(value) : std::string();
|
||||
}
|
||||
|
||||
/** @brief Get single double property */
|
||||
double PropertySet::propGetDouble(const char* property, int idx, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
double value = 0;
|
||||
OfxStatus stat = gPropSuite->propGetDouble(_propHandle, property, idx, &value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on getting double property %s[%d], host returned status %s;",
|
||||
property, idx, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Retrieved double property %s[%d], was given %lf.", property, idx, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/** @brief Get single int property */
|
||||
int PropertySet::propGetInt(const char* property, int idx, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
int value = 0;
|
||||
OfxStatus stat = gPropSuite->propGetInt(_propHandle, property, idx, &value);
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on getting int property %s[%d], host returned status %s;",
|
||||
property, idx, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Retrieved int property %s[%d], was given %d.", property, idx, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::list<std::string> PropertySet::propGetNString(const char* property, bool throwOnFailure) const
|
||||
{
|
||||
assert(_propHandle != 0);
|
||||
std::list<std::string> ret;
|
||||
int dimension = propGetDimension(property,throwOnFailure);
|
||||
if (dimension <= 0) {
|
||||
return ret;
|
||||
}
|
||||
std::vector<char*> rawValue(dimension);
|
||||
OfxStatus stat = gPropSuite->propGetStringN(_propHandle, property, dimension, rawValue.data());
|
||||
OFX::Log::error(stat != kOfxStatOK, "Failed on getting string property %s, host returned status %s;",
|
||||
property, mapStatusToString(stat));
|
||||
if(throwOnFailure)
|
||||
throwPropertyException(stat, property);
|
||||
|
||||
if(_gPropLogging > 0) Log::print("Retrieved string property %s, was given %s.", property,rawValue.data());
|
||||
|
||||
for (int i = 0; i < dimension; ++i) {
|
||||
ret.push_back(std::string(rawValue[i]));
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,228 @@
|
||||
|
||||
|
||||
#ifndef _ofxsSupportPrivate_H_
|
||||
#define _ofxsSupportPrivate_H_
|
||||
|
||||
#include "ofxsInteract.h"
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsLog.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
/** @brief Namespace private to the ofx support library.
|
||||
*/
|
||||
namespace OFX {
|
||||
|
||||
namespace Private {
|
||||
/** @brief Pointer to the host */
|
||||
extern OfxHost *gHost;
|
||||
|
||||
/** @brief Pointer to the effect suite */
|
||||
extern OfxImageEffectSuiteV1 *gEffectSuite;
|
||||
|
||||
/** @brief Pointer to the property suite */
|
||||
extern OfxPropertySuiteV1 *gPropSuite;
|
||||
|
||||
/** @brief Pointer to the interact suite */
|
||||
extern OfxInteractSuiteV1 *gInteractSuite;
|
||||
|
||||
/** @brief Pointer to the parameter suite */
|
||||
extern OfxParameterSuiteV1 *gParamSuite;
|
||||
|
||||
/** @brief Pointer to the general memory suite */
|
||||
extern OfxMemorySuiteV1 *gMemorySuite;
|
||||
|
||||
/** @brief Pointer to the threading suite */
|
||||
extern OfxMultiThreadSuiteV1 *gThreadSuite;
|
||||
|
||||
/** @brief Pointer to the message suite */
|
||||
extern OfxMessageSuiteV1 *gMessageSuite;
|
||||
|
||||
/** @brief Pointer to the optional message suite V2 */
|
||||
extern OfxMessageSuiteV2 *gMessageSuiteV2;
|
||||
|
||||
/** @brief Pointer to the optional progress suite */
|
||||
extern OfxProgressSuiteV1 *gProgressSuiteV1;
|
||||
|
||||
/** @brief Pointer to the optional progress suite */
|
||||
extern OfxProgressSuiteV2 *gProgressSuiteV2;
|
||||
|
||||
/** @brief Pointer to the optional timeline suite */
|
||||
extern OfxTimeLineSuiteV1 *gTimeLineSuite;
|
||||
|
||||
/** @brief Pointer to the parametric parameter suite */
|
||||
extern OfxParametricParameterSuiteV1* gParametricParameterSuite;
|
||||
|
||||
/** @brief Support lib function called on an ofx load action */
|
||||
void loadAction(void);
|
||||
|
||||
/** @brief Support lib function called on an ofx unload action */
|
||||
void unloadAction(void);
|
||||
|
||||
/** @brief The plugin function that gets passed the host structure.
|
||||
*/
|
||||
void setHost(OfxHost *host);
|
||||
|
||||
/** @brief fetches our pointer out of the props on the handle */
|
||||
ImageEffect *retrieveImageEffectPointer(OfxImageEffectHandle handle);
|
||||
|
||||
/** @brief fetch the prop set from the effect handle */
|
||||
OFX::PropertySet
|
||||
fetchEffectProps(OfxImageEffectHandle handle);
|
||||
|
||||
/** @brief the set of descriptors, one per context used by kOfxActionDescribeInContext, 'eContextNone' is the one used by the kOfxActionDescribe */
|
||||
typedef std::map<ContextEnum, ImageEffectDescriptor*> EffectContextMap;
|
||||
typedef std::map<std::string, EffectContextMap> EffectDescriptorMap;
|
||||
extern EffectDescriptorMap gEffectDescriptors;
|
||||
};
|
||||
|
||||
/** @brief The validation code has its own namespace */
|
||||
namespace Validation {
|
||||
|
||||
/** @brief This is uses to hold a property value, used by the property checking classes.
|
||||
|
||||
Could have been a union, but std::string can't be in one.
|
||||
*/
|
||||
struct ValueHolder {
|
||||
std::string vString;
|
||||
int vInt;
|
||||
double vDouble;
|
||||
void *vPointer;
|
||||
|
||||
ValueHolder(void) : vString(), vInt(0), vDouble(0.), vPointer(0) {}
|
||||
ValueHolder(char *s) : vString(s), vInt(0), vDouble(0.), vPointer(0) {}
|
||||
ValueHolder(const std::string &s) : vString(s), vInt(0), vDouble(0.), vPointer(0) {}
|
||||
ValueHolder(int i) : vString(), vInt(i), vDouble(0.), vPointer(0) {}
|
||||
ValueHolder(double d) : vString(), vInt(0), vDouble(d), vPointer(0) {}
|
||||
ValueHolder(void *p) : vString(), vInt(0), vDouble(0.), vPointer(p) {}
|
||||
|
||||
ValueHolder &operator = (char *v) {vString = v; return *this;}
|
||||
ValueHolder &operator = (std::string v) {vString = v; return *this;}
|
||||
ValueHolder &operator = (void *v) {vPointer = v; return *this;}
|
||||
ValueHolder &operator = (int v) {vInt = v; return *this;}
|
||||
ValueHolder &operator = (double v) {vDouble = v; return *this;}
|
||||
|
||||
operator const char * () {return vString.c_str();}
|
||||
operator std::string &() {return vString;}
|
||||
operator int &() {return vInt;}
|
||||
operator double &() {return vDouble;}
|
||||
operator void * &() {return vPointer;}
|
||||
};
|
||||
|
||||
/** @brief Enum used in the varargs list of the PropertyDescription constructor */
|
||||
enum DescriptionTag {
|
||||
eDescDefault, /** @brief following values are the default to check against */
|
||||
eDescFinished /** @brief we have finished the description */
|
||||
};
|
||||
|
||||
/** @brief class to describe properties, check their default and set their values */
|
||||
class PropertyDescription
|
||||
{
|
||||
public :
|
||||
/** @brief name of the property */
|
||||
const std::string _name;
|
||||
|
||||
/** @brief Was it validated */
|
||||
bool _exists;
|
||||
|
||||
/** @brief dimension of the property */
|
||||
int _dimension;
|
||||
|
||||
/** @brief What type of property is it */
|
||||
OFX::PropertyTypeEnum _ilk;
|
||||
|
||||
/** @brief The default value that this property should have. Empty implies no default (eg: a host name has no default). */
|
||||
std::vector<ValueHolder> _defaultValue;
|
||||
|
||||
public :
|
||||
/** @brief var args constructor that is use to describe properties */
|
||||
PropertyDescription(const char *name, OFX::PropertyTypeEnum ilk, int dimension, ...);
|
||||
|
||||
/** @brief Die! Die! Die! */
|
||||
virtual ~PropertyDescription(void) {}
|
||||
|
||||
/** @brief See if the property exists in the containing property set and has the correct dimension */
|
||||
void validate(bool checkDefaults, PropertySet &propSet);
|
||||
};
|
||||
|
||||
/** @brief Describes a set of properties */
|
||||
class PropertySetDescription {
|
||||
protected :
|
||||
/** @brief name of the property set */
|
||||
const std::string _setName;
|
||||
|
||||
/** @brief the descriptions of each property */
|
||||
std::vector<PropertyDescription *> _descriptions;
|
||||
|
||||
/** @brief The descriptions of each property */
|
||||
std::vector<PropertyDescription *> _deleteThese;
|
||||
|
||||
public :
|
||||
/** @brief constructor.
|
||||
|
||||
The varargs zero terminated are made from pairs of PropertyDescription * and ints indicating the number of properties pointed to.
|
||||
These are to come from static arrays and need not be deleted
|
||||
*/
|
||||
PropertySetDescription(const char *setName, ...);// [PropertyDescription *v, int nSetToThese]
|
||||
|
||||
/** @brief destructor */
|
||||
virtual ~PropertySetDescription();
|
||||
|
||||
/** @brief add another property in */
|
||||
void addProperty(PropertyDescription *desc, bool deleteOnDestruction = true);
|
||||
|
||||
/** @brief See if all properties exist and have the correct dimensions */
|
||||
void validate(PropertySet &propSet, bool checkDefaults = true, bool logOrdinaryMessages = false);
|
||||
};
|
||||
|
||||
|
||||
/** @brief Validates the host structure and property handle */
|
||||
void
|
||||
validateHostProperties(OfxHost *host);
|
||||
|
||||
/** @brief Validates the effect descriptor properties */
|
||||
void
|
||||
validatePluginDescriptorProperties(PropertySet props);
|
||||
|
||||
/** @brief Validates the effect instance properties */
|
||||
void
|
||||
validatePluginInstanceProperties(PropertySet props);
|
||||
|
||||
/** @brief validates a clip descriptor */
|
||||
void
|
||||
validateClipDescriptorProperties(PropertySet props);
|
||||
|
||||
/** @brief validates a clip instance */
|
||||
void
|
||||
validateClipInstanceProperties(PropertySet props);
|
||||
|
||||
/** @brief validates an image or texture instance */
|
||||
void
|
||||
validateImageBaseProperties(PropertySet props);
|
||||
|
||||
/** @brief validates an image instance */
|
||||
void
|
||||
validateImageProperties(PropertySet props);
|
||||
|
||||
#ifdef OFX_SUPPORTS_OPENGLRENDER
|
||||
/** @brief validates an OpenGL texture descriptor */
|
||||
void
|
||||
validateTextureProperties(PropertySet props);
|
||||
#endif
|
||||
|
||||
/** @brief Validates action in/out arguments */
|
||||
void
|
||||
validateActionArgumentsProperties(const std::string &action, PropertySet inArgs, PropertySet outArgs);
|
||||
|
||||
/** @brief Validates parameter properties */
|
||||
void
|
||||
validateParameterProperties(ParamTypeEnum paramType,
|
||||
OFX::PropertySet paramProps,
|
||||
bool checkDefaults);
|
||||
|
||||
/** @brief initialises the validation code, call this in on load */
|
||||
void initialise(void);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ofxsupport"=.\ofxsupport.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+695
@@ -0,0 +1,695 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="ofxsupport"
|
||||
ProjectGUID="{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}"
|
||||
RootNamespace="ofxsupport"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include,../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/ofxsupport.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\ofxSupport.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/ofxsupport.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../include,../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/ofxsupport.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\ofxSupport.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/ofxsupport.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../include,../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_LIB"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/ofxsupport.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\ofxSupport.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/ofxsupport.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../include,../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/ofxsupport.pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)\ofxSupport.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/ofxsupport.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="ofxsCore.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsImageEffect.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsInteract.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsLog.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsMultiThread.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsParams.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsProperty.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsPropertyValidation.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\include\ofxscore.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsImageEffect.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsInteract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsLog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsMemory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsMessage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsMultiThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\ofxsParam.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ofxsSupportPrivate.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,74 @@
|
||||
|
||||
|
||||
#include "ofxCore.h"
|
||||
#include "CoreFoundation/CoreFoundation.h"
|
||||
|
||||
|
||||
|
||||
typedef OfxPlugin *(OfxGetPluginFunc)(int nth);
|
||||
typedef int (OfxGetNumberOfPluginsFunc)(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
CFURLRef bundleURL;
|
||||
CFBundleRef myBundle;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <plugin>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
CFStringRef bundlePath = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
argv[1],
|
||||
kCFStringEncodingASCII);
|
||||
|
||||
// Make a CFURLRef from the CFString representation of the
|
||||
// bundle's path.
|
||||
bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
|
||||
bundlePath,
|
||||
kCFURLPOSIXPathStyle,
|
||||
true );
|
||||
|
||||
// Make a bundle instance using the URLRef.
|
||||
myBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
|
||||
|
||||
if(myBundle) {
|
||||
// Value returned from the loaded function.
|
||||
//long result;
|
||||
|
||||
OfxGetNumberOfPluginsFunc *nPluginsFunc = (OfxGetNumberOfPluginsFunc *)CFBundleGetFunctionPointerForName(myBundle, CFSTR("OfxGetNumberOfPlugins") );
|
||||
OfxGetPluginFunc *getPlugin = (OfxGetPluginFunc *)CFBundleGetFunctionPointerForName(myBundle, CFSTR("OfxGetPlugin") );
|
||||
|
||||
// If the function was found, call it with a test value.
|
||||
if (nPluginsFunc && getPlugin) {
|
||||
// This should add 1 to whatever was passed in
|
||||
int nP = nPluginsFunc();
|
||||
|
||||
|
||||
printf("Sucessfully loaded '%s', containing %d %s\n", argv[1], nP, (nP == 1 ? "plugin" : "plugins"));
|
||||
|
||||
for(int i = 0; i < nP; i++) {
|
||||
// get a plugin
|
||||
OfxPlugin *plugin = getPlugin(i);
|
||||
if(plugin) {
|
||||
printf("\tFound plugin...\n\t\tAPI = %s (%d)\n\t\tid = %s (%d.%d)\n",
|
||||
plugin->pluginApi, plugin->apiVersion,
|
||||
plugin->pluginIdentifier, plugin->pluginVersionMajor, plugin->pluginVersionMinor);
|
||||
|
||||
plugin->mainEntry(kOfxActionLoad, NULL, NULL, NULL);
|
||||
plugin->mainEntry(kOfxActionUnload, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "fetching %dth plugin returned NULL\n", i);
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Failed to find symbols OfxGetPlugin or OfxGetNumberOfPlugins\n");
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Failed to load bundle %s\n", argv[1]);
|
||||
|
||||
// Any CF objects returned from functions with "create" or
|
||||
// "copy" in their names must be released by us!
|
||||
CFRelease( bundleURL );
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>basic.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+727
@@ -0,0 +1,727 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// a dumb interact that just draw's a square you can drag
|
||||
static const OfxPointD kBoxSize = {20, 20};
|
||||
|
||||
class BasicInteract : public OFX::OverlayInteract {
|
||||
protected :
|
||||
enum StateEnum {
|
||||
eInActive,
|
||||
ePoised,
|
||||
ePicked
|
||||
};
|
||||
|
||||
OfxPointD _position;
|
||||
StateEnum _state;
|
||||
|
||||
public :
|
||||
BasicInteract(OfxInteractHandle handle, OFX::ImageEffect* /*effect*/)
|
||||
: OFX::OverlayInteract(handle)
|
||||
, _state(eInActive)
|
||||
{
|
||||
_position.x = 0;
|
||||
_position.y = 0;
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
virtual bool draw(const OFX::DrawArgs &args);
|
||||
virtual bool penMotion(const OFX::PenArgs &args);
|
||||
virtual bool penDown(const OFX::PenArgs &args);
|
||||
virtual bool penUp(const OFX::PenArgs &args);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// rendering routines
|
||||
template <class T> inline T
|
||||
Minimum(T a, T b) { return (a < b) ? a : b;}
|
||||
|
||||
template <class T> inline T
|
||||
Absolute(T a) { return (a < 0) ? -a : a;}
|
||||
|
||||
template <class T> inline T
|
||||
Clamp(T v, int min, int max)
|
||||
{
|
||||
if(v < T(min)) return T(min);
|
||||
if(v > T(max)) return T(max);
|
||||
return v;
|
||||
}
|
||||
|
||||
// Base class for the RGBA and the Alpha processor
|
||||
class ImageScalerBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
OFX::Image *_maskImg;
|
||||
double _rScale, _gScale, _bScale, _aScale;
|
||||
bool _doMasking;
|
||||
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
ImageScalerBase(OFX::ImageEffect &instance)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _srcImg(0)
|
||||
, _maskImg(0)
|
||||
, _rScale(1)
|
||||
, _gScale(1)
|
||||
, _bScale(1)
|
||||
, _aScale(1)
|
||||
, _doMasking(false)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the src image */
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
|
||||
/** @brief set the optional mask image */
|
||||
void setMaskImg(OFX::Image *v) {_maskImg = v;}
|
||||
|
||||
// Are we masking. We can't derive this from the mask image being set as NULL is a valid value for an input image
|
||||
void doMasking(bool v) {_doMasking = v;}
|
||||
|
||||
|
||||
/** @brief set the scale */
|
||||
void setScales(float r, float g, float b, float a)
|
||||
{
|
||||
_rScale = r;
|
||||
_gScale = g;
|
||||
_bScale = b;
|
||||
_aScale = a;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// template to do the RGBA processing
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageScaler : public ImageScalerBase {
|
||||
public :
|
||||
// ctor
|
||||
ImageScaler(OFX::ImageEffect &instance)
|
||||
: ImageScalerBase(instance)
|
||||
{}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float scales[4];
|
||||
scales[0] = nComponents == 1 ? (float)_aScale : (float)_rScale;
|
||||
scales[1] = (float)_gScale;
|
||||
scales[2] = (float)_bScale;
|
||||
scales[3] = (float)_aScale;
|
||||
|
||||
float maskScale = 1.0f;
|
||||
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
// are we doing masking
|
||||
if(_doMasking) {
|
||||
// we do, get the pixel from the mask
|
||||
if(!_maskImg)
|
||||
maskScale = 1.0f;
|
||||
else
|
||||
{
|
||||
PIX *maskPix = (PIX *) (_maskImg ? _maskImg->getPixelAddress(x, y) : 0);
|
||||
// figure the scale factor from that pixel
|
||||
maskScale = maskPix != 0 ? float(*maskPix)/float(max) : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// do we have a source image to scale up
|
||||
if(srcPix) {
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
float v;
|
||||
|
||||
// scale the component up by the scale factor, modulated by the maskScale
|
||||
if(maskScale != 1.0f)
|
||||
v = srcPix[c] * (1.0f + (scales[c] - 1.0f) * maskScale);
|
||||
else
|
||||
v = srcPix[c] * scales[c];
|
||||
|
||||
if(max == 1) // implies floating point and so no clamping
|
||||
dstPix[c] = PIX(v);
|
||||
else // integer based and we need to clamp
|
||||
dstPix[c] = PIX(Clamp(v, 0, max));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no src pixel here, be black and transparent
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
}
|
||||
// increment the dst pixel
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class BasicPlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
OFX::Clip *maskClip_;
|
||||
|
||||
OFX::DoubleParam *scale_;
|
||||
OFX::DoubleParam *rScale_;
|
||||
OFX::DoubleParam *gScale_;
|
||||
OFX::DoubleParam *bScale_;
|
||||
OFX::DoubleParam *aScale_;
|
||||
OFX::BooleanParam *componentScalesEnabled_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
BasicPlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, srcClip_(0)
|
||||
, scale_(0)
|
||||
, rScale_(0)
|
||||
, gScale_(0)
|
||||
, bScale_(0)
|
||||
, aScale_(0)
|
||||
, componentScalesEnabled_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
// name of mask clip depends on the context
|
||||
maskClip_ = getContext() == OFX::eContextFilter ? NULL : fetchClip(getContext() == OFX::eContextPaint ? "Brush" : "Mask");
|
||||
scale_ = fetchDoubleParam("scale");
|
||||
rScale_ = fetchDoubleParam("scaleR");
|
||||
gScale_ = fetchDoubleParam("scaleG");
|
||||
bScale_ = fetchDoubleParam("scaleB");
|
||||
aScale_ = fetchDoubleParam("scaleA");
|
||||
componentScalesEnabled_ = fetchBooleanParam("scaleComponents");
|
||||
|
||||
// set the enabledness of our RGBA sliders
|
||||
setEnabledness();
|
||||
}
|
||||
|
||||
/* sets the enabledness of the component scale params depending on the type of input image and the state of the scaleComponents param */
|
||||
void setEnabledness(void);
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* override is identity */
|
||||
virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime);
|
||||
|
||||
/* override changedParam */
|
||||
virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName);
|
||||
|
||||
/* override changed clip */
|
||||
virtual void changedClip(const OFX::InstanceChangedArgs &args, const std::string &clipName);
|
||||
|
||||
// override the rod call
|
||||
virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod);
|
||||
|
||||
// override the roi call
|
||||
virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois);
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
setupAndProcess(ImageScalerBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
BasicPlugin::setupAndProcess(ImageScalerBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// fetch main input image
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(src.get()) {
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
std::unique_ptr<OFX::Image> mask;
|
||||
|
||||
// do we do masking
|
||||
if(getContext() != OFX::eContextFilter) {
|
||||
mask.reset(maskClip_->fetchImage(args.time));
|
||||
// say we are masking
|
||||
processor.doMasking(true);
|
||||
|
||||
// Set it in the processor
|
||||
processor.setMaskImg(mask.get());
|
||||
}
|
||||
|
||||
// get the scale parameter values...
|
||||
double r, g, b, a = aScale_->getValueAtTime(args.time);
|
||||
r = g = b = scale_->getValueAtTime(args.time);
|
||||
|
||||
// see if the individual component scales are enabled
|
||||
if(componentScalesEnabled_->getValueAtTime(args.time)) {
|
||||
r *= rScale_->getValueAtTime(args.time);
|
||||
g *= gScale_->getValueAtTime(args.time);
|
||||
b *= bScale_->getValueAtTime(args.time);
|
||||
}
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// set the scales
|
||||
processor.setScales((float)r, (float)g, (float)b, (float)a);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
// override the rod call
|
||||
bool
|
||||
BasicPlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod)
|
||||
{
|
||||
// our RoD is the same as the 'Source' clip's, we are not interested in the mask
|
||||
rod = srcClip_->getRegionOfDefinition(args.time);
|
||||
|
||||
// say we set it
|
||||
return true;
|
||||
}
|
||||
|
||||
// override the roi call
|
||||
void
|
||||
BasicPlugin::getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois)
|
||||
{
|
||||
// we don't actually need to do this as this is the default, but do it for examples sake
|
||||
rois.setRegionOfInterest(*srcClip_, args.regionOfInterest);
|
||||
|
||||
// set it on the mask only if we are in an interesting context
|
||||
if(getContext() != OFX::eContextFilter)
|
||||
rois.setRegionOfInterest(*maskClip_, args.regionOfInterest);
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
BasicPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageScaler<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageScaler<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageScaler<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageScaler<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageScaler<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageScaler<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// overridden is identity
|
||||
bool
|
||||
BasicPlugin:: isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime)
|
||||
{
|
||||
// get the scale parameters
|
||||
double scale = scale_->getValueAtTime(args.time);
|
||||
double rScale = 1, gScale = 1, bScale = 1, aScale = 1;
|
||||
if(componentScalesEnabled_->getValueAtTime(args.time)) {
|
||||
rScale = rScale_->getValueAtTime(args.time);
|
||||
gScale = gScale_->getValueAtTime(args.time);
|
||||
bScale = bScale_->getValueAtTime(args.time);
|
||||
aScale = aScale_->getValueAtTime(args.time);
|
||||
}
|
||||
rScale *= scale; gScale *= scale; bScale *= scale;
|
||||
|
||||
// do we do any scaling ?
|
||||
if(rScale == 1 && gScale == 1 && bScale == 1 && aScale == 1) {
|
||||
identityClip = srcClip_;
|
||||
identityTime = args.time;
|
||||
return true;
|
||||
}
|
||||
|
||||
// nope, idenity we is
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the enabledness of the individual component scales
|
||||
void
|
||||
BasicPlugin::setEnabledness(void)
|
||||
{
|
||||
// the componet enabledness depends on the clip being RGBA and the param being true
|
||||
bool v = componentScalesEnabled_->getValue() && srcClip_->getPixelComponents() == OFX::ePixelComponentRGBA;
|
||||
|
||||
// enable them
|
||||
rScale_->setEnabled(v);
|
||||
gScale_->setEnabled(v);
|
||||
bScale_->setEnabled(v);
|
||||
aScale_->setEnabled(v);
|
||||
}
|
||||
|
||||
// we have changed a param
|
||||
void
|
||||
BasicPlugin::changedParam(const OFX::InstanceChangedArgs &/*args*/, const std::string ¶mName)
|
||||
{
|
||||
if(paramName == "scaleComponents") setEnabledness();
|
||||
}
|
||||
|
||||
// we have changed a param
|
||||
void
|
||||
BasicPlugin::changedClip(const OFX::InstanceChangedArgs &/*args*/, const std::string &clipName)
|
||||
{
|
||||
if(clipName == kOfxImageEffectSimpleSourceClipName) setEnabledness();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// stuff for the interact
|
||||
|
||||
// draw the interact
|
||||
bool BasicInteract::draw(const OFX::DrawArgs &args)
|
||||
{
|
||||
OfxRGBColourF col;
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive : col.r = col.g = col.b = 0.0f; break;
|
||||
case ePoised : col.r = col.g = col.b = 0.5f; break;
|
||||
case ePicked : col.r = col.g = col.b = 1.0f; break;
|
||||
}
|
||||
|
||||
// make the box a constant size on screen by scaling by the pixel scale
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
|
||||
// Draw a cross hair, the current coordinate system aligns with the image plane.
|
||||
glPushMatrix();
|
||||
|
||||
// draw the bo
|
||||
glColor3f(col.r, col.g, col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
// draw a complementary outline
|
||||
glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
bool
|
||||
BasicInteract::penMotion(const OFX::PenArgs &args)
|
||||
{
|
||||
// figure the size of the box in cannonical coords
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
|
||||
// pen position is in cannonical coords
|
||||
OfxPointD penPos = args.penPosition;
|
||||
|
||||
switch(_state) {
|
||||
case eInActive :
|
||||
case ePoised :
|
||||
{
|
||||
// are we in the box, become 'poised'
|
||||
StateEnum newState;
|
||||
penPos.x -= _position.x;
|
||||
penPos.y -= _position.y;
|
||||
if(Absolute(penPos.x) < dx &&
|
||||
Absolute(penPos.y) < dy) {
|
||||
newState = ePoised;
|
||||
}
|
||||
else {
|
||||
newState = eInActive;
|
||||
}
|
||||
|
||||
if(_state != newState) {
|
||||
// we have a new state
|
||||
_state = newState;
|
||||
|
||||
// and force an overlay redraw
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ePicked :
|
||||
{
|
||||
// move our position
|
||||
_position = penPos;
|
||||
|
||||
// and force an overlay redraw
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// we have trapped it only if the mouse ain't over it or we are actively dragging
|
||||
return _state != eInActive;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicInteract::penDown(const OFX::PenArgs &args)
|
||||
{
|
||||
// this will refigure the state
|
||||
penMotion(args);
|
||||
|
||||
// if poised means we were over it when the pen went down, so pick it
|
||||
if(_state == ePoised) {
|
||||
// we are now picked
|
||||
_state = ePicked;
|
||||
|
||||
// move our position
|
||||
_position = args.penPosition;
|
||||
|
||||
// and request a redraw just incase
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
|
||||
return _state == ePicked;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicInteract::penUp(const OFX::PenArgs &args)
|
||||
{
|
||||
if(_state == ePicked) {
|
||||
// reset to poised for a moment
|
||||
_state = ePoised;
|
||||
|
||||
// this will refigure the state
|
||||
penMotion(args);
|
||||
|
||||
// and redraw for good measure
|
||||
_effect->redrawOverlays();
|
||||
|
||||
// we did trap it
|
||||
return true;
|
||||
}
|
||||
|
||||
// we didn't trap it
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
mDeclarePluginFactory(BasicExamplePluginFactory, {}, {});
|
||||
|
||||
class BasicExampleOverlayDescriptor : public DefaultEffectOverlayDescriptor<BasicExampleOverlayDescriptor, BasicInteract> {};
|
||||
|
||||
void BasicExamplePluginFactory::describe(OFX::ImageEffectDescriptor& desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Gain", "Gain", "Gain");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// add the supported contexts, only filter at the moment
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
desc.addSupportedContext(eContextPaint);
|
||||
|
||||
// add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
|
||||
desc.setOverlayInteractDescriptor( new BasicExampleOverlayDescriptor);
|
||||
}
|
||||
|
||||
// make a double scale param
|
||||
static
|
||||
DoubleParamDescriptor *defineScaleParam(OFX::ImageEffectDescriptor &desc,
|
||||
const std::string &name, const std::string &label, const std::string &hint,
|
||||
GroupParamDescriptor *parent)
|
||||
{
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam(name);
|
||||
param->setLabels(label, label, label);
|
||||
param->setScriptName(name);
|
||||
param->setHint(hint);
|
||||
param->setDefault(1);
|
||||
param->setRange(0, 10);
|
||||
param->setIncrement(0.1);
|
||||
param->setDisplayRange(0, 10);
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
if(parent) param->setParent(*parent);
|
||||
return param;
|
||||
}
|
||||
|
||||
|
||||
void BasicExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor& desc, OFX::ContextEnum context)
|
||||
{
|
||||
// Source clip only in the filter context
|
||||
// create the mandated source clip
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
// if general or paint context, define the mask clip
|
||||
if(context == eContextGeneral || context == eContextPaint) {
|
||||
// if paint context, it is a mandated input called 'brush'
|
||||
ClipDescriptor *maskClip = context == eContextGeneral ? desc.defineClip("Mask") : desc.defineClip("Brush");
|
||||
maskClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
maskClip->setTemporalClipAccess(false);
|
||||
if(context == eContextGeneral)
|
||||
maskClip->setOptional(true);
|
||||
maskClip->setSupportsTiles(true);
|
||||
maskClip->setIsMask(true); // we are a mask input
|
||||
}
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
// make some pages and to things in
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
|
||||
// group param to group the scales
|
||||
GroupParamDescriptor *componentScalesGroup = desc.defineGroupParam("componentScales");
|
||||
componentScalesGroup->setHint("Scales on the individual component");
|
||||
componentScalesGroup->setLabels("Components", "Components", "Components");
|
||||
|
||||
// make overall scale params
|
||||
DoubleParamDescriptor *param = defineScaleParam(desc, "scale", "scale", "Scales all component in the image", 0);
|
||||
page->addChild(*param);
|
||||
|
||||
// add a boolean to enable the component scale
|
||||
BooleanParamDescriptor *boolP = desc.defineBooleanParam("scaleComponents");
|
||||
boolP->setDefault(true);
|
||||
boolP->setHint("Enables scales on individual components");
|
||||
boolP->setLabels("Scale Components", "Scale Components", "Scale Components");
|
||||
boolP->setParent(*componentScalesGroup);
|
||||
page->addChild(*boolP);
|
||||
|
||||
// make the four component scale params
|
||||
param = defineScaleParam(desc, "scaleR", "red", "Scales the red component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleG", "green", "Scales the green component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleB", "blue", "Scales the blue component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleA", "alpha", "Scales the alpha component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
}
|
||||
|
||||
ImageEffect *BasicExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
|
||||
{
|
||||
return new BasicPlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static BasicExamplePluginFactory p("net.sf.openfx.basicPlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Microsoft Developer Studio Project File - Name="basic" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=basic - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "basic.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "basic.mak" CFG="basic - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "basic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "basic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "basic - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/basic.ofx"
|
||||
|
||||
!ELSEIF "$(CFG)" == "basic - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\Basic.ofx.bundle\Contents\Win32\basic.ofx" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "basic - Win32 Release"
|
||||
# Name "basic - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\basic.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "basic"=.\basic.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name ofxsupport
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="basic"
|
||||
ProjectGUID="{F14E0B69-3767-44B1-A28C-326B09350C7E}"
|
||||
RootNamespace="basic"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="basic.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,48 @@
|
||||
include(OpenFX)
|
||||
|
||||
set(PLUGINS
|
||||
Basic
|
||||
ChoiceParams
|
||||
Field
|
||||
Generator
|
||||
GPUGain
|
||||
Invert
|
||||
MultiBundle
|
||||
Retimer
|
||||
Tester
|
||||
Transition)
|
||||
|
||||
foreach(PLUGIN IN LISTS PLUGINS)
|
||||
file(GLOB_RECURSE PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.cpp")
|
||||
if (${PLUGIN} STREQUAL "GPUGain")
|
||||
if(APPLE)
|
||||
file(GLOB_RECURSE METAL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.mm") # add Metal kernel
|
||||
list(APPEND PLUGIN_SOURCES ${METAL_SOURCES})
|
||||
endif()
|
||||
if (OFX_SUPPORTS_CUDARENDER)
|
||||
file(GLOB_RECURSE CUDA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.cu")
|
||||
list(APPEND PLUGIN_SOURCES ${CUDA_SOURCES})
|
||||
endif()
|
||||
if (NOT OFX_SUPPORTS_OPENCLRENDER)
|
||||
list(FILTER PLUGIN_SOURCES EXCLUDE REGEX "OpenCLKernel")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(TGT example-${PLUGIN}-support)
|
||||
add_ofx_plugin(${TGT} ${PLUGIN})
|
||||
target_sources(${TGT} PUBLIC ${PLUGIN_SOURCES})
|
||||
target_link_libraries(${TGT} ${CONAN_LIBS} OfxSupport opengl::opengl)
|
||||
target_include_directories(${TGT} PUBLIC ${OFX_HEADER_DIR} ${OFX_SUPPORT_HEADER_DIR})
|
||||
if(APPLE)
|
||||
target_link_libraries(${TGT} "-framework Metal" "-framework Foundation" "-framework QuartzCore")
|
||||
if (OFX_SUPPORTS_OPENCLRENDER)
|
||||
target_link_libraries(${TGT} "-framework OpenCL")
|
||||
endif()
|
||||
else()
|
||||
if (OFX_SUPPORTS_OPENCLRENDER)
|
||||
target_link_libraries(${TGT} OpenCL::Headers OpenCL::OpenCL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
endforeach()
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>choiceparams.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,681 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// a dumb interact that just draw's a square you can drag
|
||||
static const OfxPointD kBoxSize = {20, 20};
|
||||
|
||||
class ChoiceParamsInteract : public OFX::OverlayInteract {
|
||||
protected :
|
||||
enum StateEnum {
|
||||
eInActive,
|
||||
ePoised,
|
||||
ePicked
|
||||
};
|
||||
|
||||
OfxPointD _position;
|
||||
StateEnum _state;
|
||||
|
||||
public :
|
||||
ChoiceParamsInteract(OfxInteractHandle handle, OFX::ImageEffect* /*effect*/)
|
||||
: OFX::OverlayInteract(handle)
|
||||
, _state(eInActive)
|
||||
{
|
||||
_position.x = 0;
|
||||
_position.y = 0;
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
virtual bool draw(const OFX::DrawArgs &args);
|
||||
virtual bool penMotion(const OFX::PenArgs &args);
|
||||
virtual bool penDown(const OFX::PenArgs &args);
|
||||
virtual bool penUp(const OFX::PenArgs &args);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// rendering routines
|
||||
template <class T> inline T
|
||||
Minimum(T a, T b) { return (a < b) ? a : b;}
|
||||
|
||||
template <class T> inline T
|
||||
Absolute(T a) { return (a < 0) ? -a : a;}
|
||||
|
||||
template <class T> inline T
|
||||
Clamp(T v, int min, int max)
|
||||
{
|
||||
if(v < T(min)) return T(min);
|
||||
if(v > T(max)) return T(max);
|
||||
return v;
|
||||
}
|
||||
|
||||
// Base class for the RGBA and the Alpha processor
|
||||
class ImageScalerBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
OFX::Image *_maskImg;
|
||||
double _rScale, _gScale, _bScale, _aScale;
|
||||
bool _doMasking;
|
||||
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
ImageScalerBase(OFX::ImageEffect &instance)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _srcImg(0)
|
||||
, _maskImg(0)
|
||||
, _rScale(1)
|
||||
, _gScale(1)
|
||||
, _bScale(1)
|
||||
, _aScale(1)
|
||||
, _doMasking(false)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the src image */
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
|
||||
/** @brief set the optional mask image */
|
||||
void setMaskImg(OFX::Image *v) {_maskImg = v;}
|
||||
|
||||
// Are we masking. We can't derive this from the mask image being set as NULL is a valid value for an input image
|
||||
void doMasking(bool v) {_doMasking = v;}
|
||||
|
||||
|
||||
/** @brief set the scale */
|
||||
void setScales(float r, float g, float b, float a)
|
||||
{
|
||||
_rScale = r;
|
||||
_gScale = g;
|
||||
_bScale = b;
|
||||
_aScale = a;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// template to do the RGBA processing
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageScaler : public ImageScalerBase {
|
||||
public :
|
||||
// ctor
|
||||
ImageScaler(OFX::ImageEffect &instance)
|
||||
: ImageScalerBase(instance)
|
||||
{}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float scales[4];
|
||||
scales[0] = nComponents == 1 ? (float)_aScale : (float)_rScale;
|
||||
scales[1] = (float)_gScale;
|
||||
scales[2] = (float)_bScale;
|
||||
scales[3] = (float)_aScale;
|
||||
|
||||
float maskScale = 1.0f;
|
||||
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
// are we doing masking
|
||||
if(_doMasking) {
|
||||
// we do, get the pixel from the mask
|
||||
if(!_maskImg)
|
||||
maskScale = 1.0f;
|
||||
else
|
||||
{
|
||||
PIX *maskPix = (PIX *) (_maskImg ? _maskImg->getPixelAddress(x, y) : 0);
|
||||
// figure the scale factor from that pixel
|
||||
maskScale = maskPix != 0 ? float(*maskPix)/float(max) : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// do we have a source image to scale up
|
||||
if(srcPix) {
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
float v;
|
||||
|
||||
// scale the component up by the scale factor, modulated by the maskScale
|
||||
if(maskScale != 1.0f)
|
||||
v = srcPix[c] * (1.0f + (scales[c] - 1.0f) * maskScale);
|
||||
else
|
||||
v = srcPix[c] * scales[c];
|
||||
|
||||
if(max == 1) // implies floating point and so no clamping
|
||||
dstPix[c] = PIX(v);
|
||||
else // integer based and we need to clamp
|
||||
dstPix[c] = PIX(Clamp(v, 0, max));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no src pixel here, be black and transparent
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
}
|
||||
// increment the dst pixel
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class ChoiceParamsPlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
OFX::Clip *maskClip_;
|
||||
|
||||
OFX::ChoiceParam *red_choice_;
|
||||
OFX::ChoiceParam *green_choice_;
|
||||
OFX::StrChoiceParam *blue_choice_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
ChoiceParamsPlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, srcClip_(0)
|
||||
, red_choice_(0)
|
||||
, green_choice_(0)
|
||||
, blue_choice_()
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
// name of mask clip depends on the context
|
||||
maskClip_ = getContext() == OFX::eContextFilter ? NULL : fetchClip(getContext() == OFX::eContextPaint ? "Brush" : "Mask");
|
||||
red_choice_ = fetchChoiceParam("red_choice");
|
||||
green_choice_ = fetchChoiceParam("green_choice");
|
||||
if (OFX::getImageEffectHostDescription()->supportsStrChoice) {
|
||||
blue_choice_ = fetchStrChoiceParam("blue_choice");
|
||||
}
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* override is identity */
|
||||
virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime);
|
||||
|
||||
/* override changedParam */
|
||||
virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName);
|
||||
|
||||
/* override changed clip */
|
||||
virtual void changedClip(const OFX::InstanceChangedArgs &args, const std::string &clipName);
|
||||
|
||||
// override the rod call
|
||||
virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod);
|
||||
|
||||
// override the roi call
|
||||
virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois);
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
setupAndProcess(ImageScalerBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
ChoiceParamsPlugin::setupAndProcess(ImageScalerBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// fetch main input image
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(src.get()) {
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
std::unique_ptr<OFX::Image> mask;
|
||||
|
||||
// do we do masking
|
||||
if(getContext() != OFX::eContextFilter) {
|
||||
mask.reset(maskClip_->fetchImage(args.time));
|
||||
// say we are masking
|
||||
processor.doMasking(true);
|
||||
|
||||
// Set it in the processor
|
||||
processor.setMaskImg(mask.get());
|
||||
}
|
||||
|
||||
// get the scale parameter values...
|
||||
|
||||
int ri = 0;
|
||||
int gi = 0;
|
||||
std::string bi;
|
||||
double r = 0, g = 0, b = 0, a = 0;
|
||||
|
||||
red_choice_->getValueAtTime(args.time, ri);
|
||||
green_choice_->getValueAtTime(args.time, gi);
|
||||
|
||||
if (ri == 0)
|
||||
r = 0;
|
||||
if (ri == 1)
|
||||
r = 0.5;
|
||||
if (ri == 2)
|
||||
r = 1.0;
|
||||
|
||||
// Note that green options are out of order
|
||||
if (gi == 0)
|
||||
g = 0;
|
||||
if (gi == 2)
|
||||
g = 0.5;
|
||||
if (gi == 1)
|
||||
g = 1.0;
|
||||
|
||||
if (OFX::getImageEffectHostDescription()->supportsStrChoice) {
|
||||
blue_choice_->getValueAtTime(args.time, bi);
|
||||
if (bi == "blue_0.0")
|
||||
b = 0;
|
||||
if (bi == "blue_0.5")
|
||||
b = 0.5;
|
||||
if (bi == "blue_1.0")
|
||||
b = 1.0;
|
||||
} else {
|
||||
b = 1.0;
|
||||
}
|
||||
|
||||
a = 1.0; // always
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// set the scales
|
||||
processor.setScales((float)r, (float)g, (float)b, (float)a);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
// override the rod call
|
||||
bool
|
||||
ChoiceParamsPlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod)
|
||||
{
|
||||
// our RoD is the same as the 'Source' clip's, we are not interested in the mask
|
||||
rod = srcClip_->getRegionOfDefinition(args.time);
|
||||
|
||||
// say we set it
|
||||
return true;
|
||||
}
|
||||
|
||||
// override the roi call
|
||||
void
|
||||
ChoiceParamsPlugin::getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois)
|
||||
{
|
||||
// we don't actually need to do this as this is the default, but do it for examples sake
|
||||
rois.setRegionOfInterest(*srcClip_, args.regionOfInterest);
|
||||
|
||||
// set it on the mask only if we are in an interesting context
|
||||
if(getContext() != OFX::eContextFilter)
|
||||
rois.setRegionOfInterest(*maskClip_, args.regionOfInterest);
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
ChoiceParamsPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageScaler<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageScaler<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageScaler<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageScaler<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageScaler<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageScaler<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// overridden is identity
|
||||
bool
|
||||
ChoiceParamsPlugin:: isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have changed a param
|
||||
void
|
||||
ChoiceParamsPlugin::changedParam(const OFX::InstanceChangedArgs &/*args*/, const std::string ¶mName)
|
||||
{
|
||||
}
|
||||
|
||||
// we have changed a param
|
||||
void
|
||||
ChoiceParamsPlugin::changedClip(const OFX::InstanceChangedArgs &/*args*/, const std::string &clipName)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// stuff for the interact
|
||||
|
||||
// draw the interact
|
||||
bool ChoiceParamsInteract::draw(const OFX::DrawArgs &args)
|
||||
{
|
||||
OfxRGBColourF col;
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive : col.r = col.g = col.b = 0.0f; break;
|
||||
case ePoised : col.r = col.g = col.b = 0.5f; break;
|
||||
case ePicked : col.r = col.g = col.b = 1.0f; break;
|
||||
}
|
||||
|
||||
// make the box a constant size on screen by scaling by the pixel scale
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
|
||||
// Draw a cross hair, the current coordinate system aligns with the image plane.
|
||||
glPushMatrix();
|
||||
|
||||
// draw the bo
|
||||
glColor3f(col.r, col.g, col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
// draw a complementary outline
|
||||
glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
bool
|
||||
ChoiceParamsInteract::penMotion(const OFX::PenArgs &args)
|
||||
{
|
||||
// figure the size of the box in cannonical coords
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
|
||||
// pen position is in cannonical coords
|
||||
OfxPointD penPos = args.penPosition;
|
||||
|
||||
switch(_state) {
|
||||
case eInActive :
|
||||
case ePoised :
|
||||
{
|
||||
// are we in the box, become 'poised'
|
||||
StateEnum newState;
|
||||
penPos.x -= _position.x;
|
||||
penPos.y -= _position.y;
|
||||
if(Absolute(penPos.x) < dx &&
|
||||
Absolute(penPos.y) < dy) {
|
||||
newState = ePoised;
|
||||
}
|
||||
else {
|
||||
newState = eInActive;
|
||||
}
|
||||
|
||||
if(_state != newState) {
|
||||
// we have a new state
|
||||
_state = newState;
|
||||
|
||||
// and force an overlay redraw
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ePicked :
|
||||
{
|
||||
// move our position
|
||||
_position = penPos;
|
||||
|
||||
// and force an overlay redraw
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// we have trapped it only if the mouse ain't over it or we are actively dragging
|
||||
return _state != eInActive;
|
||||
}
|
||||
|
||||
bool
|
||||
ChoiceParamsInteract::penDown(const OFX::PenArgs &args)
|
||||
{
|
||||
// this will refigure the state
|
||||
penMotion(args);
|
||||
|
||||
// if poised means we were over it when the pen went down, so pick it
|
||||
if(_state == ePoised) {
|
||||
// we are now picked
|
||||
_state = ePicked;
|
||||
|
||||
// move our position
|
||||
_position = args.penPosition;
|
||||
|
||||
// and request a redraw just incase
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
|
||||
return _state == ePicked;
|
||||
}
|
||||
|
||||
bool
|
||||
ChoiceParamsInteract::penUp(const OFX::PenArgs &args)
|
||||
{
|
||||
if(_state == ePicked) {
|
||||
// reset to poised for a moment
|
||||
_state = ePoised;
|
||||
|
||||
// this will refigure the state
|
||||
penMotion(args);
|
||||
|
||||
// and redraw for good measure
|
||||
_effect->redrawOverlays();
|
||||
|
||||
// we did trap it
|
||||
return true;
|
||||
}
|
||||
|
||||
// we didn't trap it
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
mDeclarePluginFactory(ChoiceParamsExamplePluginFactory, {}, {});
|
||||
|
||||
class ChoiceParamsExampleOverlayDescriptor : public DefaultEffectOverlayDescriptor<ChoiceParamsExampleOverlayDescriptor, ChoiceParamsInteract> {};
|
||||
|
||||
void ChoiceParamsExamplePluginFactory::describe(OFX::ImageEffectDescriptor& desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Choice Params (Support)", "ChoiceParams(spt)", "Choice Params (Support)");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// add the supported contexts, only filter at the moment
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
desc.addSupportedContext(eContextPaint);
|
||||
|
||||
// add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
|
||||
desc.setOverlayInteractDescriptor( new ChoiceParamsExampleOverlayDescriptor);
|
||||
}
|
||||
|
||||
void ChoiceParamsExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor& desc, OFX::ContextEnum context)
|
||||
{
|
||||
// Source clip only in the filter context
|
||||
// create the mandated source clip
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
// if general or paint context, define the mask clip
|
||||
if(context == eContextGeneral || context == eContextPaint) {
|
||||
// if paint context, it is a mandated input called 'brush'
|
||||
ClipDescriptor *maskClip = context == eContextGeneral ? desc.defineClip("Mask") : desc.defineClip("Brush");
|
||||
maskClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
maskClip->setTemporalClipAccess(false);
|
||||
if(context == eContextGeneral)
|
||||
maskClip->setOptional(true);
|
||||
maskClip->setSupportsTiles(true);
|
||||
maskClip->setIsMask(true); // we are a mask input
|
||||
}
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
// make some pages and to things in
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
|
||||
auto *choice1 = desc.defineChoiceParam("red_choice");
|
||||
choice1->appendOption("red: none");
|
||||
choice1->appendOption("red: some");
|
||||
choice1->appendOption("red: lots");
|
||||
choice1->setDefault(0);
|
||||
page->addChild(*choice1);
|
||||
|
||||
// Note: index 1 is "lots" (even though UI order is 2), index 2 is "some"
|
||||
// because options are appended in order.
|
||||
auto *choice2 = desc.defineChoiceParam("green_choice");
|
||||
choice2->appendOption("green: none", "", 0);
|
||||
choice2->appendOption("green: lots", "", 2);
|
||||
choice2->appendOption("green: some", "", 1);
|
||||
choice2->setDefault(0);
|
||||
page->addChild(*choice2);
|
||||
|
||||
if (getImageEffectHostDescription()->supportsStrChoice) {
|
||||
auto *choice3 = desc.defineStrChoiceParam("blue_choice");
|
||||
choice3->appendOption("blue_0.0", "blue: none", 0);
|
||||
choice3->appendOption("blue_0.5", "blue: some", 1);
|
||||
choice3->appendOption("blue_1.0", "blue: lots", 2);
|
||||
choice3->setDefault("blue_0.0");
|
||||
page->addChild(*choice3);
|
||||
}
|
||||
}
|
||||
|
||||
ImageEffect *ChoiceParamsExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
|
||||
{
|
||||
return new ChoiceParamsPlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static ChoiceParamsExamplePluginFactory p("org.openeffects.support.choiceParamsPlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic", "Basic\basic.vcproj", "{F14E0B69-3767-44B1-A28C-326B09350C7E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ofxsupport", "..\Library\ofxsupport.vcproj", "{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "noise", "Generator\noise.vcproj", "{F14EBC69-3767-44B1-A28C-326B59350C7F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "invert", "Invert\invert.vcproj", "{F14E0B89-3767-88B1-A28C-326B0B350C7E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "retimer", "Retimer\retimer.vcproj", "{F14E0B89-3767-48B1-A28C-326B0F350C7B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crossfade", "Transition\crossFade.vcproj", "{C14CCB89-3767-88B1-A28C-326B0B350C7E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "proptester", "..\PropTester\propTester.vcproj", "{F14E0B69-BD67-4CB1-A28C-326B09350C7B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultiBundle", "MultiBundle\multibundle.vcproj", "{F14ECC69-3767-44B1-A28C-32FB09F50C7E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707} = {257EC9EE-530A-4A6F-8B2E-AAB1C8458707}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Debug|x64.Build.0 = Debug|x64
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Release|x64.ActiveCfg = Release|x64
|
||||
{F14E0B69-3767-44B1-A28C-326B09350C7E}.Release|x64.Build.0 = Release|x64
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Debug|x64.Build.0 = Debug|x64
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Release|Win32.Build.0 = Release|Win32
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Release|x64.ActiveCfg = Release|x64
|
||||
{257EC9EE-530A-4A6F-8B2E-AAB1C8458707}.Release|x64.Build.0 = Release|x64
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Debug|x64.Build.0 = Debug|x64
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Release|x64.ActiveCfg = Release|x64
|
||||
{F14EBC69-3767-44B1-A28C-326B59350C7F}.Release|x64.Build.0 = Release|x64
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Debug|x64.Build.0 = Debug|x64
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Release|x64.ActiveCfg = Release|x64
|
||||
{F14E0B89-3767-88B1-A28C-326B0B350C7E}.Release|x64.Build.0 = Release|x64
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Debug|x64.Build.0 = Debug|x64
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Release|x64.ActiveCfg = Release|x64
|
||||
{F14E0B89-3767-48B1-A28C-326B0F350C7B}.Release|x64.Build.0 = Release|x64
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Debug|x64.Build.0 = Debug|x64
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Release|Win32.Build.0 = Release|Win32
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Release|x64.ActiveCfg = Release|x64
|
||||
{C14CCB89-3767-88B1-A28C-326B0B350C7E}.Release|x64.Build.0 = Release|x64
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Debug|x64.Build.0 = Debug|x64
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Release|x64.ActiveCfg = Release|x64
|
||||
{F14E0B69-BD67-4CB1-A28C-326B09350C7B}.Release|x64.Build.0 = Release|x64
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Release|Win32.Build.0 = Release|Win32
|
||||
{F14ECC69-3767-44B1-A28C-32FB09F50C7E}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>field.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
|
||||
// Base class for the RGBA and the Alpha processor
|
||||
class FieldBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
OFX::FieldEnum _field;
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
FieldBase(OFX::ImageEffect &instance, OFX::FieldEnum field)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _srcImg(0), _field(field)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the src image */
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
};
|
||||
|
||||
// template to do the RGBA processing
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageFielder : public FieldBase {
|
||||
public :
|
||||
// ctor
|
||||
ImageFielder(OFX::ImageEffect &instance, OFX::FieldEnum field)
|
||||
: FieldBase(instance, field)
|
||||
{}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
//eFieldLower only the spatially lower field is present
|
||||
//eFieldUpper only the spatially upper field is present
|
||||
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
// do we have a source image to scale up
|
||||
if(srcPix) {
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
if((_field == OFX::eFieldLower) && (c==0))
|
||||
dstPix[c] = max;
|
||||
else if((_field == OFX::eFieldUpper) && (c==2))
|
||||
dstPix[c] = max;
|
||||
else
|
||||
dstPix[c] = max - srcPix[c];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no src pixel here, be black and transparent
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
if((_field == OFX::eFieldLower) && (c==0))
|
||||
dstPix[c] = max;
|
||||
else if((_field == OFX::eFieldUpper) && (c==2))
|
||||
dstPix[c] = max;
|
||||
else
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// increment the dst pixel
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class FieldPlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
FieldPlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, srcClip_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* set up and run a processor */
|
||||
void setupAndProcess(FieldBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
FieldPlugin::setupAndProcess(FieldBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// fetch main input image
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(src.get()) {
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
FieldPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
double time = args.time;
|
||||
std::cout << "Rendering at time " << time << std::endl;
|
||||
OFX::FieldEnum field = args.fieldToRender;
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA)
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageFielder<unsigned char, 4, 255> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageFielder<unsigned short, 4, 65535> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageFielder<float, 4, 1> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageFielder<unsigned char, 1, 255> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageFielder<unsigned short, 1, 65535> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageFielder<float, 1, 1> fred(*this, field);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mDeclarePluginFactory(FieldExamplePluginFactory, {}, {});
|
||||
|
||||
using namespace OFX;
|
||||
void FieldExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Field", "Field", "Field");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// add the supported contexts, only filter at the moment
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
|
||||
// add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(true);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
}
|
||||
|
||||
void FieldExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
// Source clip only in the filter context
|
||||
// create the mandated source clip
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
srcClip->setFieldExtraction(eFieldExtractSingle);
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
}
|
||||
|
||||
OFX::ImageEffect* FieldExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
return new FieldPlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static FieldExamplePluginFactory p("net.sf.openfx.fieldPlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="field"
|
||||
ProjectGUID="{F14E0B89-3767-88B1-A28C-326B0B350C7E}"
|
||||
RootNamespace="field"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="field.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
__global__ void GainAdjustKernel(int p_Width, int p_Height, float p_GainR, float p_GainG, float p_GainB, float p_GainA, const float* p_Input, float* p_Output)
|
||||
{
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if ((x < p_Width) && (y < p_Height))
|
||||
{
|
||||
const int index = ((y * p_Width) + x) * 4;
|
||||
|
||||
p_Output[index + 0] = p_Input[index + 0] * p_GainR;
|
||||
p_Output[index + 1] = p_Input[index + 1] * p_GainG;
|
||||
p_Output[index + 2] = p_Input[index + 2] * p_GainB;
|
||||
p_Output[index + 3] = p_Input[index + 3] * p_GainA;
|
||||
}
|
||||
}
|
||||
|
||||
void RunCudaKernel(void* p_Stream, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output)
|
||||
{
|
||||
dim3 threads(128, 1, 1);
|
||||
dim3 blocks(((p_Width + threads.x - 1) / threads.x), p_Height, 1);
|
||||
cudaStream_t stream = static_cast<cudaStream_t>(p_Stream);
|
||||
|
||||
GainAdjustKernel<<<blocks, threads, 0, stream>>>(p_Width, p_Height, p_Gain[0], p_Gain[1], p_Gain[2], p_Gain[3], p_Input, p_Output);
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
|
||||
|
||||
#include "GPUGain.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
#include "ofxsProcessing.h"
|
||||
#include "ofxsLog.h"
|
||||
|
||||
#define kPluginName "GPU Gain"
|
||||
#define kPluginGrouping "OFX Example (Support)"
|
||||
#define kPluginDescription "Apply separate RGB gain adjustments to each channels; CUDA/OpenCL Buffers/OpenCL Images/Metal"
|
||||
#define kPluginIdentifier "com.OpenFXSample.GPUGain"
|
||||
#define kPluginVersionMajor 1
|
||||
#define kPluginVersionMinor 0
|
||||
|
||||
#define kSupportsTiles false
|
||||
#define kSupportsMultiResolution false
|
||||
#define kSupportsMultipleClipPARs false
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GainExample : public OFX::ImageProcessor
|
||||
{
|
||||
public:
|
||||
explicit GainExample(OFX::ImageEffect& p_Instance);
|
||||
|
||||
virtual void processImagesCuda();
|
||||
virtual void processImagesOpenCL();
|
||||
virtual void processImagesMetal();
|
||||
virtual void multiThreadProcessImages(OfxRectI p_ProcWindow);
|
||||
|
||||
void setSrcImg(OFX::Image* p_SrcImg);
|
||||
void setScales(float p_ScaleR, float p_ScaleG, float p_ScaleB, float p_ScaleA);
|
||||
|
||||
private:
|
||||
OFX::Image* _srcImg;
|
||||
float _scales[4];
|
||||
};
|
||||
|
||||
GainExample::GainExample(OFX::ImageEffect& p_Instance)
|
||||
: OFX::ImageProcessor(p_Instance)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef OFX_SUPPORTS_CUDARENDER
|
||||
extern void RunCudaKernel(void* p_Stream, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
|
||||
#endif
|
||||
|
||||
void GainExample::processImagesCuda()
|
||||
{
|
||||
#ifdef OFX_SUPPORTS_CUDARENDER
|
||||
const OfxRectI& bounds = _srcImg->getBounds();
|
||||
const int width = bounds.x2 - bounds.x1;
|
||||
const int height = bounds.y2 - bounds.y1;
|
||||
|
||||
float* input = static_cast<float*>(_srcImg->getPixelData());
|
||||
float* output = static_cast<float*>(_dstImg->getPixelData());
|
||||
|
||||
RunCudaKernel(_pCudaStream, width, height, _scales, input, output);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern void RunMetalKernel(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
|
||||
#endif
|
||||
|
||||
void GainExample::processImagesMetal()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
const OfxRectI& bounds = _srcImg->getBounds();
|
||||
const int width = bounds.x2 - bounds.x1;
|
||||
const int height = bounds.y2 - bounds.y1;
|
||||
|
||||
float* input = static_cast<float*>(_srcImg->getPixelData());
|
||||
float* output = static_cast<float*>(_dstImg->getPixelData());
|
||||
|
||||
RunMetalKernel(_pMetalCmdQ, width, height, _scales, input, output);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void RunOpenCLKernelBuffers(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
|
||||
extern void RunOpenCLKernelImages(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output);
|
||||
|
||||
void GainExample::processImagesOpenCL()
|
||||
{
|
||||
#ifdef OFX_SUPPORTS_OPENCLRENDER
|
||||
const OfxRectI& bounds = _srcImg->getBounds();
|
||||
const int width = bounds.x2 - bounds.x1;
|
||||
const int height = bounds.y2 - bounds.y1;
|
||||
|
||||
float* input = static_cast<float*>(_srcImg->getOpenCLImage());
|
||||
float* output = static_cast<float*>(_dstImg->getOpenCLImage());
|
||||
|
||||
// if a plugin supports both OpenCL Buffers and Images, the host decides which is used and
|
||||
// the plugin must determine which based on whether kOfxImageEffectPropOpenCLImage or kOfxImagePropData is set
|
||||
if (input || output)
|
||||
{
|
||||
RunOpenCLKernelImages(_pOpenCLCmdQ, width, height, _scales, input, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
input = static_cast<float*>(_srcImg->getPixelData());
|
||||
output = static_cast<float*>(_dstImg->getPixelData());
|
||||
|
||||
RunOpenCLKernelBuffers(_pOpenCLCmdQ, width, height, _scales, input, output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GainExample::multiThreadProcessImages(OfxRectI p_ProcWindow)
|
||||
{
|
||||
for (int y = p_ProcWindow.y1; y < p_ProcWindow.y2; ++y)
|
||||
{
|
||||
if (_effect.abort()) break;
|
||||
|
||||
float* dstPix = static_cast<float*>(_dstImg->getPixelAddress(p_ProcWindow.x1, y));
|
||||
|
||||
for (int x = p_ProcWindow.x1; x < p_ProcWindow.x2; ++x)
|
||||
{
|
||||
float* srcPix = static_cast<float*>(_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
// do we have a source image to scale up
|
||||
if (srcPix)
|
||||
{
|
||||
for(int c = 0; c < 4; ++c)
|
||||
{
|
||||
dstPix[c] = srcPix[c] * _scales[c];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no src pixel here, be black and transparent
|
||||
for (int c = 0; c < 4; ++c)
|
||||
{
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// increment the dst pixel
|
||||
dstPix += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GainExample::setSrcImg(OFX::Image* p_SrcImg)
|
||||
{
|
||||
_srcImg = p_SrcImg;
|
||||
}
|
||||
|
||||
void GainExample::setScales(float p_ScaleR, float p_ScaleG, float p_ScaleB, float p_ScaleA)
|
||||
{
|
||||
_scales[0] = p_ScaleR;
|
||||
_scales[1] = p_ScaleG;
|
||||
_scales[2] = p_ScaleB;
|
||||
_scales[3] = p_ScaleA;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class GPUGain : public OFX::ImageEffect
|
||||
{
|
||||
public:
|
||||
explicit GPUGain(OfxImageEffectHandle p_Handle);
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments& p_Args);
|
||||
|
||||
/* Override is identity */
|
||||
virtual bool isIdentity(const OFX::IsIdentityArguments& p_Args, OFX::Clip*& p_IdentityClip, double& p_IdentityTime);
|
||||
|
||||
/* Override changedParam */
|
||||
virtual void changedParam(const OFX::InstanceChangedArgs& p_Args, const std::string& p_ParamName);
|
||||
|
||||
/* Override changed clip */
|
||||
virtual void changedClip(const OFX::InstanceChangedArgs& p_Args, const std::string& p_ClipName);
|
||||
|
||||
/* Set the enabledness of the component scale params depending on the type of input image and the state of the scaleComponents param */
|
||||
void setEnabledness();
|
||||
|
||||
/* Set up and run a processor */
|
||||
void setupAndProcess(GainExample &p_GainExample, const OFX::RenderArguments& p_Args);
|
||||
|
||||
private:
|
||||
// Does not own the following pointers
|
||||
OFX::Clip* m_DstClip;
|
||||
OFX::Clip* m_SrcClip;
|
||||
|
||||
OFX::DoubleParam* m_Scale;
|
||||
OFX::DoubleParam* m_ScaleR;
|
||||
OFX::DoubleParam* m_ScaleG;
|
||||
OFX::DoubleParam* m_ScaleB;
|
||||
OFX::DoubleParam* m_ScaleA;
|
||||
OFX::BooleanParam* m_ComponentScalesEnabled;
|
||||
};
|
||||
|
||||
GPUGain::GPUGain(OfxImageEffectHandle p_Handle)
|
||||
: ImageEffect(p_Handle)
|
||||
{
|
||||
m_DstClip = fetchClip(kOfxImageEffectOutputClipName);
|
||||
m_SrcClip = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
|
||||
m_Scale = fetchDoubleParam("scale");
|
||||
m_ScaleR = fetchDoubleParam("scaleR");
|
||||
m_ScaleG = fetchDoubleParam("scaleG");
|
||||
m_ScaleB = fetchDoubleParam("scaleB");
|
||||
m_ScaleA = fetchDoubleParam("scaleA");
|
||||
m_ComponentScalesEnabled = fetchBooleanParam("scaleComponents");
|
||||
|
||||
// Set the enabledness of our RGBA sliders
|
||||
setEnabledness();
|
||||
}
|
||||
|
||||
void GPUGain::render(const OFX::RenderArguments& p_Args)
|
||||
{
|
||||
if ((m_DstClip->getPixelDepth() == OFX::eBitDepthFloat) && (m_DstClip->getPixelComponents() == OFX::ePixelComponentRGBA))
|
||||
{
|
||||
GainExample imageScaler(*this);
|
||||
setupAndProcess(imageScaler, p_Args);
|
||||
}
|
||||
else
|
||||
{
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUGain::isIdentity(const OFX::IsIdentityArguments& p_Args, OFX::Clip*& p_IdentityClip, double& p_IdentityTime)
|
||||
{
|
||||
double rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
|
||||
|
||||
if (m_ComponentScalesEnabled->getValueAtTime(p_Args.time))
|
||||
{
|
||||
rScale = m_ScaleR->getValueAtTime(p_Args.time);
|
||||
gScale = m_ScaleG->getValueAtTime(p_Args.time);
|
||||
bScale = m_ScaleB->getValueAtTime(p_Args.time);
|
||||
aScale = m_ScaleA->getValueAtTime(p_Args.time);
|
||||
}
|
||||
|
||||
const double scale = m_Scale->getValueAtTime(p_Args.time);
|
||||
rScale *= scale;
|
||||
gScale *= scale;
|
||||
bScale *= scale;
|
||||
|
||||
if ((rScale == 1.0) && (gScale == 1.0) && (bScale == 1.0) && (aScale == 1.0))
|
||||
{
|
||||
p_IdentityClip = m_SrcClip;
|
||||
p_IdentityTime = p_Args.time;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPUGain::changedParam(const OFX::InstanceChangedArgs& p_Args, const std::string& p_ParamName)
|
||||
{
|
||||
if (p_ParamName == "scaleComponents")
|
||||
{
|
||||
setEnabledness();
|
||||
}
|
||||
}
|
||||
|
||||
void GPUGain::changedClip(const OFX::InstanceChangedArgs& p_Args, const std::string& p_ClipName)
|
||||
{
|
||||
if (p_ClipName == kOfxImageEffectSimpleSourceClipName)
|
||||
{
|
||||
setEnabledness();
|
||||
}
|
||||
}
|
||||
|
||||
void GPUGain::setEnabledness()
|
||||
{
|
||||
// the component enabledness depends on the clip being RGBA and the param being true
|
||||
const bool enable = (m_ComponentScalesEnabled->getValue() && (m_SrcClip->getPixelComponents() == OFX::ePixelComponentRGBA));
|
||||
|
||||
m_ScaleR->setEnabled(enable);
|
||||
m_ScaleG->setEnabled(enable);
|
||||
m_ScaleB->setEnabled(enable);
|
||||
m_ScaleA->setEnabled(enable);
|
||||
}
|
||||
|
||||
void GPUGain::setupAndProcess(GainExample& p_GainExample, const OFX::RenderArguments& p_Args)
|
||||
{
|
||||
// Get the dst image
|
||||
std::unique_ptr<OFX::Image> dst(m_DstClip->fetchImage(p_Args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// Get the src image
|
||||
std::unique_ptr<OFX::Image> src(m_SrcClip->fetchImage(p_Args.time));
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// Check to see if the bit depth and number of components are the same
|
||||
if ((srcBitDepth != dstBitDepth) || (srcComponents != dstComponents))
|
||||
{
|
||||
OFX::throwSuiteStatusException(kOfxStatErrValue);
|
||||
}
|
||||
|
||||
double rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
|
||||
|
||||
if (m_ComponentScalesEnabled->getValueAtTime(p_Args.time))
|
||||
{
|
||||
rScale = m_ScaleR->getValueAtTime(p_Args.time);
|
||||
gScale = m_ScaleG->getValueAtTime(p_Args.time);
|
||||
bScale = m_ScaleB->getValueAtTime(p_Args.time);
|
||||
aScale = m_ScaleA->getValueAtTime(p_Args.time);
|
||||
}
|
||||
|
||||
const double scale = m_Scale->getValueAtTime(p_Args.time);
|
||||
rScale *= scale;
|
||||
gScale *= scale;
|
||||
bScale *= scale;
|
||||
|
||||
// Set the images
|
||||
p_GainExample.setDstImg(dst.get());
|
||||
p_GainExample.setSrcImg(src.get());
|
||||
|
||||
// Setup OpenCL and CUDA Render arguments
|
||||
p_GainExample.setGPURenderArgs(p_Args);
|
||||
|
||||
// Set the render window
|
||||
p_GainExample.setRenderWindow(p_Args.renderWindow);
|
||||
|
||||
// Set the scales
|
||||
p_GainExample.setScales(rScale, gScale, bScale, aScale);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
p_GainExample.process();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
GPUGainFactory::GPUGainFactory()
|
||||
: OFX::PluginFactoryHelper<GPUGainFactory>(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor)
|
||||
{
|
||||
}
|
||||
|
||||
void GPUGainFactory::describe(OFX::ImageEffectDescriptor& p_Desc)
|
||||
{
|
||||
// Basic labels
|
||||
p_Desc.setLabels(kPluginName, kPluginName, kPluginName);
|
||||
p_Desc.setPluginGrouping(kPluginGrouping);
|
||||
p_Desc.setPluginDescription(kPluginDescription);
|
||||
|
||||
// Add the supported contexts, only filter at the moment
|
||||
p_Desc.addSupportedContext(eContextFilter);
|
||||
p_Desc.addSupportedContext(eContextGeneral);
|
||||
|
||||
// Add supported pixel depths
|
||||
p_Desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// Set a few flags
|
||||
p_Desc.setSingleInstance(false);
|
||||
p_Desc.setHostFrameThreading(false);
|
||||
p_Desc.setSupportsMultiResolution(kSupportsMultiResolution);
|
||||
p_Desc.setSupportsTiles(kSupportsTiles);
|
||||
p_Desc.setTemporalClipAccess(false);
|
||||
p_Desc.setRenderTwiceAlways(false);
|
||||
p_Desc.setSupportsMultipleClipPARs(kSupportsMultipleClipPARs);
|
||||
|
||||
// Setup OpenCL render capability flags
|
||||
p_Desc.setSupportsOpenCLBuffersRender(true);
|
||||
p_Desc.setSupportsOpenCLImagesRender(true);
|
||||
|
||||
// Setup CUDA render capability flags on non-Apple system
|
||||
#ifndef __APPLE__
|
||||
p_Desc.setSupportsCudaRender(true);
|
||||
p_Desc.setSupportsCudaStream(true);
|
||||
#endif
|
||||
|
||||
// Setup Metal render capability flags only on Apple system
|
||||
#ifdef __APPLE__
|
||||
p_Desc.setSupportsMetalRender(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
static DoubleParamDescriptor* defineScaleParam(OFX::ImageEffectDescriptor& p_Desc, const std::string& p_Name, const std::string& p_Label,
|
||||
const std::string& p_Hint, GroupParamDescriptor* p_Parent)
|
||||
{
|
||||
DoubleParamDescriptor* param = p_Desc.defineDoubleParam(p_Name);
|
||||
param->setLabels(p_Label, p_Label, p_Label);
|
||||
param->setScriptName(p_Name);
|
||||
param->setHint(p_Hint);
|
||||
param->setDefault(1);
|
||||
param->setRange(0, 10);
|
||||
param->setIncrement(0.1);
|
||||
param->setDisplayRange(0, 10);
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
|
||||
if (p_Parent)
|
||||
{
|
||||
param->setParent(*p_Parent);
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
|
||||
void GPUGainFactory::describeInContext(OFX::ImageEffectDescriptor& p_Desc, OFX::ContextEnum /*p_Context*/)
|
||||
{
|
||||
// Source clip only in the filter context
|
||||
// Create the mandated source clip
|
||||
ClipDescriptor* srcClip = p_Desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(kSupportsTiles);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
// Create the mandated output clip
|
||||
ClipDescriptor* dstClip = p_Desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(kSupportsTiles);
|
||||
|
||||
// Make some pages and to things in
|
||||
PageParamDescriptor* page = p_Desc.definePageParam("Controls");
|
||||
|
||||
// Group param to group the scales
|
||||
GroupParamDescriptor* componentScalesGroup = p_Desc.defineGroupParam("componentScales");
|
||||
componentScalesGroup->setHint("Scales on the individual component");
|
||||
componentScalesGroup->setLabels("Components", "Components", "Components");
|
||||
|
||||
// Make overall scale params
|
||||
DoubleParamDescriptor* param = defineScaleParam(p_Desc, "scale", "scale", "Scales all component in the image", 0);
|
||||
page->addChild(*param);
|
||||
|
||||
// Add a boolean to enable the component scale
|
||||
BooleanParamDescriptor* boolParam = p_Desc.defineBooleanParam("scaleComponents");
|
||||
boolParam->setDefault(true);
|
||||
boolParam->setHint("Enables scales on individual components");
|
||||
boolParam->setLabels("Scale Components", "Scale Components", "Scale Components");
|
||||
boolParam->setParent(*componentScalesGroup);
|
||||
page->addChild(*boolParam);
|
||||
|
||||
// Make the four component scale params
|
||||
param = defineScaleParam(p_Desc, "scaleR", "red", "Scales the red component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(p_Desc, "scaleG", "green", "Scales the green component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(p_Desc, "scaleB", "blue", "Scales the blue component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(p_Desc, "scaleA", "alpha", "Scales the alpha component of the image", componentScalesGroup);
|
||||
page->addChild(*param);
|
||||
}
|
||||
|
||||
ImageEffect* GPUGainFactory::createInstance(OfxImageEffectHandle p_Handle, ContextEnum /*p_Context*/)
|
||||
{
|
||||
return new GPUGain(p_Handle);
|
||||
}
|
||||
|
||||
void OFX::Plugin::getPluginIDs(PluginFactoryArray& p_FactoryArray)
|
||||
{
|
||||
static GPUGainFactory gainPlugin;
|
||||
p_FactoryArray.push_back(&gainPlugin);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ofxsImageEffect.h"
|
||||
|
||||
class GPUGainFactory : public OFX::PluginFactoryHelper<GPUGainFactory>
|
||||
{
|
||||
public:
|
||||
GPUGainFactory();
|
||||
virtual void load() {}
|
||||
virtual void unload() {}
|
||||
virtual void describe(OFX::ImageEffectDescriptor& p_Desc);
|
||||
virtual void describeInContext(OFX::ImageEffectDescriptor& p_Desc, OFX::ContextEnum p_Context);
|
||||
virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle p_Handle, OFX::ContextEnum p_Context);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.40629.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPUGain", "GPUGain.vcxproj", "{88405F0E-918E-4523-8627-1380BC83A605}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{88405F0E-918E-4523-8627-1380BC83A605}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{88405F0E-918E-4523-8627-1380BC83A605}.Debug|x64.Build.0 = Debug|x64
|
||||
{88405F0E-918E-4523-8627-1380BC83A605}.Release|x64.ActiveCfg = Release|x64
|
||||
{88405F0E-918E-4523-8627-1380BC83A605}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{88405F0E-918E-4523-8627-1380BC83A605}</ProjectGuid>
|
||||
<RootNamespace>GPUGain</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 8.0.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(CUDA_INC_PATH);$(AMDAPPSDKROOT)/include;../OpenFX-1.4/include;../Support/include</IncludePath>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(CUDA_LIB_PATH);$(AMDAPPSDKROOT)/lib/x86_64</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(CUDA_INC_PATH);$(AMDAPPSDKROOT)/include;../OpenFX-1.4/include;../Support/include</IncludePath>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(CUDA_LIB_PATH);$(AMDAPPSDKROOT)/lib/x86_64</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PreBuildEvent>
|
||||
<Command />
|
||||
</PreBuildEvent>
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;cuda.lib;cudart.lib;OpenCL.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Message>Creating bundle...</Message>
|
||||
<Command>if not exist "$(OutDir)GPUGain.ofx.bundle\Contents\Resources" mkdir "$(OutDir)GPUGain.ofx.bundle\Contents\Resources"
|
||||
if not exist "$(OutDir)GPUGain.ofx.bundle\Contents\Win64" mkdir "$(OutDir)GPUGain.ofx.bundle\Contents\Win64"
|
||||
copy /Y "$(TargetPath)" /B "$(OutDir)GPUGain.ofx.bundle\Contents\Win64\GPUGain.ofx" /B
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CudaCompile>
|
||||
<TargetMachinePlatform>64</TargetMachinePlatform>
|
||||
</CudaCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;cuda.lib;cudart.lib;OpenCL.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Message>Creating bundle...</Message>
|
||||
<Command>if not exist "$(OutDir)GPUGain.ofx.bundle\Contents\Resources" mkdir "$(OutDir)GPUGain.ofx.bundle\Contents\Resources"
|
||||
if not exist "$(OutDir)GPUGain.ofx.bundle\Contents\Win64" mkdir "$(OutDir)GPUGain.ofx.bundle\Contents\Win64"
|
||||
copy /Y "$(TargetPath)" /B "$(OutDir)GPUGain.ofx.bundle\Contents\Win64\GPUGain.ofx" /B
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<CudaCompile>
|
||||
<TargetMachinePlatform>64</TargetMachinePlatform>
|
||||
</CudaCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\Support\Library\ofxsCore.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsImageEffect.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsInteract.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsLog.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsMultiThread.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsParams.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsProperty.cpp" />
|
||||
<ClCompile Include="..\Support\Library\ofxsPropertyValidation.cpp" />
|
||||
<ClCompile Include="GPUGain.cpp" />
|
||||
<ClCompile Include="OpenCLKernel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CudaCompile Include="CudaKernel.cu" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 8.0.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3DF51C6C1CB741110070CA48 /* CudaKernel.cu */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CudaKernel.cu; sourceTree = "<group>"; };
|
||||
3DF51C6D1CB741110070CA48 /* GPUGain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GPUGain.cpp; sourceTree = "<group>"; };
|
||||
3DF51C6E1CB741110070CA48 /* GPUGain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPUGain.h; sourceTree = "<group>"; };
|
||||
3DF51C701CB741110070CA48 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||
3DF51C711CB741110070CA48 /* OpenCLKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenCLKernel.cpp; sourceTree = "<group>"; };
|
||||
3DF51C721CB7413B0070CA48 /* ofxsCore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsCore.cpp; path = ../../Support/Library/ofxsCore.cpp; sourceTree = "<group>"; };
|
||||
3DF51C731CB7413B0070CA48 /* ofxsImageEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsImageEffect.cpp; path = ../../Support/Library/ofxsImageEffect.cpp; sourceTree = "<group>"; };
|
||||
3DF51C741CB7413B0070CA48 /* ofxsInteract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsInteract.cpp; path = ../../Support/Library/ofxsInteract.cpp; sourceTree = "<group>"; };
|
||||
3DF51C751CB7413B0070CA48 /* ofxsLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsLog.cpp; path = ../../Support/Library/ofxsLog.cpp; sourceTree = "<group>"; };
|
||||
3DF51C761CB7413B0070CA48 /* ofxsMultiThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsMultiThread.cpp; path = ../../Support/Library/ofxsMultiThread.cpp; sourceTree = "<group>"; };
|
||||
3DF51C771CB7413B0070CA48 /* ofxsParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsParams.cpp; path = ../../Support/Library/ofxsParams.cpp; sourceTree = "<group>"; };
|
||||
3DF51C781CB7413B0070CA48 /* ofxsProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsProperty.cpp; path = ../../Support/Library/ofxsProperty.cpp; sourceTree = "<group>"; };
|
||||
3DF51C791CB7413B0070CA48 /* ofxsPropertyValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ofxsPropertyValidation.cpp; path = ../../Support/Library/ofxsPropertyValidation.cpp; sourceTree = "<group>"; };
|
||||
4F799E1E1EC4662F00E46226 /* MetalKernel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalKernel.mm; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
3D2F26961CBB8F6B00FC8803 /* Support */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3DF51C721CB7413B0070CA48 /* ofxsCore.cpp */,
|
||||
3DF51C731CB7413B0070CA48 /* ofxsImageEffect.cpp */,
|
||||
3DF51C741CB7413B0070CA48 /* ofxsInteract.cpp */,
|
||||
3DF51C751CB7413B0070CA48 /* ofxsLog.cpp */,
|
||||
3DF51C761CB7413B0070CA48 /* ofxsMultiThread.cpp */,
|
||||
3DF51C771CB7413B0070CA48 /* ofxsParams.cpp */,
|
||||
3DF51C781CB7413B0070CA48 /* ofxsProperty.cpp */,
|
||||
3DF51C791CB7413B0070CA48 /* ofxsPropertyValidation.cpp */,
|
||||
);
|
||||
name = Support;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3DF51C611CB740BF0070CA48 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D2F26961CBB8F6B00FC8803 /* Support */,
|
||||
3DF51C6C1CB741110070CA48 /* CudaKernel.cu */,
|
||||
3DF51C6D1CB741110070CA48 /* GPUGain.cpp */,
|
||||
3DF51C6E1CB741110070CA48 /* GPUGain.h */,
|
||||
3DF51C701CB741110070CA48 /* Makefile */,
|
||||
3DF51C711CB741110070CA48 /* OpenCLKernel.cpp */,
|
||||
4F799E1E1EC4662F00E46226 /* MetalKernel.mm */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXLegacyTarget section */
|
||||
3DF51C661CB740BF0070CA48 /* GPUGain */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$(ACTION)";
|
||||
buildConfigurationList = 3DF51C691CB740BF0070CA48 /* Build configuration list for PBXLegacyTarget "GPUGain" */;
|
||||
buildPhases = (
|
||||
);
|
||||
buildToolPath = /usr/bin/make;
|
||||
dependencies = (
|
||||
);
|
||||
name = GPUGain;
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = GPUGain;
|
||||
};
|
||||
/* End PBXLegacyTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
3DF51C621CB740BF0070CA48 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0640;
|
||||
ORGANIZATIONNAME = blackmagicdesign;
|
||||
TargetAttributes = {
|
||||
3DF51C661CB740BF0070CA48 = {
|
||||
CreatedOnToolsVersion = 6.4;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 3DF51C651CB740BF0070CA48 /* Build configuration list for PBXProject "GPUGain" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = 3DF51C611CB740BF0070CA48;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
3DF51C661CB740BF0070CA48 /* GPUGain */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
3DF51C671CB740BF0070CA48 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3DF51C681CB740BF0070CA48 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
3DF51C6A1CB740BF0070CA48 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEBUGGING_SYMBOLS = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3DF51C6B1CB740BF0070CA48 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
3DF51C651CB740BF0070CA48 /* Build configuration list for PBXProject "GPUGain" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3DF51C671CB740BF0070CA48 /* Debug */,
|
||||
3DF51C681CB740BF0070CA48 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
3DF51C691CB740BF0070CA48 /* Build configuration list for PBXLegacyTarget "GPUGain" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3DF51C6A1CB740BF0070CA48 /* Debug */,
|
||||
3DF51C6B1CB740BF0070CA48 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 3DF51C621CB740BF0070CA48 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>GPUGain.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
const char* kernelSource = \
|
||||
"#include <metal_stdlib>\n" \
|
||||
"using namespace metal; \n" \
|
||||
"kernel void GainAdjustKernel(constant int& p_Width [[buffer (11)]], constant int& p_Height [[buffer (12)]], constant float& p_GainR [[buffer (13)]], \n" \
|
||||
" constant float& p_GainG [[buffer (14)]], constant float& p_GainB [[buffer (15)]], constant float& p_GainA [[buffer (16)]], \n" \
|
||||
" const device float* p_Input [[buffer (0)]], device float* p_Output [[buffer (8)]], uint2 id [[ thread_position_in_grid ]]) \n" \
|
||||
"{ \n" \
|
||||
" if ((id.x < p_Width) && (id.y < p_Height)) \n" \
|
||||
" { \n" \
|
||||
" const int index = ((id.y * p_Width) + id.x) * 4; \n" \
|
||||
" p_Output[index + 0] = p_Input[index + 0] * p_GainR; \n" \
|
||||
" p_Output[index + 1] = p_Input[index + 1] * p_GainG; \n" \
|
||||
" p_Output[index + 2] = p_Input[index + 2] * p_GainB; \n" \
|
||||
" p_Output[index + 3] = p_Input[index + 3] * p_GainA; \n" \
|
||||
" } \n" \
|
||||
"} \n";
|
||||
|
||||
std::mutex s_PipelineQueueMutex;
|
||||
typedef std::unordered_map<id<MTLCommandQueue>, id<MTLComputePipelineState>> PipelineQueueMap;
|
||||
PipelineQueueMap s_PipelineQueueMap;
|
||||
|
||||
void RunMetalKernel(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output)
|
||||
{
|
||||
const char* kernelName = "GainAdjustKernel";
|
||||
|
||||
id<MTLCommandQueue> queue = static_cast<id<MTLCommandQueue> >(p_CmdQ);
|
||||
id<MTLDevice> device = queue.device;
|
||||
id<MTLLibrary> metalLibrary; // Metal library
|
||||
id<MTLFunction> kernelFunction; // Compute kernel
|
||||
id<MTLComputePipelineState> pipelineState; // Metal pipeline
|
||||
NSError* err;
|
||||
|
||||
std::unique_lock<std::mutex> lock(s_PipelineQueueMutex);
|
||||
|
||||
const auto it = s_PipelineQueueMap.find(queue);
|
||||
if (it == s_PipelineQueueMap.end())
|
||||
{
|
||||
id<MTLLibrary> metalLibrary; // Metal library
|
||||
id<MTLFunction> kernelFunction; // Compute kernel
|
||||
NSError* err;
|
||||
|
||||
MTLCompileOptions* options = [MTLCompileOptions new];
|
||||
options.fastMathEnabled = YES;
|
||||
if (!(metalLibrary = [device newLibraryWithSource:@(kernelSource) options:options error:&err]))
|
||||
{
|
||||
fprintf(stderr, "Failed to load metal library, %s\n", err.localizedDescription.UTF8String);
|
||||
return;
|
||||
}
|
||||
[options release];
|
||||
if (!(kernelFunction = [metalLibrary newFunctionWithName:[NSString stringWithUTF8String:kernelName]/* constantValues : constantValues */]))
|
||||
{
|
||||
fprintf(stderr, "Failed to retrieve kernel\n");
|
||||
[metalLibrary release];
|
||||
return;
|
||||
}
|
||||
if (!(pipelineState = [device newComputePipelineStateWithFunction:kernelFunction error:&err]))
|
||||
{
|
||||
fprintf(stderr, "Unable to compile, %s\n", err.localizedDescription.UTF8String);
|
||||
[metalLibrary release];
|
||||
[kernelFunction release];
|
||||
return;
|
||||
}
|
||||
|
||||
s_PipelineQueueMap[queue] = pipelineState;
|
||||
|
||||
//Release resources
|
||||
[metalLibrary release];
|
||||
[kernelFunction release];
|
||||
}
|
||||
else
|
||||
{
|
||||
pipelineState = it->second;
|
||||
}
|
||||
|
||||
id<MTLBuffer> srcDeviceBuf = reinterpret_cast<id<MTLBuffer> >(const_cast<float *>(p_Input));
|
||||
id<MTLBuffer> dstDeviceBuf = reinterpret_cast<id<MTLBuffer> >(p_Output);
|
||||
|
||||
id<MTLCommandBuffer> commandBuffer = [queue commandBuffer];
|
||||
commandBuffer.label = [NSString stringWithFormat:@"GainAdjustKernel"];
|
||||
|
||||
id<MTLComputeCommandEncoder> computeEncoder = [commandBuffer computeCommandEncoder];
|
||||
[computeEncoder setComputePipelineState:pipelineState];
|
||||
|
||||
int exeWidth = [pipelineState threadExecutionWidth];
|
||||
MTLSize threadGroupCount = MTLSizeMake(exeWidth, 1, 1);
|
||||
MTLSize threadGroups = MTLSizeMake((p_Width + exeWidth - 1)/exeWidth, p_Height, 1);
|
||||
|
||||
[computeEncoder setBuffer:srcDeviceBuf offset: 0 atIndex: 0];
|
||||
[computeEncoder setBuffer:dstDeviceBuf offset: 0 atIndex: 8];
|
||||
[computeEncoder setBytes:&p_Width length:sizeof(int) atIndex:11];
|
||||
[computeEncoder setBytes:&p_Height length:sizeof(int) atIndex:12];
|
||||
[computeEncoder setBytes:&p_Gain[0] length:sizeof(float) atIndex:13];
|
||||
[computeEncoder setBytes:&p_Gain[1] length:sizeof(float) atIndex:14];
|
||||
[computeEncoder setBytes:&p_Gain[2] length:sizeof(float) atIndex:15];
|
||||
[computeEncoder setBytes:&p_Gain[3] length:sizeof(float) atIndex:16];
|
||||
|
||||
[computeEncoder dispatchThreadgroups:threadGroups threadsPerThreadgroup: threadGroupCount];
|
||||
|
||||
[computeEncoder endEncoding];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
const char *KernelSourceBuffers = "\n" \
|
||||
"__kernel void GainAdjustKernelBuffers( \n" \
|
||||
" int p_Width, \n" \
|
||||
" int p_Height, \n" \
|
||||
" float p_GainR, \n" \
|
||||
" float p_GainG, \n" \
|
||||
" float p_GainB, \n" \
|
||||
" float p_GainA, \n" \
|
||||
" __global const float* p_Input, \n" \
|
||||
" __global float* p_Output) \n" \
|
||||
"{ \n" \
|
||||
" const int x = get_global_id(0); \n" \
|
||||
" const int y = get_global_id(1); \n" \
|
||||
" \n" \
|
||||
" if ((x < p_Width) && (y < p_Height)) \n" \
|
||||
" { \n" \
|
||||
" const int index = ((y * p_Width) + x) * 4; \n" \
|
||||
" \n" \
|
||||
" p_Output[index + 0] = p_Input[index + 0] * p_GainR; \n" \
|
||||
" p_Output[index + 1] = p_Input[index + 1] * p_GainG; \n" \
|
||||
" p_Output[index + 2] = p_Input[index + 2] * p_GainB; \n" \
|
||||
" p_Output[index + 3] = p_Input[index + 3] * p_GainA; \n" \
|
||||
" } \n" \
|
||||
"} \n" \
|
||||
"\n";
|
||||
|
||||
const char *KernelSourceImages = "\n" \
|
||||
"__constant sampler_t imageSampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; \n" \
|
||||
" \n" \
|
||||
"__kernel void GainAdjustKernelImages( \n" \
|
||||
" int p_Width, \n" \
|
||||
" int p_Height, \n" \
|
||||
" float p_GainR, \n" \
|
||||
" float p_GainG, \n" \
|
||||
" float p_GainB, \n" \
|
||||
" float p_GainA, \n" \
|
||||
" __read_only image2d_t p_Input, \n" \
|
||||
" __write_only image2d_t p_Output) \n" \
|
||||
"{ \n" \
|
||||
" const int x = get_global_id(0); \n" \
|
||||
" const int y = get_global_id(1); \n" \
|
||||
" \n" \
|
||||
" if ((x < p_Width) && (y < p_Height)) \n" \
|
||||
" { \n" \
|
||||
" int2 coord = (int2)(x, y); \n" \
|
||||
" float4 out = read_imagef(p_Input, imageSampler, coord); \n" \
|
||||
" out *= (float4)(p_GainR, p_GainG, p_GainB, p_GainA); \n" \
|
||||
" write_imagef(p_Output, coord, out); \n" \
|
||||
" } \n" \
|
||||
"} \n" \
|
||||
"\n";
|
||||
|
||||
void CheckError(cl_int p_Error, const char* p_Msg)
|
||||
{
|
||||
if (p_Error != CL_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "%s [%d]\n", p_Msg, p_Error);
|
||||
}
|
||||
}
|
||||
|
||||
class Locker
|
||||
{
|
||||
public:
|
||||
Locker()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
InitializeCriticalSection(&mutex);
|
||||
#else
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
~Locker()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
DeleteCriticalSection(&mutex);
|
||||
#else
|
||||
pthread_mutex_destroy(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
EnterCriticalSection(&mutex);
|
||||
#else
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
LeaveCriticalSection(&mutex);
|
||||
#else
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef _WIN64
|
||||
CRITICAL_SECTION mutex;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
void RunOpenCLKernelBuffers(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output)
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
cl_command_queue cmdQ = static_cast<cl_command_queue>(p_CmdQ);
|
||||
|
||||
// store device id and kernel per command queue (required for multi-GPU systems)
|
||||
static std::map<cl_command_queue, cl_device_id> deviceIdMap;
|
||||
static std::map<cl_command_queue, cl_kernel> kernelMap;
|
||||
|
||||
static Locker locker; // simple lock to control access to the above maps from multiple threads
|
||||
|
||||
locker.Lock();
|
||||
|
||||
// find the device id corresponding to the command queue
|
||||
cl_device_id deviceId = NULL;
|
||||
if (deviceIdMap.find(cmdQ) == deviceIdMap.end())
|
||||
{
|
||||
error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_DEVICE, sizeof(cl_device_id), &deviceId, NULL);
|
||||
CheckError(error, "Unable to get the device");
|
||||
|
||||
deviceIdMap[cmdQ] = deviceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceId = deviceIdMap[cmdQ];
|
||||
}
|
||||
|
||||
// find the program kernel corresponding to the command queue
|
||||
cl_kernel kernel = NULL;
|
||||
if (kernelMap.find(cmdQ) == kernelMap.end())
|
||||
{
|
||||
cl_context clContext = NULL;
|
||||
error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_CONTEXT, sizeof(cl_context), &clContext, NULL);
|
||||
CheckError(error, "Unable to get the context");
|
||||
|
||||
cl_program program = clCreateProgramWithSource(clContext, 1, (const char **)&KernelSourceBuffers, NULL, &error);
|
||||
CheckError(error, "Unable to create program");
|
||||
|
||||
error = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
|
||||
CheckError(error, "Unable to build program");
|
||||
|
||||
kernel = clCreateKernel(program, "GainAdjustKernelBuffers", &error);
|
||||
CheckError(error, "Unable to create kernel");
|
||||
|
||||
kernelMap[cmdQ] = kernel;
|
||||
}
|
||||
else
|
||||
{
|
||||
kernel = kernelMap[cmdQ];
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
int count = 0;
|
||||
error = clSetKernelArg(kernel, count++, sizeof(int), &p_Width);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(int), &p_Height);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[0]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[1]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[2]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[3]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Input);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Output);
|
||||
CheckError(error, "Unable to set kernel arguments");
|
||||
|
||||
size_t localWorkSize[2], globalWorkSize[2];
|
||||
clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), localWorkSize, NULL);
|
||||
localWorkSize[1] = 1;
|
||||
globalWorkSize[0] = ((p_Width + localWorkSize[0] - 1) / localWorkSize[0]) * localWorkSize[0];
|
||||
globalWorkSize[1] = p_Height;
|
||||
|
||||
clEnqueueNDRangeKernel(cmdQ, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
void RunOpenCLKernelImages(void* p_CmdQ, int p_Width, int p_Height, float* p_Gain, const float* p_Input, float* p_Output)
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
cl_command_queue cmdQ = static_cast<cl_command_queue>(p_CmdQ);
|
||||
|
||||
// store device id and kernel per command queue (required for multi-GPU systems)
|
||||
static std::map<cl_command_queue, cl_device_id> deviceIdMap;
|
||||
static std::map<cl_command_queue, cl_kernel> kernelMap;
|
||||
|
||||
static Locker locker; // simple lock to control access to the above maps from multiple threads
|
||||
|
||||
locker.Lock();
|
||||
|
||||
// find the device id corresponding to the command queue
|
||||
cl_device_id deviceId = NULL;
|
||||
if (deviceIdMap.find(cmdQ) == deviceIdMap.end())
|
||||
{
|
||||
error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_DEVICE, sizeof(cl_device_id), &deviceId, NULL);
|
||||
CheckError(error, "Unable to get the device");
|
||||
|
||||
deviceIdMap[cmdQ] = deviceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceId = deviceIdMap[cmdQ];
|
||||
}
|
||||
|
||||
// find the program kernel corresponding to the command queue
|
||||
cl_kernel kernel = NULL;
|
||||
if (kernelMap.find(cmdQ) == kernelMap.end())
|
||||
{
|
||||
cl_context clContext = NULL;
|
||||
error = clGetCommandQueueInfo(cmdQ, CL_QUEUE_CONTEXT, sizeof(cl_context), &clContext, NULL);
|
||||
CheckError(error, "Unable to get the context");
|
||||
|
||||
cl_program program = clCreateProgramWithSource(clContext, 1, (const char **)&KernelSourceImages, NULL, &error);
|
||||
CheckError(error, "Unable to create program");
|
||||
|
||||
error = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
|
||||
CheckError(error, "Unable to build program");
|
||||
|
||||
kernel = clCreateKernel(program, "GainAdjustKernelImages", &error);
|
||||
CheckError(error, "Unable to create kernel");
|
||||
|
||||
kernelMap[cmdQ] = kernel;
|
||||
}
|
||||
else
|
||||
{
|
||||
kernel = kernelMap[cmdQ];
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
int count = 0;
|
||||
error = clSetKernelArg(kernel, count++, sizeof(int), &p_Width);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(int), &p_Height);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[0]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[1]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[2]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(float), &p_Gain[3]);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Input);
|
||||
error |= clSetKernelArg(kernel, count++, sizeof(cl_mem), &p_Output);
|
||||
CheckError(error, "Unable to set kernel arguments");
|
||||
|
||||
size_t localWorkSize[2], globalWorkSize[2];
|
||||
clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), localWorkSize, NULL);
|
||||
localWorkSize[1] = 1;
|
||||
globalWorkSize[0] = ((p_Width + localWorkSize[0] - 1) / localWorkSize[0]) * localWorkSize[0];
|
||||
globalWorkSize[1] = p_Height;
|
||||
|
||||
clEnqueueNDRangeKernel(cmdQ, kernel, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>noise.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,293 @@
|
||||
|
||||
|
||||
#include <limits>
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
#include <random>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// base class for the noise
|
||||
|
||||
/** @brief Base class used to blend two images together */
|
||||
class NoiseGeneratorBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
float _noiseLevel; // how much to blend
|
||||
uint32_t _seed; // base seed
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
NoiseGeneratorBase(OFX::ImageEffect &instance)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _noiseLevel(0.5f)
|
||||
, _seed(0)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the scale */
|
||||
void setNoiseLevel(float v) {_noiseLevel = v;}
|
||||
|
||||
/** @brief the seed to use */
|
||||
void setSeed(uint32_t v) {_seed = v;}
|
||||
};
|
||||
|
||||
/** @brief templated class to blend between two images */
|
||||
template <class PIX, int nComponents, int max>
|
||||
class NoiseGenerator : public NoiseGeneratorBase {
|
||||
public :
|
||||
// ctor
|
||||
NoiseGenerator(OFX::ImageEffect &instance)
|
||||
: NoiseGeneratorBase(instance)
|
||||
{}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float noiseLevel = _noiseLevel;
|
||||
|
||||
// set up a random number generator
|
||||
// Distribution is from 0 to pixel max level times noise level
|
||||
std::random_device rd;
|
||||
std::mt19937_64 mt(rd());
|
||||
mt.seed(_seed + procWindow.y1);
|
||||
std::uniform_real_distribution<double> dist(0.0, max * noiseLevel);
|
||||
|
||||
// push pixels
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
double randValue = dist(mt);
|
||||
|
||||
if(max == 1) // implies floating point, so don't clamp
|
||||
dstPix[c] = PIX(randValue);
|
||||
else { // integer base one, clamp it
|
||||
dstPix[c] = randValue < 0 ? 0 : (randValue > max ? max : PIX(randValue));
|
||||
}
|
||||
}
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class NoisePlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
|
||||
OFX::DoubleParam *noise_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
NoisePlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, noise_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
noise_ = fetchDoubleParam("Noise");
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* Override the clip preferences, we need to say we are setting the frame varying flag */
|
||||
virtual void getClipPreferences(OFX::ClipPreferencesSetter &clipPreferences);
|
||||
|
||||
/* set up and run a processor */
|
||||
void setupAndProcess(NoiseGeneratorBase &, const OFX::RenderArguments &args);
|
||||
|
||||
/** @brief The get RoD action. We flag an infinite rod */
|
||||
bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
NoisePlugin::setupAndProcess(NoiseGeneratorBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
//OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
//OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// set the scales
|
||||
processor.setNoiseLevel((float)noise_->getValueAtTime(args.time));
|
||||
|
||||
// set the seed based on the current time, and double it we get difference seeds on different fields
|
||||
processor.setSeed(uint32_t(args.time * 2.0f + 2000.0f));
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
/* Override the clip preferences, we need to say we are setting the frame varying flag */
|
||||
void
|
||||
NoisePlugin::getClipPreferences(OFX::ClipPreferencesSetter &clipPreferences)
|
||||
{
|
||||
clipPreferences.setOutputFrameVarying(true);
|
||||
}
|
||||
|
||||
/** @brief The get RoD action. We flag an infinite rod */
|
||||
bool
|
||||
NoisePlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &/*args*/, OfxRectD &rod)
|
||||
{
|
||||
// we can generate noise anywhere on the image plan, so set our RoD to be infinite
|
||||
rod.x1 = rod.y1 = kOfxFlagInfiniteMin;
|
||||
rod.x2 = rod.y2 = kOfxFlagInfiniteMax;
|
||||
return true;
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
NoisePlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte : {
|
||||
NoiseGenerator<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
NoiseGenerator<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
NoiseGenerator<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
NoiseGenerator<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
NoiseGenerator<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
NoiseGenerator<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mDeclarePluginFactory(NoiseExamplePluginFactory, {}, {});
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
void NoiseExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
desc.setLabels("Noise", "Noise", "Noise");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
desc.addSupportedContext(eContextGenerator);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
}
|
||||
|
||||
void NoiseExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum /*context*/)
|
||||
{
|
||||
// there has to be an input clip, even for generators
|
||||
ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
|
||||
srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
|
||||
srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setOptional(true);
|
||||
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
dstClip->setFieldExtraction(eFieldExtractSingle);
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam("Noise");
|
||||
param->setLabels("noise", "noise", "noise");
|
||||
param->setScriptName("noise");
|
||||
param->setHint("How much noise to make.");
|
||||
param->setDefault(0.2);
|
||||
param->setRange(0, 10);
|
||||
param->setIncrement(0.1);
|
||||
param->setDisplayRange(0, 1);
|
||||
param->setAnimates(true); // can animate
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
page->addChild(*param);
|
||||
}
|
||||
|
||||
ImageEffect* NoiseExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
|
||||
{
|
||||
return new NoisePlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static NoiseExamplePluginFactory p("net.sf.openfx.noisePlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
};
|
||||
};
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
# Microsoft Developer Studio Project File - Name="noise" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=noise - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "noise.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "noise.mak" CFG="noise - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "noise - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "noise - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "noise - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/noise.ofx"
|
||||
|
||||
!ELSEIF "$(CFG)" == "noise - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\Noise.ofx.bundle\Contents\Win32\noise.ofx" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "noise - Win32 Release"
|
||||
# Name "noise - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\noise.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\randomGenerator.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "noise"=.\noise.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name ofxsupport
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+472
@@ -0,0 +1,472 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="noise"
|
||||
ProjectGUID="{F14EBC69-3767-44B1-A28C-326B59350C7F}"
|
||||
RootNamespace="noise"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="randomGenerator.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\randomGenerator.H"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>invert.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,257 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
|
||||
// Base class for the RGBA and the Alpha processor
|
||||
class InvertBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
InvertBase(OFX::ImageEffect &instance)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _srcImg(0)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the src image */
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
};
|
||||
|
||||
// template to do the RGBA processing
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageInverter : public InvertBase {
|
||||
public :
|
||||
// ctor
|
||||
ImageInverter(OFX::ImageEffect &instance)
|
||||
: InvertBase(instance)
|
||||
{}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
// do we have a source image to scale up
|
||||
if(srcPix) {
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
dstPix[c] = max - srcPix[c];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no src pixel here, be black and transparent
|
||||
for(int c = 0; c < nComponents; c++) {
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// increment the dst pixel
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class InvertPlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
InvertPlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, srcClip_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* set up and run a processor */
|
||||
void setupAndProcess(InvertBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
InvertPlugin::setupAndProcess(InvertBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// fetch main input image
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(src.get()) {
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
InvertPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageInverter<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageInverter<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageInverter<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
ImageInverter<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
ImageInverter<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
ImageInverter<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mDeclarePluginFactory(InvertExamplePluginFactory, {}, {});
|
||||
|
||||
using namespace OFX;
|
||||
void InvertExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Invert", "Invert", "Invert");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// add the supported contexts, only filter at the moment
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
|
||||
// add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
|
||||
}
|
||||
|
||||
void InvertExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
// Source clip only in the filter context
|
||||
// create the mandated source clip
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
}
|
||||
|
||||
OFX::ImageEffect* InvertExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
return new InvertPlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static InvertExamplePluginFactory p("net.sf.openfx.invertPlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="invert"
|
||||
ProjectGUID="{F14E0B89-3767-88B1-A28C-326B0B350C7E}"
|
||||
RootNamespace="invert"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="invert.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>multibundle.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "multibundle1.h"
|
||||
#include "multibundle2.h"
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static DotExamplePluginFactory p1;
|
||||
ids.push_back(&p1);
|
||||
static GammaExamplePluginFactory p2;
|
||||
ids.push_back(&p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="MultiBundle"
|
||||
ProjectGUID="{F14ECC69-3767-44B1-A28C-32FB09F50C7E}"
|
||||
RootNamespace="MultiBundle"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\multibundle1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\multibundle2.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\PluginRegistration.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\multibundle1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\multibundle2.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
+529
@@ -0,0 +1,529 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
#include "multibundle1.h"
|
||||
|
||||
static const OfxPointD kBoxSize = {20, 20};
|
||||
class GammaInteract : public OFX::OverlayInteract
|
||||
{
|
||||
protected :
|
||||
enum StateEnum {
|
||||
eInActive,
|
||||
ePoised,
|
||||
ePicked
|
||||
};
|
||||
OfxPointD _position;
|
||||
StateEnum _state;
|
||||
public :
|
||||
GammaInteract(OfxInteractHandle handle, OFX::ImageEffect* /*effect*/) : OFX::OverlayInteract(handle), _state(eInActive)
|
||||
{
|
||||
_position.x = 0;
|
||||
_position.y = 0;
|
||||
}
|
||||
virtual bool draw(const OFX::DrawArgs &args);
|
||||
virtual bool penMotion(const OFX::PenArgs &args);
|
||||
virtual bool penDown(const OFX::PenArgs &args);
|
||||
virtual bool penUp(const OFX::PenArgs &args);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T Absolute(T a)
|
||||
{
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T Clamp(T v, int min, int max)
|
||||
{
|
||||
if(v < T(min))
|
||||
return T(min);
|
||||
if(v > T(max))
|
||||
return T(max);
|
||||
return v;
|
||||
}
|
||||
|
||||
class ImageScalerBase : public OFX::ImageProcessor
|
||||
{
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
OFX::Image *_maskImg;
|
||||
double _rScale, _gScale, _bScale, _aScale;
|
||||
bool _doMasking;
|
||||
|
||||
public :
|
||||
ImageScalerBase(OFX::ImageEffect &instance): OFX::ImageProcessor(instance), _srcImg(0), _maskImg(0),
|
||||
_rScale(1), _gScale(1), _bScale(1), _aScale(1), _doMasking(false)
|
||||
{
|
||||
}
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
void setMaskImg(OFX::Image *v) {_maskImg = v;}
|
||||
void doMasking(bool v) {_doMasking = v;}
|
||||
void setScales(float r, float g, float b, float a)
|
||||
{
|
||||
_rScale = r;
|
||||
_gScale = g;
|
||||
_bScale = b;
|
||||
_aScale = a;
|
||||
}
|
||||
};
|
||||
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageScaler : public ImageScalerBase
|
||||
{
|
||||
public :
|
||||
ImageScaler(OFX::ImageEffect &instance): ImageScalerBase(instance)
|
||||
{}
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float scales[4];
|
||||
scales[0] = nComponents == 1 ? (float)_aScale : (float)_rScale;
|
||||
scales[1] = (float)_gScale;
|
||||
scales[2] = (float)_bScale;
|
||||
scales[3] = (float)_aScale;
|
||||
float maskScale = 1.0f;
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++)
|
||||
{
|
||||
if(_effect.abort())
|
||||
break;
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++)
|
||||
{
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
if(_doMasking)
|
||||
{
|
||||
if(!_maskImg)
|
||||
maskScale = 1.0f;
|
||||
else
|
||||
{
|
||||
PIX *maskPix = (PIX *) (_maskImg ? _maskImg->getPixelAddress(x, y) : 0);
|
||||
maskScale = maskPix != 0 ? float(*maskPix)/float(max) : 0.0f;
|
||||
}
|
||||
}
|
||||
if(srcPix)
|
||||
{
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
{
|
||||
float v = (float)(pow((double)srcPix[c], (double)scales[c])) * maskScale + (1.0f - maskScale) * srcPix[c];
|
||||
if(max == 1)
|
||||
dstPix[c] = PIX(v);
|
||||
else
|
||||
dstPix[c] = PIX(Clamp(v, 0, max));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GammaPlugin : public OFX::ImageEffect
|
||||
{
|
||||
protected :
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
OFX::Clip *maskClip_;
|
||||
OFX::DoubleParam *scale_;
|
||||
OFX::DoubleParam *rScale_;
|
||||
OFX::DoubleParam *gScale_;
|
||||
OFX::DoubleParam *bScale_;
|
||||
OFX::DoubleParam *aScale_;
|
||||
OFX::BooleanParam *componentScalesEnabled_;
|
||||
public :
|
||||
GammaPlugin(OfxImageEffectHandle handle): ImageEffect(handle), dstClip_(0), srcClip_(0), scale_(0)
|
||||
, rScale_(0), gScale_(0), bScale_(0), aScale_(0), componentScalesEnabled_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
maskClip_ = getContext() == OFX::eContextFilter ? NULL : fetchClip(getContext() == OFX::eContextPaint ? "Brush" : "Mask");
|
||||
scale_ = fetchDoubleParam("scale");
|
||||
rScale_ = fetchDoubleParam("scaleR");
|
||||
gScale_ = fetchDoubleParam("scaleG");
|
||||
bScale_ = fetchDoubleParam("scaleB");
|
||||
aScale_ = fetchDoubleParam("scaleA");
|
||||
componentScalesEnabled_ = fetchBooleanParam("scaleComponents");
|
||||
setEnabledness();
|
||||
}
|
||||
void setEnabledness();
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime);
|
||||
virtual void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName);
|
||||
virtual void changedClip(const OFX::InstanceChangedArgs &args, const std::string &clipName);
|
||||
virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod);
|
||||
virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois);
|
||||
void setupAndProcess(ImageScalerBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
void GammaPlugin::setupAndProcess(ImageScalerBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
if(src.get())
|
||||
{
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1);
|
||||
}
|
||||
std::unique_ptr<OFX::Image> mask;
|
||||
if(getContext() != OFX::eContextFilter)
|
||||
{
|
||||
mask.reset(maskClip_->fetchImage(args.time));
|
||||
processor.doMasking(true);
|
||||
processor.setMaskImg(mask.get());
|
||||
}
|
||||
double r, g, b, a = aScale_->getValueAtTime(args.time);
|
||||
r = g = b = scale_->getValueAtTime(args.time);
|
||||
if(componentScalesEnabled_->getValueAtTime(args.time))
|
||||
{
|
||||
r += rScale_->getValueAtTime(args.time);
|
||||
g += gScale_->getValueAtTime(args.time);
|
||||
b += bScale_->getValueAtTime(args.time);
|
||||
}
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
processor.setScales((float)r, (float)g, (float)b, (float)a);
|
||||
processor.process();
|
||||
}
|
||||
|
||||
bool GammaPlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod)
|
||||
{
|
||||
rod = srcClip_->getRegionOfDefinition(args.time);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GammaPlugin::getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois)
|
||||
{
|
||||
rois.setRegionOfInterest(*srcClip_, args.regionOfInterest);
|
||||
if(getContext() != OFX::eContextFilter)
|
||||
rois.setRegionOfInterest(*maskClip_, args.regionOfInterest);
|
||||
}
|
||||
|
||||
void GammaPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
if(dstComponents == OFX::ePixelComponentRGBA)
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageScaler<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageScaler<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageScaler<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageScaler<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageScaler<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageScaler<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GammaPlugin:: isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime)
|
||||
{
|
||||
double scale = scale_->getValueAtTime(args.time);
|
||||
double rScale = 1, gScale = 1, bScale = 1, aScale = 1;
|
||||
if(componentScalesEnabled_->getValueAtTime(args.time)) {
|
||||
rScale = rScale_->getValueAtTime(args.time);
|
||||
gScale = gScale_->getValueAtTime(args.time);
|
||||
bScale = bScale_->getValueAtTime(args.time);
|
||||
aScale = aScale_->getValueAtTime(args.time);
|
||||
}
|
||||
rScale += scale;
|
||||
gScale += scale;
|
||||
bScale += scale;
|
||||
if(rScale == 1 && gScale == 1 && bScale == 1 && aScale == 1) {
|
||||
identityClip = srcClip_;
|
||||
identityTime = args.time;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GammaPlugin::setEnabledness(void)
|
||||
{
|
||||
bool v = componentScalesEnabled_->getValue() && srcClip_->getPixelComponents() == OFX::ePixelComponentRGBA;
|
||||
rScale_->setEnabled(v);
|
||||
gScale_->setEnabled(v);
|
||||
bScale_->setEnabled(v);
|
||||
aScale_->setEnabled(v);
|
||||
}
|
||||
|
||||
void GammaPlugin::changedParam(const OFX::InstanceChangedArgs &/*args*/, const std::string ¶mName)
|
||||
{
|
||||
if(paramName == "scaleComponents")
|
||||
setEnabledness();
|
||||
}
|
||||
|
||||
void GammaPlugin::changedClip(const OFX::InstanceChangedArgs &/*args*/, const std::string &clipName)
|
||||
{
|
||||
if(clipName == kOfxImageEffectSimpleSourceClipName)
|
||||
setEnabledness();
|
||||
}
|
||||
|
||||
bool GammaInteract::draw(const OFX::DrawArgs &args)
|
||||
{
|
||||
OfxRGBColourF col;
|
||||
switch(_state) {
|
||||
case eInActive :
|
||||
col.r = col.g = col.b = 0.0f;
|
||||
break;
|
||||
case ePoised :
|
||||
col.r = col.g = col.b = 0.5f;
|
||||
break;
|
||||
case ePicked :
|
||||
col.r = col.g = col.b = 1.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
glPushMatrix();
|
||||
glColor3f(col.r, col.g, col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b);
|
||||
glTranslated(_position.x, _position.y, 0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GammaInteract::penMotion(const OFX::PenArgs &args)
|
||||
{
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
OfxPointD penPos = args.penPosition;
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive :
|
||||
case ePoised :
|
||||
{
|
||||
StateEnum newState;
|
||||
penPos.x -= _position.x;
|
||||
penPos.y -= _position.y;
|
||||
if(Absolute(penPos.x) < dx && Absolute(penPos.y) < dy)
|
||||
{
|
||||
newState = ePoised;
|
||||
}
|
||||
else
|
||||
{
|
||||
newState = eInActive;
|
||||
}
|
||||
|
||||
if(_state != newState)
|
||||
{
|
||||
_state = newState;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ePicked :
|
||||
{
|
||||
_position = penPos;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return _state != eInActive;
|
||||
}
|
||||
|
||||
bool GammaInteract::penDown(const OFX::PenArgs &args)
|
||||
{
|
||||
penMotion(args);
|
||||
if(_state == ePoised)
|
||||
{
|
||||
_state = ePicked;
|
||||
_position = args.penPosition;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
return _state == ePicked;
|
||||
}
|
||||
|
||||
bool GammaInteract::penUp(const OFX::PenArgs &args)
|
||||
{
|
||||
if(_state == ePicked)
|
||||
{
|
||||
_state = ePoised;
|
||||
penMotion(args);
|
||||
_effect->redrawOverlays();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
class GammaOverlayDescriptor : public DefaultEffectOverlayDescriptor<GammaOverlayDescriptor, GammaInteract> {};
|
||||
|
||||
void GammaExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
desc.setLabels("Gamma", "Gamma", "Gamma");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
desc.addSupportedContext(eContextPaint);
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
desc.setOverlayInteractDescriptor( new GammaOverlayDescriptor );
|
||||
}
|
||||
|
||||
static
|
||||
DoubleParamDescriptor *defineScaleParam(OFX::ImageEffectDescriptor &desc,
|
||||
const std::string &name, const std::string &label, const std::string &hint,
|
||||
GroupParamDescriptor *parent, double def = 1.0)
|
||||
{
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam(name);
|
||||
param->setLabels(label, label, label);
|
||||
param->setScriptName(name);
|
||||
param->setHint(hint);
|
||||
param->setDefault(def);
|
||||
param->setRange(0, 10);
|
||||
param->setIncrement(0.1);
|
||||
param->setDisplayRange(0, 10);
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
if(parent)
|
||||
param->setParent(*parent);
|
||||
return param;
|
||||
}
|
||||
|
||||
void GammaExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context)
|
||||
{
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
if(context == eContextGeneral || context == eContextPaint)
|
||||
{
|
||||
ClipDescriptor *maskClip = context == eContextGeneral ? desc.defineClip("Mask") : desc.defineClip("Brush");
|
||||
maskClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
maskClip->setTemporalClipAccess(false);
|
||||
if(context == eContextGeneral)
|
||||
maskClip->setOptional(true);
|
||||
maskClip->setSupportsTiles(true);
|
||||
maskClip->setIsMask(true);
|
||||
}
|
||||
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
|
||||
GroupParamDescriptor *componentScalesGroup = desc.defineGroupParam("componentScales");
|
||||
componentScalesGroup->setHint("Scales on the individual component");
|
||||
componentScalesGroup->setLabels("Components", "Components", "Components");
|
||||
|
||||
DoubleParamDescriptor *param = defineScaleParam(desc, "scale", "scale", "Scales all component in the image", 0, 1.0);
|
||||
page->addChild(*param);
|
||||
|
||||
BooleanParamDescriptor *boolP = desc.defineBooleanParam("scaleComponents");
|
||||
boolP->setDefault(true);
|
||||
boolP->setHint("Enables gamma correction on individual components");
|
||||
boolP->setLabels("Gamma Components", "Gamma Components", "Gamma Components");
|
||||
boolP->setParent(*componentScalesGroup);
|
||||
page->addChild(*boolP);
|
||||
|
||||
param = defineScaleParam(desc, "scaleR", "red", "Gamma corrects the red component of the image", componentScalesGroup, 0.0);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleG", "green", "Gamma corrects the green component of the image", componentScalesGroup, 0.0);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleB", "blue", "Gamma corrects the blue component of the image", componentScalesGroup, 0.0);
|
||||
page->addChild(*param);
|
||||
|
||||
param = defineScaleParam(desc, "scaleA", "alpha", "Gamma corrects the alpha component of the image", componentScalesGroup, 0.0);
|
||||
page->addChild(*param);
|
||||
|
||||
}
|
||||
|
||||
ImageEffect* GammaExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
return new GammaPlugin(handle);
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#include "ofxsCore.h"
|
||||
|
||||
class GammaExamplePluginFactory : public OFX::PluginFactoryHelper<GammaExamplePluginFactory>
|
||||
{
|
||||
public:
|
||||
GammaExamplePluginFactory():OFX::PluginFactoryHelper<GammaExamplePluginFactory>("net.sf.openfx.gammaexample", 1, 0){}
|
||||
virtual void describe(OFX::ImageEffectDescriptor &desc);
|
||||
virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context);
|
||||
virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
#include "multibundle2.h"
|
||||
|
||||
static const OfxPointD kBoxSize = {20, 20};
|
||||
|
||||
class DotExampleInteract : public OFX::OverlayInteract
|
||||
{
|
||||
protected :
|
||||
enum StateEnum {
|
||||
eInActive,
|
||||
ePoised,
|
||||
ePicked
|
||||
};
|
||||
StateEnum _state;
|
||||
OFX::Double2DParam* position_;
|
||||
public :
|
||||
DotExampleInteract(OfxInteractHandle handle, OFX::ImageEffect* effect) : OFX::OverlayInteract(handle), _state(eInActive)
|
||||
{
|
||||
position_ = effect->fetchDouble2DParam("position");
|
||||
}
|
||||
virtual bool draw(const OFX::DrawArgs &args);
|
||||
virtual bool penMotion(const OFX::PenArgs &args);
|
||||
virtual bool penDown(const OFX::PenArgs &args);
|
||||
virtual bool penUp(const OFX::PenArgs &args);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T Absolute(T a)
|
||||
{
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
class DotGeneratorBase : public OFX::ImageProcessor
|
||||
{
|
||||
public :
|
||||
DotGeneratorBase(OFX::ImageEffect &instance) : OFX::ImageProcessor(instance), _radius(0.0f), _positionx(0.0f), _positiony(0.0f)
|
||||
{
|
||||
_colour[0] = _colour[1] = _colour[2] = _colour[3] = 0;
|
||||
}
|
||||
void setRadius(float v) { _radius = v; }
|
||||
void setR(float v) { _colour[0] = v;}
|
||||
void setG(float v) { _colour[1] = v;}
|
||||
void setB(float v) { _colour[2] = v;}
|
||||
void setA(float v) { _colour[3] = v;}
|
||||
void setColour(double r, double g, double b, double a)
|
||||
{
|
||||
setR((float)r);
|
||||
setG((float)g);
|
||||
setB((float)b);
|
||||
setA((float)a);
|
||||
}
|
||||
void setPosition(float x, float y)
|
||||
{
|
||||
_positionx = x;
|
||||
_positiony = y;
|
||||
}
|
||||
protected:
|
||||
float _radius;
|
||||
float _colour[4];
|
||||
float _positionx;
|
||||
float _positiony;
|
||||
};
|
||||
|
||||
template <class PIX, int nComponents, int max>
|
||||
class DotGenerator : public DotGeneratorBase {
|
||||
public :
|
||||
DotGenerator(OFX::ImageEffect &instance): DotGeneratorBase(instance){}
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float radiusSq = _radius * _radius;
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++)
|
||||
{
|
||||
if(_effect.abort())
|
||||
break;
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++)
|
||||
{
|
||||
float radsq = (x - _positionx)*(x - _positionx) + (y - _positiony)*(y - _positiony);
|
||||
float val = radsq/radiusSq;
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
{
|
||||
dstPix[c] = val < 1.0f ? PIX((1.0f-val)*max) : PIX(0);
|
||||
dstPix[c] = (PIX)(dstPix[c] * _colour[c]);
|
||||
}
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class DotExamplePlugin : public OFX::ImageEffect
|
||||
{
|
||||
protected:
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::DoubleParam *radius_;
|
||||
OFX::RGBAParam *colour_;
|
||||
OFX::Double2DParam* position_;
|
||||
public:
|
||||
DotExamplePlugin(OfxImageEffectHandle handle): ImageEffect(handle), dstClip_(0), radius_(0) , colour_(0), position_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
radius_ = fetchDoubleParam("radius");
|
||||
colour_ = fetchRGBAParam("colour");
|
||||
position_ = fetchDouble2DParam("position");
|
||||
}
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
void setupAndProcess(DotGeneratorBase &, const OFX::RenderArguments &args);
|
||||
bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod);
|
||||
template<class ARGS>
|
||||
void getPositionInPixels(double& x, double& y, const ARGS& args);
|
||||
template<class ARGS>
|
||||
void getPositionInCanonical(double& x, double& y, const ARGS& args);
|
||||
};
|
||||
|
||||
template<class ARGS>
|
||||
void DotExamplePlugin::getPositionInCanonical(double& x, double& y, const ARGS& args)
|
||||
{
|
||||
position_->getValueAtTime(args.time, x, y);
|
||||
}
|
||||
|
||||
template<class ARGS>
|
||||
void DotExamplePlugin::getPositionInPixels(double& x, double& y, const ARGS& args)
|
||||
{
|
||||
double xpos, ypos;
|
||||
getPositionInCanonical(xpos, ypos, args);
|
||||
x = (xpos * args.renderScale.x) /getProjectPixelAspectRatio();
|
||||
y = ypos * args.renderScale.y;
|
||||
}
|
||||
|
||||
void DotExamplePlugin::setupAndProcess(DotGeneratorBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
//OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
//OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
double rad = radius_->getValueAtTime(args.time);
|
||||
processor.setRadius((float)(rad));
|
||||
double r, g, b, a;
|
||||
colour_->getValueAtTime(args.time, r, g, b, a);
|
||||
processor.setColour(r,g,b,a);
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
double xpospixel, ypospixel;
|
||||
getPositionInPixels(xpospixel, ypospixel, args);
|
||||
float fieldScaler = (args.fieldToRender == OFX::eFieldLower || args.fieldToRender == OFX::eFieldUpper)? 0.5f: 1.0f;
|
||||
ypospixel *= fieldScaler;
|
||||
processor.setPosition((float)xpospixel, (float)ypospixel);
|
||||
processor.process();
|
||||
}
|
||||
|
||||
|
||||
bool DotExamplePlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod)
|
||||
{
|
||||
double r = radius_->getValueAtTime(args.time);
|
||||
double x, y;
|
||||
position_->getValueAtTime(args.time, x, y);
|
||||
rod.x1 = x - r;
|
||||
rod.y1 = y - r;
|
||||
rod.x2 = x + r;
|
||||
rod.y2 = y + r;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DotExamplePlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
if(dstComponents == OFX::ePixelComponentRGBA)
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
DotGenerator<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
DotGenerator<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
DotGenerator<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
DotGenerator<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
DotGenerator<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
DotGenerator<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DotExampleInteract::draw(const OFX::DrawArgs &args)
|
||||
{
|
||||
OfxRGBColourF col;
|
||||
col.r = 0.5f;
|
||||
col.g = 0.0f;
|
||||
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive :
|
||||
col.b = 0.0f;
|
||||
break;
|
||||
case ePoised :
|
||||
col.b = 0.5f;
|
||||
break;
|
||||
case ePicked :
|
||||
col.b = 1.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
double xpos = 0., ypos = 0.;
|
||||
DotExamplePlugin* plug = dynamic_cast<DotExamplePlugin*>(_effect);
|
||||
assert(plug);
|
||||
if (plug) {
|
||||
plug->getPositionInCanonical(xpos, ypos, args);
|
||||
}
|
||||
glPushMatrix();
|
||||
glColor3f(col.r, col.g, col.b);
|
||||
glTranslated(xpos, ypos, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b);
|
||||
glTranslated(xpos, ypos, 0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DotExampleInteract::penMotion(const OFX::PenArgs &args)
|
||||
{
|
||||
float dx = (float)(kBoxSize.x * args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y * args.pixelScale.y);
|
||||
OfxPointD penPos = args.penPosition;
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive :
|
||||
case ePoised :
|
||||
{
|
||||
StateEnum newState;
|
||||
double xpos = 0., ypos = 0.;
|
||||
DotExamplePlugin* plug = dynamic_cast<DotExamplePlugin*>(_effect);
|
||||
if (plug) {
|
||||
plug->getPositionInCanonical(xpos, ypos, args);
|
||||
}
|
||||
penPos.x -= xpos;
|
||||
penPos.y -= ypos;
|
||||
if(Absolute(penPos.x) < dx && Absolute(penPos.y) < dy)
|
||||
{
|
||||
newState = ePoised;
|
||||
}
|
||||
else
|
||||
{
|
||||
newState = eInActive;
|
||||
}
|
||||
|
||||
if(_state != newState)
|
||||
{
|
||||
_state = newState;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ePicked :
|
||||
{
|
||||
|
||||
position_->setValueAtTime(args.time, args.penPosition.x, args.penPosition.y);
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return _state != eInActive;
|
||||
}
|
||||
|
||||
bool DotExampleInteract::penDown(const OFX::PenArgs &args)
|
||||
{
|
||||
penMotion(args);
|
||||
if(_state == ePoised)
|
||||
{
|
||||
_state = ePicked;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
return _state == ePicked;
|
||||
}
|
||||
|
||||
bool DotExampleInteract::penUp(const OFX::PenArgs &args)
|
||||
{
|
||||
if(_state == ePicked)
|
||||
{
|
||||
_state = ePoised;
|
||||
penMotion(args);
|
||||
_effect->redrawOverlays();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
using namespace OFX;
|
||||
|
||||
class DotExampleOverlayDescriptor : public DefaultEffectOverlayDescriptor<DotExampleOverlayDescriptor, DotExampleInteract> {};
|
||||
|
||||
void DotExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
desc.setLabels("Dot Generator", "Dot Generator", "Dot Generator");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
desc.addSupportedContext(eContextGenerator);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setOverlayInteractDescriptor( new DotExampleOverlayDescriptor );
|
||||
}
|
||||
|
||||
void DotExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
// there has to be an input clip, even for generators
|
||||
ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
|
||||
srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
|
||||
srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setOptional(true);
|
||||
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
dstClip->setFieldExtraction(eFieldExtractSingle);
|
||||
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam("radius");
|
||||
param->setLabels("Radius", "Radius", "Radius");
|
||||
param->setScriptName("radius");
|
||||
param->setHint("The radius of the dot produced.");
|
||||
param->setDoubleType(eDoubleTypeX);
|
||||
param->setDefaultCoordinateSystem(eCoordinatesNormalised);
|
||||
param->setDefault(0.02);
|
||||
//param->setRange(0, 1);
|
||||
param->setIncrement(1);
|
||||
param->setDisplayRange(0, 1);
|
||||
param->setAnimates(true);
|
||||
|
||||
RGBAParamDescriptor *param2 = desc.defineRGBAParam("colour");
|
||||
param2->setAnimates(true);
|
||||
param2->setLabels("Colour", "Colour", "Colour");
|
||||
param2->setHint("The colour of the dot produced.");
|
||||
param2->setScriptName("colour");
|
||||
param2->setDefault(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
Double2DParamDescriptor* param3 = desc.defineDouble2DParam("position");
|
||||
param3->setLabels("Dot Position", "Dot Position", "Dot Position");
|
||||
param3->setDoubleType(eDoubleTypeXY);
|
||||
param3->setDefaultCoordinateSystem(eCoordinatesNormalised);
|
||||
param3->setAnimates(true);
|
||||
param3->setDimensionLabels("X", "Y");
|
||||
param3->setDefault(0.5, 0.5);
|
||||
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
page->addChild(*param);
|
||||
page->addChild(*param2);
|
||||
page->addChild(*param3);
|
||||
}
|
||||
|
||||
ImageEffect* DotExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
return new DotExamplePlugin(handle);
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#include "ofxsImageEffect.h"
|
||||
|
||||
class DotExamplePluginFactory : public OFX::PluginFactoryHelper<DotExamplePluginFactory>
|
||||
{
|
||||
public:
|
||||
DotExamplePluginFactory():OFX::PluginFactoryHelper<DotExamplePluginFactory>("net.sf.openfx.dotexample", 1, 0){}
|
||||
virtual void describe(OFX::ImageEffectDescriptor &desc);
|
||||
virtual void describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context);
|
||||
virtual OFX::ImageEffect* createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>retimer.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,386 @@
|
||||
|
||||
|
||||
#include <math.h> // for floor
|
||||
#include <float.h> // for FLT_MAX
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
#include "../include/ofxsImageBlender.H"
|
||||
|
||||
namespace OFX {
|
||||
extern ImageEffectHostDescription gHostDescription;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class RetimerPlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_; /**< @brief Mandated output clips */
|
||||
OFX::Clip *srcClip_; /**< @brief Mandated input clips */
|
||||
|
||||
OFX::DoubleParam *sourceTime_; /**< @brief mandated parameter, only used in the retimer context. */
|
||||
OFX::DoubleParam *speed_; /**< @brief only used in the filter context. */
|
||||
OFX::DoubleParam *duration_; /**< @brief how long the output should be as a proportion of input. General context only */
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
RetimerPlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, srcClip_(0)
|
||||
, sourceTime_(0)
|
||||
, speed_(0)
|
||||
, duration_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
|
||||
// What parameters we instantiate depend on the context
|
||||
if(getContext() == OFX::eContextRetimer)
|
||||
// fetch the mandated parameter which the host uses to pass us the frame to retime to
|
||||
sourceTime_ = fetchDoubleParam(kOfxImageEffectRetimerParamName);
|
||||
else // context == OFX::eContextFilter || context == OFX::eContextGeneral
|
||||
// filter context means we are in charge of how to retime, and our example is using a speed curve to do that
|
||||
speed_ = fetchDoubleParam("Speed");
|
||||
|
||||
// fetch duration param for general context
|
||||
if(getContext() == OFX::eContextGeneral)
|
||||
duration_ = fetchDoubleParam("Duration");
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/** Override the get frames needed action */
|
||||
virtual void getFramesNeeded(const OFX::FramesNeededArguments &args, OFX::FramesNeededSetter &frames);
|
||||
|
||||
/* override the time domain action, only for the general context */
|
||||
virtual bool getTimeDomain(OfxRangeD &range);
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
setupAndProcess(OFX::ImageBlenderBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
// make sure components are sane
|
||||
static void
|
||||
checkComponents(const OFX::Image &src,
|
||||
OFX::BitDepthEnum dstBitDepth,
|
||||
OFX::PixelComponentEnum dstComponents)
|
||||
{
|
||||
OFX::BitDepthEnum srcBitDepth = src.getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src.getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
static void framesNeeded(double sourceTime, OFX::FieldEnum fieldToRender, double *fromTimep, double *toTimep, double *blendp)
|
||||
{
|
||||
// figure the two images we are blending between
|
||||
double fromTime, toTime;
|
||||
double blend;
|
||||
|
||||
if (fieldToRender == OFX::eFieldNone) {
|
||||
// unfielded, easy peasy
|
||||
fromTime = floor(sourceTime);
|
||||
toTime = fromTime + 1;
|
||||
blend = sourceTime - fromTime;
|
||||
}
|
||||
else {
|
||||
// Fielded clips, pook. We are rendering field doubled images,
|
||||
// and so need to blend between fields, not frames.
|
||||
double frac = sourceTime - floor(sourceTime);
|
||||
if(frac < 0.5) {
|
||||
// need to go between the first and second fields of this frame
|
||||
fromTime = floor(sourceTime); // this will get the first field
|
||||
toTime = fromTime + 0.5; // this will get the second field of the same frame
|
||||
blend = frac * 2.0; // and the blend is between those two
|
||||
}
|
||||
else { // frac > 0.5
|
||||
fromTime = floor(sourceTime) + 0.5; // this will get the second field of this frame
|
||||
toTime = floor(sourceTime) + 1.0; // this will get the first field of the next frame
|
||||
blend = (frac - 0.5) * 2.0;
|
||||
}
|
||||
}
|
||||
*fromTimep = fromTime;
|
||||
*toTimep = toTime;
|
||||
*blendp = blend;
|
||||
}
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
RetimerPlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// figure the frame we should be retiming from
|
||||
double sourceTime;
|
||||
|
||||
if(getContext() == OFX::eContextRetimer) {
|
||||
// the host is specifying it, so fetch it from the kOfxImageEffectRetimerParamName pseudo-param
|
||||
sourceTime = sourceTime_->getValueAtTime(args.time);
|
||||
}
|
||||
else {
|
||||
// we have our own param, which is a speed, so we integrate it to get the time we want
|
||||
sourceTime = speed_->integrate(0, args.time);
|
||||
}
|
||||
|
||||
// figure the two images we are blending between
|
||||
double fromTime, toTime;
|
||||
double blend;
|
||||
framesNeeded(sourceTime, args.fieldToRender, &fromTime, &toTime, &blend);
|
||||
|
||||
// fetch the two source images
|
||||
std::unique_ptr<OFX::Image> fromImg(srcClip_->fetchImage(fromTime));
|
||||
std::unique_ptr<OFX::Image> toImg(srcClip_->fetchImage(toTime));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(fromImg.get()) checkComponents(*fromImg, dstBitDepth, dstComponents);
|
||||
if(toImg.get()) checkComponents(*toImg, dstBitDepth, dstComponents);
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setFromImg(fromImg.get());
|
||||
processor.setToImg(toImg.get());
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// set the blend between
|
||||
processor.setBlend((float)blend);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
void
|
||||
RetimerPlugin::getFramesNeeded(const OFX::FramesNeededArguments &args,
|
||||
OFX::FramesNeededSetter &frames)
|
||||
{
|
||||
// figure the two images we are blending between
|
||||
double fromTime, toTime;
|
||||
double blend;
|
||||
// whatever the rendered field is, the frames are the same
|
||||
framesNeeded(args.time, OFX::eFieldNone, &fromTime, &toTime, &blend);
|
||||
OfxRangeD range;
|
||||
range.min = fromTime;
|
||||
range.max = toTime;
|
||||
frames.setFramesNeeded(*srcClip_, range);
|
||||
}
|
||||
|
||||
/* override the time domain action, only for the general context */
|
||||
bool
|
||||
RetimerPlugin::getTimeDomain(OfxRangeD &range)
|
||||
{
|
||||
// this should only be called in the general context, ever!
|
||||
if(getContext() == OFX::eContextGeneral) {
|
||||
// If we are a general context, we can changed the duration of the effect, so have a param to do that
|
||||
// We need a separate param as it is impossible to derive this from a speed param and the input clip
|
||||
// duration (the speed may be animating or wired to an expression).
|
||||
double duration = duration_->getValue(); //don't animate
|
||||
|
||||
// how many frames on the input clip
|
||||
OfxRangeD srcRange = srcClip_->getFrameRange();
|
||||
|
||||
range.min = 0;
|
||||
range.max = srcRange.max * duration;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
RetimerPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
OFX::ImageBlender<unsigned char, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
OFX::ImageBlender<unsigned short, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
OFX::ImageBlender<float, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
OFX::ImageBlender<unsigned char, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
OFX::ImageBlender<unsigned short, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
OFX::ImageBlender<float, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
using namespace OFX;
|
||||
mDeclarePluginFactory(RetimerExamplePluginFactory, ;, {});
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static RetimerExamplePluginFactory p("net.sf.openfx.retimer", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void RetimerExamplePluginFactory::load()
|
||||
{
|
||||
// we can't be used on hosts that don't perfrom temporal clip access
|
||||
if(!gHostDescription.temporalClipAccess) {
|
||||
throw OFX::Exception::HostInadequate("Need random temporal image access to work");
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief The basic describe function, passed a plugin descriptor */
|
||||
void RetimerExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Retimer", "Retimer", "Retimer");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// Say we are a transition context
|
||||
desc.addSupportedContext(OFX::eContextRetimer);
|
||||
desc.addSupportedContext(OFX::eContextFilter);
|
||||
desc.addSupportedContext(OFX::eContextGeneral);
|
||||
|
||||
// Add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(true); // say we will be doing random time access on clips
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
}
|
||||
|
||||
/** @brief The describe in context function, passed a plugin descriptor and a context */
|
||||
void RetimerExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum context)
|
||||
{
|
||||
// we are a transition, so define the sourceTo input clip
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(true); // say we will be doing random time access on this clip
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setFieldExtraction(eFieldExtractDoubled); // which is the default anyway
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setFieldExtraction(eFieldExtractDoubled); // which is the default anyway
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
// what param we have is dependant on the host
|
||||
if(context == OFX::eContextRetimer) {
|
||||
// Define the mandated kOfxImageEffectRetimerParamName param, note that we don't do anything with this other than.
|
||||
// describe it. It is not a true param but how the host indicates to the plug-in which frame
|
||||
// it wants you to retime to. It appears on no plug-in side UI, it is purely the host's to manage.
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam(kOfxImageEffectRetimerParamName);
|
||||
(void)param;
|
||||
}
|
||||
else {
|
||||
// We are a general or filter context, define a speed param and a page of controls to put that in
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam("Speed");
|
||||
param->setLabels("speed", "speed", "speed");
|
||||
param->setScriptName("speed");
|
||||
param->setHint("How much to changed the speed of the input clip");
|
||||
param->setDefault(1);
|
||||
param->setRange(-FLT_MAX, FLT_MAX);
|
||||
param->setIncrement(0.05);
|
||||
param->setDisplayRange(0, 1);
|
||||
param->setAnimates(true); // can animate
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
|
||||
// make a page to put it in
|
||||
PageParamDescriptor *page = desc.definePageParam("Controls");
|
||||
|
||||
// add our speed param into it
|
||||
page->addChild(*param);
|
||||
|
||||
// If we are a general context, we can change the duration of the effect, so have a param to do that
|
||||
// We need a separate param as it is impossible to derive this from a speed param and the input clip
|
||||
// duration (the speed may be animating or wired to an expression).
|
||||
if(context == OFX::eContextGeneral) {
|
||||
// We are a general or filter context, define a speed param and a page of controls to put that in
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam("Duration");
|
||||
param->setLabels("duration", "duraction", "duration");
|
||||
param->setScriptName("duration");
|
||||
param->setHint("How long the output clip should be, as a proportion of the input clip's length.");
|
||||
param->setDefault(1);
|
||||
param->setRange(0, 10);
|
||||
param->setIncrement(0.1);
|
||||
param->setDisplayRange(0, 10);
|
||||
param->setAnimates(false); // no animation here!
|
||||
param->setDoubleType(eDoubleTypeScale);
|
||||
|
||||
// add param to page
|
||||
page->addChild(*param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief The create instance function, the plugin must return an object derived from the \ref OFX::ImageEffect class */
|
||||
ImageEffect* RetimerExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
|
||||
{
|
||||
return new RetimerPlugin(handle);
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Microsoft Developer Studio Project File - Name="retimer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=retimer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "retimer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "retimer.mak" CFG="retimer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "retimer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "retimer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "retimer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/retimer.ofx"
|
||||
|
||||
!ELSEIF "$(CFG)" == "retimer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\Retimer.ofx.bundle\Contents\Win32\retimer.ofx" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "retimer - Win32 Release"
|
||||
# Name "retimer - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\retimer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "retimer"=.\retimer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name ofxsupport
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="retimer"
|
||||
ProjectGUID="{F14E0B89-3767-48B1-A28C-326B0F350C7B}"
|
||||
RootNamespace="retimer"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="retimer.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>tester.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,528 @@
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
#include "ofxsInteract.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
|
||||
static const OfxPointD kBoxSize = {5, 5};
|
||||
|
||||
template <class T>
|
||||
inline T Minimum(T a, T b) { return (a < b) ? a : b;}
|
||||
|
||||
template <class T>
|
||||
inline T Absolute(T a) { return (a < 0) ? -a : a;}
|
||||
|
||||
class PositionInteract : public OFX::OverlayInteract
|
||||
{
|
||||
protected :
|
||||
enum StateEnum {
|
||||
eInActive,
|
||||
ePoised,
|
||||
ePicked
|
||||
};
|
||||
|
||||
StateEnum _state;
|
||||
OFX::Double2DParam* _position;
|
||||
public :
|
||||
PositionInteract(OfxInteractHandle handle, OFX::ImageEffect* effect)
|
||||
: OFX::OverlayInteract(handle)
|
||||
, _state(eInActive)
|
||||
{
|
||||
_position = effect->fetchDouble2DParam("widgetPos");
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
virtual bool draw(const OFX::DrawArgs &args);
|
||||
virtual bool penMotion(const OFX::PenArgs &args);
|
||||
virtual bool penDown(const OFX::PenArgs &args);
|
||||
virtual bool penUp(const OFX::PenArgs &args);
|
||||
OfxPointD getCanonicalPosition(double time) const
|
||||
{
|
||||
OfxPointD retVal;
|
||||
_position->getValueAtTime(time, retVal.x, retVal.y);
|
||||
return retVal;
|
||||
}
|
||||
void setCanonicalPosition(double x, double y, double time)
|
||||
{
|
||||
_position->setValueAtTime(time, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
bool PositionInteract::draw(const OFX::DrawArgs &args)
|
||||
{
|
||||
OfxRGBColourF col;
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive : col.r = col.g = col.b = 0.0f; break;
|
||||
case ePoised : col.r = col.g = col.b = 0.5f; break;
|
||||
case ePicked : col.r = col.g = col.b = 1.0f; break;
|
||||
}
|
||||
|
||||
// make the box a constant size on screen by scaling by the pixel scale
|
||||
float dx = (float)(kBoxSize.x / args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y / args.pixelScale.y);
|
||||
|
||||
// Draw a cross hair, the current coordinate system aligns with the image plane.
|
||||
glPushMatrix();
|
||||
|
||||
// draw the bo
|
||||
OfxPointD pos = getCanonicalPosition(args.time);
|
||||
glColor3f(col.r, col.g, col.b);
|
||||
glTranslated(pos.x, pos.y, 0);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
// draw a complementary outline
|
||||
glColor3f(1.0f - col.r, 1.0f - col.g, 1.0f - col.b);
|
||||
glTranslated(pos.x, pos.y, 0);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(-dx, -dy);
|
||||
glVertex2f(-dx, dy);
|
||||
glVertex2f( dx, dy);
|
||||
glVertex2f( dx, -dy);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// overridden functions from OFX::Interact to do things
|
||||
bool PositionInteract::penMotion(const OFX::PenArgs &args)
|
||||
{
|
||||
// figure the size of the box in cannonical coords
|
||||
float dx = (float)(kBoxSize.x / args.pixelScale.x);
|
||||
float dy = (float)(kBoxSize.y / args.pixelScale.y);
|
||||
|
||||
OfxPointD pos = getCanonicalPosition(args.time);
|
||||
|
||||
// pen position is in cannonical coords
|
||||
OfxPointD penPos = args.penPosition;
|
||||
|
||||
switch(_state)
|
||||
{
|
||||
case eInActive :
|
||||
case ePoised :
|
||||
{
|
||||
// are we in the box, become 'poised'
|
||||
StateEnum newState;
|
||||
penPos.x -= pos.x;
|
||||
penPos.y -= pos.y;
|
||||
if(Absolute(penPos.x) < dx &&
|
||||
Absolute(penPos.y) < dy) {
|
||||
newState = ePoised;
|
||||
}
|
||||
else {
|
||||
newState = eInActive;
|
||||
}
|
||||
|
||||
if(_state != newState) {
|
||||
_state = newState;
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ePicked :
|
||||
{
|
||||
setCanonicalPosition(penPos.x, penPos.y, args.time);
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return _state != eInActive;
|
||||
}
|
||||
|
||||
bool PositionInteract::penDown(const OFX::PenArgs &args)
|
||||
{
|
||||
penMotion(args);
|
||||
if(_state == ePoised) {
|
||||
_state = ePicked;
|
||||
setCanonicalPosition(args.penPosition.x, args.penPosition.y, args.time);
|
||||
_effect->redrawOverlays();
|
||||
}
|
||||
|
||||
return _state == ePicked;
|
||||
}
|
||||
|
||||
bool PositionInteract::penUp(const OFX::PenArgs &args)
|
||||
{
|
||||
if(_state == ePicked)
|
||||
{
|
||||
_state = ePoised;
|
||||
penMotion(args);
|
||||
_effect->redrawOverlays();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class GenericTestBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
OFX::Image *_srcImg;
|
||||
public :
|
||||
GenericTestBase(OFX::ImageEffect &instance): OFX::ImageProcessor(instance), _srcImg(0)
|
||||
{
|
||||
}
|
||||
void setSrcImg(OFX::Image *v) {_srcImg = v;}
|
||||
};
|
||||
|
||||
template <class PIX, int nComponents, int max>
|
||||
class ImageGenericTester : public GenericTestBase
|
||||
{
|
||||
public :
|
||||
ImageGenericTester(OFX::ImageEffect &instance) : GenericTestBase(instance){}
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++)
|
||||
{
|
||||
if(_effect.abort())
|
||||
break;
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++)
|
||||
{
|
||||
PIX *srcPix = (PIX *) (_srcImg ? _srcImg->getPixelAddress(x, y) : 0);
|
||||
if(srcPix)
|
||||
{
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = max - srcPix[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = 0;
|
||||
}
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class TypeCarrier, int kComponents, int kMax>
|
||||
class Analyser
|
||||
{
|
||||
public:
|
||||
Analyser(OFX::Clip* srcClip, OFX::DoubleParam* dbl)
|
||||
{
|
||||
OfxRangeD range = srcClip->getFrameRange();
|
||||
for(double d = range.min; d< range.max; ++d)
|
||||
{
|
||||
std::unique_ptr<OFX::Image> src(srcClip->fetchImage(d));
|
||||
dbl->setValueAtTime(d, d);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class GenericTestPlugin : public OFX::ImageEffect
|
||||
{
|
||||
protected :
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *srcClip_;
|
||||
|
||||
public :
|
||||
GenericTestPlugin(OfxImageEffectHandle handle) : ImageEffect(handle), dstClip_(0), srcClip_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
srcClip_ = fetchClip(kOfxImageEffectSimpleSourceClipName);
|
||||
}
|
||||
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
void setupAndProcess(GenericTestBase &, const OFX::RenderArguments &args);
|
||||
void changedParam(const OFX::InstanceChangedArgs &args, const std::string ¶mName)
|
||||
{
|
||||
if(paramName=="enableTest")
|
||||
{
|
||||
OFX::ChoiceParam* choice = fetchChoiceParam("enableTest");
|
||||
OFX::DoubleParam* dbl = fetchDoubleParam("enableDbl");
|
||||
int value = 0;
|
||||
choice->getValueAtTime(args.time, value);
|
||||
dbl->setEnabled(value ==0 );
|
||||
}
|
||||
else if(paramName=="pbButton")
|
||||
{
|
||||
sendMessage(OFX::Message::eMessageMessage, "", "Push Button Pressed - TestPassed!");
|
||||
}
|
||||
else if(paramName=="widgetPos")
|
||||
{
|
||||
redrawOverlays();
|
||||
}
|
||||
else if(paramName == "analyseButton")
|
||||
{
|
||||
OFX::BitDepthEnum dstBitDepth = srcClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = srcClip_->getPixelComponents();
|
||||
OFX::DoubleParam* dbl = fetchDoubleParam("analysisParam");
|
||||
|
||||
if(dstComponents == OFX::ePixelComponentRGBA)
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
Analyser<unsigned char, 4, 255> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
Analyser<unsigned short, 4, 65535> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
Analyser<float, 4, 1> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
Analyser<unsigned char, 1, 255> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
Analyser<unsigned short, 1, 65535> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
Analyser<float, 1, 1> analyse(srcClip_, dbl);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void GenericTestPlugin::setupAndProcess(GenericTestBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
std::unique_ptr<OFX::Image> src(srcClip_->fetchImage(args.time));
|
||||
|
||||
if(src.get())
|
||||
{
|
||||
OFX::BitDepthEnum srcBitDepth = src->getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src->getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setSrcImg(src.get());
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
processor.process();
|
||||
}
|
||||
|
||||
|
||||
void GenericTestPlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
if(dstComponents == OFX::ePixelComponentRGBA)
|
||||
{
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageGenericTester<unsigned char, 4, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageGenericTester<unsigned short, 4, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageGenericTester<float, 4, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth)
|
||||
{
|
||||
case OFX::eBitDepthUByte :
|
||||
{
|
||||
ImageGenericTester<unsigned char, 1, 255> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort :
|
||||
{
|
||||
ImageGenericTester<unsigned short, 1, 65535> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat :
|
||||
{
|
||||
ImageGenericTester<float, 1, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PositionOverlayDescriptor : public OFX::DefaultEffectOverlayDescriptor<PositionOverlayDescriptor, PositionInteract> {};
|
||||
|
||||
mDeclarePluginFactory(GenericTestExamplePluginFactory, {}, {});
|
||||
|
||||
using namespace OFX;
|
||||
void GenericTestExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
desc.setLabels("GenericTest", "GenericTest", "GenericTest");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
desc.addSupportedContext(eContextFilter);
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
|
||||
desc.setOverlayInteractDescriptor( new PositionOverlayDescriptor);
|
||||
}
|
||||
|
||||
void GenericTestExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName);
|
||||
srcClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
srcClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
srcClip->setTemporalClipAccess(false);
|
||||
srcClip->setSupportsTiles(true);
|
||||
srcClip->setIsMask(false);
|
||||
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
DoubleParamDescriptor *param1 = desc.defineDoubleParam("MinMaxTest");
|
||||
param1->setLabels("Min/Max Test", "Min/Max Test", "Min/Max Test");
|
||||
param1->setScriptName("minMaxTest");
|
||||
param1->setHint("A double parameter to illustrate visual min/max.");
|
||||
param1->setDefault(50.0);
|
||||
param1->setRange(-1000, 1000);
|
||||
param1->setDisplayRange(-1000, 1000);
|
||||
param1->setDoubleType(eDoubleTypePlain);
|
||||
|
||||
ChoiceParamDescriptor* param2 = desc.defineChoiceParam("enableTest");
|
||||
param2->setLabels("Enabler", "Enabler", "Enabler");
|
||||
param2->appendOption("Enable parameter", "Enable parameter");
|
||||
param2->appendOption("Disable parameter", "Disable parameter");
|
||||
|
||||
DoubleParamDescriptor *param3 = desc.defineDoubleParam("enableDbl");
|
||||
param3->setLabels("Enabled by Enabler", "Enabled by Enabler", "Enabled by Enabler");
|
||||
|
||||
|
||||
BooleanParamDescriptor* bparam = desc.defineBooleanParam("Insignificant");
|
||||
bparam->setLabels("Insignificant", "Insignificant", "Insignificant");
|
||||
bparam->setHint("Shouldn't cause a re-render.");
|
||||
bparam->setEvaluateOnChange(false);
|
||||
|
||||
BooleanParamDescriptor* bparam2 = desc.defineBooleanParam("secretTest");
|
||||
bparam2->setLabels("SECRET!", "SECRET!", "SECRET!");
|
||||
bparam2->setIsSecret(true);
|
||||
bparam2->setHint("Shouldn't be shown in the user interface.");
|
||||
|
||||
BooleanParamDescriptor* bparam3 = desc.defineBooleanParam("nonPersistant");
|
||||
bparam3->setLabels("Non-persistant", "Non-persistant", "Non-persistant");
|
||||
bparam3->setHint("Shouldn't be saved in the plugin description.");
|
||||
bparam3->setIsPersistant(false);
|
||||
|
||||
DoubleParamDescriptor *param5 = desc.defineDoubleParam("animateDbl");
|
||||
param5->setLabels("No Animation", "No Animation", "No Animation");
|
||||
param5->setAnimates(false);
|
||||
|
||||
DoubleParamDescriptor *param6 = desc.defineDoubleParam("angleTest");
|
||||
param6->setLabels("Angle?", "Angle?", "Angle?");
|
||||
param6->setRange(-180.0, 180.0);
|
||||
param6->setHint("An angle parameter.");
|
||||
param6->setDoubleType(eDoubleTypeAngle);
|
||||
|
||||
PushButtonParamDescriptor* pb = desc.definePushButtonParam("pbButton");
|
||||
pb->setLabels("Push Me", "Push Me", "Push Me");
|
||||
|
||||
PushButtonParamDescriptor* pb2 = desc.definePushButtonParam("analyseButton");
|
||||
pb2->setLabels("Analyse", "Analyse", "Analyse");
|
||||
|
||||
DoubleParamDescriptor *param7 = desc.defineDoubleParam("analysisParam");
|
||||
param7->setLabels("Analysis Slave", "Analysis Slave", "Analysis Slave");
|
||||
|
||||
Double2DParamDescriptor* widgetPos = desc.defineDouble2DParam("widgetPos");
|
||||
widgetPos->setLabels("Widget Position", "Widget Position", "Widget Position");
|
||||
widgetPos->setDoubleType(OFX::eDoubleTypeXYAbsolute);
|
||||
widgetPos->setDefaultCoordinateSystem(eCoordinatesNormalised);
|
||||
widgetPos->setDimensionLabels("X Position", "Y Position");
|
||||
widgetPos->setDefault(0.5, 0.5);
|
||||
}
|
||||
|
||||
OFX::ImageEffect* GenericTestExamplePluginFactory::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum /*context*/)
|
||||
{
|
||||
return new GenericTestPlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static GenericTestExamplePluginFactory p("net.sf.openfx.GenericTestPlugin", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="Tester"
|
||||
ProjectGUID="{CD419A0A-BD7D-4FE8-9520-2259B2F92F61}"
|
||||
RootNamespace="Tester"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="Tester.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>crossFade.ofx</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1d1</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,260 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
|
||||
#include "../include/ofxsProcessing.H"
|
||||
#include "../include/ofxsImageBlender.H"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief The plugin that does our work */
|
||||
class CrossFadePlugin : public OFX::ImageEffect {
|
||||
protected :
|
||||
// do not need to delete these, the ImageEffect is managing them for us
|
||||
OFX::Clip *dstClip_;
|
||||
OFX::Clip *fromClip_;
|
||||
OFX::Clip *toClip_;
|
||||
|
||||
OFX::DoubleParam *transition_;
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
CrossFadePlugin(OfxImageEffectHandle handle)
|
||||
: ImageEffect(handle)
|
||||
, dstClip_(0)
|
||||
, fromClip_(0)
|
||||
, toClip_(0)
|
||||
, transition_(0)
|
||||
{
|
||||
dstClip_ = fetchClip(kOfxImageEffectOutputClipName);
|
||||
fromClip_ = fetchClip(kOfxImageEffectTransitionSourceFromClipName);
|
||||
toClip_ = fetchClip(kOfxImageEffectTransitionSourceToClipName);
|
||||
transition_ = fetchDoubleParam("Transition");
|
||||
}
|
||||
|
||||
/* Override the render */
|
||||
virtual void render(const OFX::RenderArguments &args);
|
||||
|
||||
/* override is identity */
|
||||
virtual bool isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime);
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
setupAndProcess(OFX::ImageBlenderBase &, const OFX::RenderArguments &args);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** @brief render for the filter */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// basic plugin render function, just a skelington to instantiate templates from
|
||||
|
||||
// make sure components are sane
|
||||
static void
|
||||
checkComponents(const OFX::Image &src,
|
||||
OFX::BitDepthEnum dstBitDepth,
|
||||
OFX::PixelComponentEnum dstComponents)
|
||||
{
|
||||
OFX::BitDepthEnum srcBitDepth = src.getPixelDepth();
|
||||
OFX::PixelComponentEnum srcComponents = src.getPixelComponents();
|
||||
|
||||
// see if they have the same depths and bytes and all
|
||||
if(srcBitDepth != dstBitDepth || srcComponents != dstComponents)
|
||||
throw int(1); // HACK!! need to throw an sensible exception here!
|
||||
}
|
||||
|
||||
/* set up and run a processor */
|
||||
void
|
||||
CrossFadePlugin::setupAndProcess(OFX::ImageBlenderBase &processor, const OFX::RenderArguments &args)
|
||||
{
|
||||
// get a dst image
|
||||
std::unique_ptr<OFX::Image> dst(dstClip_->fetchImage(args.time));
|
||||
OFX::BitDepthEnum dstBitDepth = dst->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dst->getPixelComponents();
|
||||
|
||||
// fetch the two source images
|
||||
std::unique_ptr<OFX::Image> fromImg(fromClip_->fetchImage(args.time));
|
||||
std::unique_ptr<OFX::Image> toImg(toClip_->fetchImage(args.time));
|
||||
|
||||
// make sure bit depths are sane
|
||||
if(fromImg.get()) checkComponents(*fromImg, dstBitDepth, dstComponents);
|
||||
if(toImg.get()) checkComponents(*toImg, dstBitDepth, dstComponents);
|
||||
|
||||
// get the transition value
|
||||
float blend = (float)transition_->getValueAtTime(args.time);
|
||||
|
||||
// set the images
|
||||
processor.setDstImg(dst.get());
|
||||
processor.setFromImg(fromImg.get());
|
||||
processor.setToImg(toImg.get());
|
||||
|
||||
// set the render window
|
||||
processor.setRenderWindow(args.renderWindow);
|
||||
|
||||
// set the scales
|
||||
processor.setBlend(blend);
|
||||
|
||||
// Call the base class process member, this will call the derived templated process code
|
||||
processor.process();
|
||||
}
|
||||
|
||||
// the overridden render function
|
||||
void
|
||||
CrossFadePlugin::render(const OFX::RenderArguments &args)
|
||||
{
|
||||
// instantiate the render code based on the pixel depth of the dst clip
|
||||
OFX::BitDepthEnum dstBitDepth = dstClip_->getPixelDepth();
|
||||
OFX::PixelComponentEnum dstComponents = dstClip_->getPixelComponents();
|
||||
|
||||
// do the rendering
|
||||
if(dstComponents == OFX::ePixelComponentRGBA) {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
OFX::ImageBlender<unsigned char, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
OFX::ImageBlender<unsigned short, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
OFX::ImageBlender<float, 4> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(dstBitDepth) {
|
||||
case OFX::eBitDepthUByte : {
|
||||
OFX::ImageBlender<unsigned char, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthUShort : {
|
||||
OFX::ImageBlender<unsigned short, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
|
||||
case OFX::eBitDepthFloat : {
|
||||
OFX::ImageBlender<float, 1> fred(*this);
|
||||
setupAndProcess(fred, args);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
// overridden is identity
|
||||
bool
|
||||
CrossFadePlugin::isIdentity(const OFX::IsIdentityArguments &args, OFX::Clip * &identityClip, double &identityTime)
|
||||
{
|
||||
// get the transition value
|
||||
float blend = (float)transition_->getValueAtTime(args.time);
|
||||
|
||||
identityTime = args.time;
|
||||
|
||||
// at the start?
|
||||
if(blend <= 0.0) {
|
||||
identityClip = fromClip_;
|
||||
identityTime = args.time;
|
||||
return true;
|
||||
}
|
||||
|
||||
// at the end?
|
||||
if(blend >= 1.0) {
|
||||
identityClip = toClip_;
|
||||
identityTime = args.time;
|
||||
return true;
|
||||
}
|
||||
|
||||
// nope, identity we isnt
|
||||
return false;
|
||||
}
|
||||
|
||||
mDeclarePluginFactory(CrossFadeExamplePluginFactory, {}, {});
|
||||
using namespace OFX;
|
||||
|
||||
void CrossFadeExamplePluginFactory::describe(OFX::ImageEffectDescriptor &desc)
|
||||
{
|
||||
// basic labels
|
||||
desc.setLabels("Cross Fade", "Cross Fade", "Cross Fade");
|
||||
desc.setPluginGrouping("OFX Example (Support)");
|
||||
|
||||
// Say we are a transition context
|
||||
desc.addSupportedContext(eContextTransition);
|
||||
desc.addSupportedContext(eContextGeneral);
|
||||
|
||||
// Add supported pixel depths
|
||||
desc.addSupportedBitDepth(eBitDepthUByte);
|
||||
desc.addSupportedBitDepth(eBitDepthUShort);
|
||||
desc.addSupportedBitDepth(eBitDepthFloat);
|
||||
|
||||
// set a few flags
|
||||
desc.setSingleInstance(false);
|
||||
desc.setHostFrameThreading(false);
|
||||
desc.setSupportsMultiResolution(true);
|
||||
desc.setSupportsTiles(true);
|
||||
desc.setTemporalClipAccess(false);
|
||||
desc.setRenderTwiceAlways(false);
|
||||
desc.setSupportsMultipleClipPARs(false);
|
||||
|
||||
}
|
||||
|
||||
void CrossFadeExamplePluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ContextEnum /*context*/)
|
||||
{
|
||||
// we are a transition, so define the sourceFrom input clip
|
||||
ClipDescriptor *fromClip = desc.defineClip(kOfxImageEffectTransitionSourceFromClipName);
|
||||
fromClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
fromClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
fromClip->setTemporalClipAccess(false);
|
||||
fromClip->setSupportsTiles(true);
|
||||
|
||||
// we are a transition, so define the sourceTo input clip
|
||||
ClipDescriptor *toClip = desc.defineClip(kOfxImageEffectTransitionSourceToClipName);
|
||||
toClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
toClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
toClip->setTemporalClipAccess(false);
|
||||
toClip->setSupportsTiles(true);
|
||||
|
||||
// create the mandated output clip
|
||||
ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
|
||||
dstClip->addSupportedComponent(ePixelComponentRGBA);
|
||||
dstClip->addSupportedComponent(ePixelComponentAlpha);
|
||||
dstClip->setSupportsTiles(true);
|
||||
|
||||
// Define the mandated "Transition" param, note that we don't do anything with this other than.
|
||||
// describe it. It is not a true param but how the host indicates to the plug-in how far through
|
||||
// the transition it is. It appears on no plug-in side UI, it is purely the hosts to manage.
|
||||
DoubleParamDescriptor *param = desc.defineDoubleParam("Transition");
|
||||
(void)param;
|
||||
}
|
||||
|
||||
ImageEffect* CrossFadeExamplePluginFactory::createInstance(OfxImageEffectHandle handle, ContextEnum /*context*/)
|
||||
{
|
||||
return new CrossFadePlugin(handle);
|
||||
}
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Plugin
|
||||
{
|
||||
void getPluginIDs(OFX::PluginFactoryArray &ids)
|
||||
{
|
||||
static CrossFadeExamplePluginFactory p("net.sf.openfx.crossFade", 1, 0);
|
||||
ids.push_back(&p);
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Microsoft Developer Studio Project File - Name="crossFade" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=crossFade - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "crossFade.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "crossFade.mak" CFG="crossFade - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "crossFade - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "crossFade - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "crossFade - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/PropTester.ofx.bundle/Contents/Win32/crossFade.ofx"
|
||||
|
||||
!ELSEIF "$(CFG)" == "crossFade - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PROPTESTER_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Common Files\OFX\Plugins\CrossFade.ofx.bundle\Contents\Win32\crossFade.ofx" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "crossFade - Win32 Release"
|
||||
# Name "crossFade - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\crossFade.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "crossFade"=.\crossFade.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name ofxsupport
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ofxsupport"=..\..\Library\ofxsupport.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+464
@@ -0,0 +1,464 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="crossfade"
|
||||
ProjectGUID="{C14CCB89-3767-88B1-A28C-326B0B350C7E}"
|
||||
RootNamespace="crossfade"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Debug/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;_DEBUG;_WINDOWS;_USRDLL;"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PROPTESTER_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win32/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(IntDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(IntDir)/$(InputName).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
IntermediateDirectory=".\$(ConfigurationName)-$(PlatformName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="3"
|
||||
TypeLibraryName=".\Release/$(InputName).tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../../include,../../../include"
|
||||
PreprocessorDefinitions="WIN64;NDEBUG;_WINDOWS;_USRDLL;"
|
||||
StringPooling="false"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\$(ConfigurationName)-$(PlatformName)/$(InputName).pch"
|
||||
AssemblerListingLocation="$(IntDir)/"
|
||||
ObjectFile="$(IntDir)/"
|
||||
ProgramDataBaseFileName="$(IntDir)/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="2057"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib opengl32.lib"
|
||||
OutputFile="../$(OutDir)/$(InputName).ofx.bundle/Contents/Win64/$(InputName).ofx"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ProgramDatabaseFile="$(OutDir)/$(InputName).pdb"
|
||||
ImportLibrary="$(OutDir)/$(InputName).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/$(InputName).bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="crossFade.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,3 @@
|
||||
This directory contains header code that is used by the OFX Support library example plugins to perform basic processing functions.
|
||||
|
||||
The code in this directory is not so much a skin on the base OFX classes, but code used in implementing specific image processing algorithms. As such it does not sit in the support include lib, but in its own include directory.
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
|
||||
#ifndef _ofxsImageBlender_h_
|
||||
#define _ofxsImageBlender_h_
|
||||
|
||||
#include "ofxsProcessing.H"
|
||||
|
||||
namespace OFX {
|
||||
|
||||
/** @brief Base class used to blend two images together */
|
||||
class ImageBlenderBase : public OFX::ImageProcessor {
|
||||
protected :
|
||||
const OFX::Image *_fromImg; // be this at 0
|
||||
const OFX::Image *_toImg; // be this at 1
|
||||
float _blend; // how much to blend
|
||||
|
||||
public :
|
||||
/** @brief no arg ctor */
|
||||
ImageBlenderBase(OFX::ImageEffect &instance)
|
||||
: OFX::ImageProcessor(instance)
|
||||
, _fromImg(0)
|
||||
, _toImg(0)
|
||||
, _blend(0.5f)
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief set the src image */
|
||||
void setFromImg(const OFX::Image *v) {_fromImg = v;}
|
||||
void setToImg(const OFX::Image *v) {_toImg = v;}
|
||||
|
||||
/** @brief set the scale */
|
||||
void setBlend(float v) {_blend = v;}
|
||||
};
|
||||
|
||||
/** @brief templated class to blend between two images */
|
||||
template <class PIX, int nComponents>
|
||||
class ImageBlender : public ImageBlenderBase {
|
||||
public :
|
||||
// ctor
|
||||
ImageBlender(OFX::ImageEffect &instance)
|
||||
: ImageBlenderBase(instance)
|
||||
{}
|
||||
|
||||
static PIX Lerp(const PIX &v1,
|
||||
const PIX &v2,
|
||||
float blend)
|
||||
{
|
||||
return PIX((v2 - v1) * blend + v1);
|
||||
}
|
||||
|
||||
// and do some processing
|
||||
void multiThreadProcessImages(OfxRectI procWindow)
|
||||
{
|
||||
float blend = _blend;
|
||||
float blendComp = 1.0f - blend;
|
||||
|
||||
for(int y = procWindow.y1; y < procWindow.y2; y++) {
|
||||
if(_effect.abort()) break;
|
||||
|
||||
PIX *dstPix = (PIX *) _dstImg->getPixelAddress(procWindow.x1, y);
|
||||
|
||||
for(int x = procWindow.x1; x < procWindow.x2; x++) {
|
||||
|
||||
PIX *fromPix = (PIX *) (_fromImg ? _fromImg->getPixelAddress(x, y) : 0);
|
||||
PIX *toPix = (PIX *) (_toImg ? _toImg->getPixelAddress(x, y) : 0);
|
||||
|
||||
if(fromPix && toPix) {
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = Lerp(fromPix[c], toPix[c], blend);
|
||||
}
|
||||
else if(fromPix) {
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = PIX(fromPix[c] * blendComp);
|
||||
}
|
||||
else if(toPix) {
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = PIX(toPix[c] * blend);
|
||||
}
|
||||
else {
|
||||
for(int c = 0; c < nComponents; c++)
|
||||
dstPix[c] = PIX(0);
|
||||
}
|
||||
|
||||
dstPix += nComponents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user