change: Switch to offical OpenFX Support. Still can't compile.
This commit is contained in:
+334
@@ -0,0 +1,334 @@
|
||||
|
||||
|
||||
#ifndef _ofxsCore_H_
|
||||
#define _ofxsCore_H_
|
||||
// Copyright OpenFX and contributors to the OpenFX project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
/** @mainpage OFX Support Library
|
||||
|
||||
@section mainpageIntro Introduction
|
||||
|
||||
This support library skins the raw OFX C API with a set of C++ classes and functions that makes it easier to understand and write plug-ins to the API. Look at the examples to see how it is done.
|
||||
|
||||
<HR>
|
||||
|
||||
@section fifteenLineGuide Fifteen Line Plugin Writing Guide
|
||||
|
||||
- work from the examples
|
||||
- you need to write the following functions....
|
||||
- void OFX::Plugin::getPluginID(OFX::PluginID &id)
|
||||
- gives the unique name and version numbers of the plug-in
|
||||
- void OFX::Plugin::loadAction(void)
|
||||
- called after the plug-in is first loaded, and before any instance has been made,
|
||||
- void OFX::Plugin::unloadAction(void)
|
||||
- called before the plug-in is unloaded, and all instances have been destroyed,
|
||||
- void OFX::Plugin::describe(OFX::ImageEffectDescriptor &desc)
|
||||
- called to describe the plugin to the host
|
||||
- void OFX::Plugin::describeInContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context)
|
||||
- called to describe the plugin to the host for a context reported in OFX::Plugin::describe
|
||||
- OFX::ImageEffect * OFX::Plugin::createInstance(OfxImageEffectHandle handle, OFX::ContextEnum context)
|
||||
- called when a new instance of a plug-in needs to be created. You need to derive a class from ImageEffect, new it and return it.
|
||||
|
||||
The OFX::ImageEffect class has a set of members you can override to do various things, like rendering an effect. Again, look at the examples.
|
||||
|
||||
<HR>
|
||||
|
||||
@section license Copyright and License
|
||||
|
||||
The library is Copyright OpenFX and contributors to the OpenFX project. and was
|
||||
written by Bruno Nicoletti (bruno@thefoundry.co.uk).
|
||||
|
||||
It has been released under the GNU Lesser General Public License, see the
|
||||
top of any source file for details.
|
||||
|
||||
*/
|
||||
|
||||
/** @file This file contains core code that wraps OFX 'objects' with C++ classes.
|
||||
|
||||
This file only holds code that is visible to a plugin implementation, and so hides much
|
||||
of the direct OFX objects and any library side only functions.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4290 )
|
||||
#endif
|
||||
|
||||
#include "ofxCore.h"
|
||||
#include "ofxImageEffect.h"
|
||||
#include "ofxInteract.h"
|
||||
#include "ofxKeySyms.h"
|
||||
#include "ofxMemory.h"
|
||||
#include "ofxMessage.h"
|
||||
#include "ofxMultiThread.h"
|
||||
#include "ofxParam.h"
|
||||
#include "ofxProperty.h"
|
||||
#include "ofxPixels.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef OFX_CLIENT_EXCEPTION_HEADER
|
||||
#include OFX_CLIENT_EXCEPTION_HEADER
|
||||
#endif
|
||||
|
||||
/** @brief Defines an integer 3D point
|
||||
|
||||
Should migrate this to the ofxCore.h in a v1.1
|
||||
*/
|
||||
struct Ofx3DPointI {
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
/** @brief Defines a double precision 3D point
|
||||
|
||||
Should migrate this to the ofxCore.h in a v1.1
|
||||
*/
|
||||
struct Ofx3DPointD {
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
/** @brief Nasty macro used to define empty protected copy ctors and assign ops */
|
||||
#define mDeclareProtectedAssignAndCC(CLASS) \
|
||||
CLASS &operator=(const CLASS &) {assert(false); return *this;} \
|
||||
CLASS(const CLASS &) {assert(false); }
|
||||
|
||||
/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
|
||||
*/
|
||||
namespace OFX {
|
||||
/** forward class declarations */
|
||||
class PropertySet;
|
||||
|
||||
/** @brief Enumerates the different types a property can be */
|
||||
enum PropertyTypeEnum {
|
||||
ePointer,
|
||||
eInt,
|
||||
eString,
|
||||
eDouble
|
||||
};
|
||||
|
||||
/** @brief Enumerates the reasons a plug-in instance may have had one of its values changed */
|
||||
enum InstanceChangeReason {
|
||||
eChangeUserEdit, /**< @brief A user actively editted something in the plugin, eg: changed the value of an integer param on an interface */
|
||||
eChangePluginEdit, /**< @brief The plugin's own code changed something in the instance, eg: a callback on on param settting the value of another */
|
||||
eChangeTime /**< @brief The current value of a parameter has changed because the param animates and the current time has changed */
|
||||
};
|
||||
|
||||
/** @brief maps a status to a string for debugging purposes, note a c-str for printf */
|
||||
const char * mapStatusToString(OfxStatus stat);
|
||||
|
||||
/** @brief namespace for OFX support lib exceptions, all derive from std::exception, calling it */
|
||||
namespace Exception {
|
||||
|
||||
/** @brief thrown when a suite returns a dud status code
|
||||
*/
|
||||
class Suite : public std::exception {
|
||||
protected :
|
||||
OfxStatus _status;
|
||||
public :
|
||||
Suite(OfxStatus s) : _status(s) {}
|
||||
OfxStatus status(void) const {return _status;}
|
||||
operator OfxStatus() const {return _status;}
|
||||
|
||||
/** @brief reimplemented from std::exception */
|
||||
virtual const char * what () const noexcept {return mapStatusToString(_status);}
|
||||
|
||||
};
|
||||
|
||||
/** @brief Exception indicating that a host doesn't know about a property that is should do */
|
||||
class PropertyUnknownToHost : public std::exception {
|
||||
protected :
|
||||
std::string _what;
|
||||
public :
|
||||
PropertyUnknownToHost(const char *what) : _what(what) {}
|
||||
virtual ~PropertyUnknownToHost() noexcept {}
|
||||
|
||||
/** @brief reimplemented from std::exception */
|
||||
virtual const char * what () const noexcept
|
||||
{
|
||||
return _what.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief exception indicating that the host thinks a property has an illegal value */
|
||||
class PropertyValueIllegalToHost : public std::exception {
|
||||
protected :
|
||||
std::string _what;
|
||||
public :
|
||||
PropertyValueIllegalToHost(const char *what) : _what(what) {}
|
||||
virtual ~PropertyValueIllegalToHost() noexcept {}
|
||||
|
||||
/** @brief reimplemented from std::exception */
|
||||
virtual const char * what () const noexcept
|
||||
{
|
||||
return _what.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief exception indicating a request for a named thing exists (eg: a param), but is of the wrong type, should never make it back to the main entry
|
||||
indicates a logical error in the code. Asserts are raised in debug code in these situations.
|
||||
*/
|
||||
class TypeRequest : public std::exception {
|
||||
protected :
|
||||
std::string _what;
|
||||
public :
|
||||
TypeRequest(const char *what) : _what(what) {}
|
||||
virtual ~TypeRequest() noexcept {}
|
||||
|
||||
/** @brief reimplemented from std::exception */
|
||||
virtual const char * what () const noexcept
|
||||
{
|
||||
return _what.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// These exceptions are to be thrown by the plugin if it hits a problem, the
|
||||
// code managing the main entry will trap the exception and return a suitable
|
||||
// status code to the host.
|
||||
|
||||
/** @brief exception indicating a required host feature is missing */
|
||||
class HostInadequate : public std::exception {
|
||||
protected :
|
||||
std::string _what;
|
||||
public :
|
||||
HostInadequate(const char *what) : _what(what) {}
|
||||
virtual ~HostInadequate() noexcept {}
|
||||
|
||||
/** @brief reimplemented from std::exception */
|
||||
virtual const char * what () const noexcept
|
||||
{
|
||||
return _what.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
}; // end of Exception namespace
|
||||
|
||||
/** @brief Throws an @ref OFX::Exception::Suite depending on the status flag passed in */
|
||||
void
|
||||
throwSuiteStatusException(OfxStatus stat);
|
||||
|
||||
void
|
||||
throwHostMissingSuiteException(std::string name);
|
||||
|
||||
/** @brief This struct is used to return an identifier for the plugin by the function @ref OFX:Plugin::getPlugin.
|
||||
The members correspond to those in the OfxPlugin struct defined in ofxCore.h.
|
||||
*/
|
||||
|
||||
class ImageEffectDescriptor;
|
||||
class ImageEffect;
|
||||
|
||||
/** @brief This class wraps up an OFX property set */
|
||||
class PropertySet {
|
||||
protected :
|
||||
/** @brief The raw property handle */
|
||||
OfxPropertySetHandle _propHandle;
|
||||
|
||||
/** @brief Class static, whether we are logging each property action */
|
||||
static int _gPropLogging;
|
||||
|
||||
/** @brief Do not throw an exception if a host returns 'unsupported' when setting a property */
|
||||
static bool _gThrowOnUnsupported;
|
||||
|
||||
public :
|
||||
/** @brief turns on logging of property access functions */
|
||||
static void propEnableLogging(void) {++_gPropLogging;}
|
||||
|
||||
/** @brief turns off logging of property access functions */
|
||||
static void propDisableLogging(void) {--_gPropLogging;}
|
||||
|
||||
/** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */
|
||||
static void setThrowOnUnsupportedProperties(bool v) {_gThrowOnUnsupported = v;}
|
||||
|
||||
/** @brief Do we throw an exception if a host returns 'unsupported' when setting a property. Default is true */
|
||||
static bool getThrowOnUnsupportedProperties(void) {return _gThrowOnUnsupported;}
|
||||
|
||||
/** @brief construct a property set */
|
||||
PropertySet(OfxPropertySetHandle h = 0) : _propHandle(h) {}
|
||||
virtual ~PropertySet();
|
||||
|
||||
/** @brief set the handle to use for this set */
|
||||
void propSetHandle(OfxPropertySetHandle h) { _propHandle = h;}
|
||||
|
||||
/** @brief return the handle for this property set */
|
||||
OfxPropertySetHandle propSetHandle(void) const {return _propHandle;}
|
||||
|
||||
int propGetDimension(const char* property, bool throwOnFailure = true) const;
|
||||
void propReset(const char* property);
|
||||
|
||||
// set single values
|
||||
void propSetPointer(const char* property, void *value, int idx, bool throwOnFailure = true);
|
||||
void propSetString(const char* property, const std::string &value, int idx, bool throwOnFailure = true);
|
||||
void propSetDouble(const char* property, double value, int idx, bool throwOnFailure = true);
|
||||
void propSetInt(const char* property, int value, int idx, bool throwOnFailure = true);
|
||||
|
||||
// set multiple values
|
||||
void propSetDoubleN(const char* property, const double *value, int count, bool throwOnFailure = true);
|
||||
|
||||
void propSetPointer(const char* property, void *value, bool throwOnFailure = true)
|
||||
{propSetPointer(property, value, 0, throwOnFailure);}
|
||||
|
||||
void propSetString(const char* property, const std::string &value, bool throwOnFailure = true)
|
||||
{propSetString(property, value, 0, throwOnFailure);}
|
||||
|
||||
void propSetDouble(const char* property, double value, bool throwOnFailure = true)
|
||||
{propSetDouble(property, value, 0, throwOnFailure);}
|
||||
|
||||
void propSetInt(const char* property, int value, bool throwOnFailure = true)
|
||||
{propSetInt(property, value, 0, throwOnFailure);}
|
||||
|
||||
|
||||
/// get a pointer property
|
||||
void *propGetPointer(const char* property, int idx, bool throwOnFailure = true) const;
|
||||
|
||||
/// get a string property
|
||||
std::string propGetString(const char* property, int idx, bool throwOnFailure = true) const;
|
||||
/// get a double property
|
||||
double propGetDouble(const char* property, int idx, bool throwOnFailure = true) const;
|
||||
|
||||
/// get an int property
|
||||
int propGetInt(const char* property, int idx, bool throwOnFailure = true) const;
|
||||
|
||||
/// get a pointer property with index 0
|
||||
void* propGetPointer(const char* property, bool throwOnFailure = true) const
|
||||
{
|
||||
return propGetPointer(property, 0, throwOnFailure);
|
||||
}
|
||||
|
||||
/// get a string property with index 0
|
||||
std::string propGetString(const char* property, bool throwOnFailure = true) const
|
||||
{
|
||||
return propGetString(property, 0, throwOnFailure);
|
||||
}
|
||||
|
||||
/// get a double property with index 0
|
||||
double propGetDouble(const char* property, bool throwOnFailure = true) const
|
||||
{
|
||||
return propGetDouble(property, 0, throwOnFailure);
|
||||
}
|
||||
|
||||
/// get an int property with index 0
|
||||
int propGetInt(const char* property, bool throwOnFailure = true) const
|
||||
{
|
||||
return propGetInt(property, 0, throwOnFailure);
|
||||
}
|
||||
|
||||
std::list<std::string> propGetNString(const char* property, bool throwOnFailure = true) const;
|
||||
|
||||
};
|
||||
|
||||
// forward decl of the image effect
|
||||
class ImageEffect;
|
||||
};
|
||||
|
||||
// undeclare the protected assign and CC macro
|
||||
#undef mDeclareProtectedAssignAndCC
|
||||
|
||||
#endif
|
||||
+1224
File diff suppressed because it is too large
Load Diff
+286
@@ -0,0 +1,286 @@
|
||||
|
||||
|
||||
#ifndef _ofxsInteract_H_
|
||||
#define _ofxsInteract_H_
|
||||
// Copyright OpenFX and contributors to the OpenFX project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
/** @file This file contains core code that wraps OFX 'objects' with C++ classes.
|
||||
|
||||
This file only holds code that is visible to a plugin implementation, and so hides much
|
||||
of the direct OFX objects and any library side only functions.
|
||||
*/
|
||||
#include "ofxsParam.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
/** @brief Nasty macro used to define empty protected copy ctors and assign ops */
|
||||
#define mDeclareProtectedAssignAndCC(CLASS) \
|
||||
CLASS &operator=(const CLASS &) {assert(false); return *this;} \
|
||||
CLASS(const CLASS &) {assert(false); }
|
||||
|
||||
/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
|
||||
*/
|
||||
namespace OFX {
|
||||
|
||||
/** @brief forward declaration */
|
||||
class ImageEffect;
|
||||
|
||||
/// all image effect interacts have these argumens
|
||||
struct InteractArgs {
|
||||
/// ctor
|
||||
InteractArgs(const PropertySet &props);
|
||||
double time; /**< @brief The current effect time to draw at */
|
||||
OfxPointD renderScale; /**< @brief The current render scale being applied to any image that would be fetched */
|
||||
};
|
||||
|
||||
/** @brief struct to pass arguments into OFX::Interact::draw */
|
||||
struct DrawArgs : public InteractArgs {
|
||||
DrawArgs(const PropertySet &props);
|
||||
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */
|
||||
#endif
|
||||
OfxPointD pixelScale; /**< @brief The current effect time to draw at */
|
||||
OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */
|
||||
};
|
||||
|
||||
/** @brief POD to pass arguments into OFX::Interact pen actions */
|
||||
struct PenArgs : public InteractArgs {
|
||||
PenArgs(const PropertySet &props);
|
||||
|
||||
#ifdef kOfxInteractPropViewportSize // removed in OFX 1.4
|
||||
OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */
|
||||
#endif
|
||||
OfxPointD pixelScale; /**< @brief The current effect time to draw at */
|
||||
OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */
|
||||
OfxPointD penPosition; /**< @brief The current pen position */
|
||||
OfxPointD penViewportPosition;/**< @brief The current pen position in viewport coordinates */
|
||||
double penPressure; /**< @brief The normalised pressure on the pen */
|
||||
};
|
||||
|
||||
/** @brief struct to pass arguments into OFX::Interact key actions
|
||||
|
||||
Note
|
||||
- some keys cannot be represented as UTF8 strings (eg: the key pad page down key kOfxKey_KP_Page_Up), in which case the key string will be set to "".
|
||||
- some UTF8 symbols (generally non-English language ones) cannot be represented by one of the keySymbols, in which case the UTF8 string will be set to some non empty value, but the keySymbol will be set to kOfxKey_Unknown.
|
||||
- in no case will keyString be set to "" and keySymbol be set to kOfxKey_Unknown.
|
||||
*/
|
||||
struct KeyArgs : public InteractArgs {
|
||||
KeyArgs(const PropertySet &props);
|
||||
|
||||
int keySymbol; /**< @brief The key represented as one of the entries in ofxKeySyms.h, see note in OFX::KeyArgs */
|
||||
std::string keyString; /**< @brief That key as a UTF8 string, see note in OFX::KeyArgs */
|
||||
};
|
||||
|
||||
/** @brief struct to pass arguments into OFX::Interact focus actions */
|
||||
struct FocusArgs : public InteractArgs {
|
||||
FocusArgs(const PropertySet &props);
|
||||
|
||||
OfxPointD viewportSize; /**< @brief The openGL viewport size for the instance */
|
||||
OfxPointD pixelScale; /**< @brief The current effect time to draw at */
|
||||
OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */
|
||||
};
|
||||
|
||||
/** @brief Wraps up an OFX interact object for an Image Effect. It won't work for any other plug-in type at present (it would need to be broken into a hierarchy of classes).
|
||||
*/
|
||||
class Interact {
|
||||
protected :
|
||||
OfxInteractHandle _interactHandle; /**< @brief The handle for this interact */
|
||||
PropertySet _interactProperties; /**< @brief The property set on this interact */
|
||||
std::list<Param *> _slaveParams; /**< @brief List of params we are currently slaved to */
|
||||
ImageEffect *_effect; /**< @brief The instance we are associated with */
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
Interact(OfxInteractHandle handle);
|
||||
|
||||
/** @brief virtual destructor */
|
||||
virtual ~Interact();
|
||||
|
||||
PropertySet &getProperties() { return _interactProperties; }
|
||||
|
||||
/** @brief The bitdepth of each component in the openGL frame buffer */
|
||||
int getBitDepth(void) const;
|
||||
|
||||
/** @brief Does the openGL frame buffer have an alpha */
|
||||
bool hasAlpha(void) const;
|
||||
|
||||
/** @brief Returns the size of a real screen pixel under the interact's cannonical projection */
|
||||
OfxPointD getPixelScale(void) const;
|
||||
|
||||
/** @brief The suggested colour to draw a widget in an interact. Returns false if there is no suggestion. */
|
||||
bool getSuggestedColour(OfxRGBColourD &c) const;
|
||||
|
||||
/** @brief the background colour */
|
||||
OfxRGBColourD getBackgroundColour(void) const;
|
||||
|
||||
/** @brief Set a param that the interact should be redrawn on if its value changes */
|
||||
void addParamToSlaveTo(Param *p);
|
||||
|
||||
/** @brief Remova a param that the interact should be redrawn on if its value changes */
|
||||
void removeParamToSlaveTo(Param *p);
|
||||
|
||||
/** @brief Request a redraw */
|
||||
void requestRedraw(void) const;
|
||||
|
||||
/** @brief Swap a buffer in the case of a double bufferred interact, this is possibly a silly one */
|
||||
void swapBuffers(void) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// override the below in derived classes to do something useful
|
||||
|
||||
/** @brief the function called to draw in the interact */
|
||||
virtual bool draw(const DrawArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool penMotion(const PenArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool penDown(const PenArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool penUp(const PenArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool keyDown(const KeyArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool keyUp(const KeyArgs &args);
|
||||
|
||||
/** @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.
|
||||
*/
|
||||
virtual bool keyRepeat(const KeyArgs &args);
|
||||
|
||||
/** @brief Called when the interact is given input focus */
|
||||
virtual void gainFocus(const FocusArgs &args);
|
||||
|
||||
/** @brief Called when the interact is loses input focus */
|
||||
virtual void loseFocus(const FocusArgs &args);
|
||||
};
|
||||
|
||||
/** @brief an interact for an image effect overlay */
|
||||
class OverlayInteract : public Interact {
|
||||
public :
|
||||
/** @brief ctor */
|
||||
OverlayInteract(OfxInteractHandle handle);
|
||||
|
||||
/** @brief dtor */
|
||||
virtual ~OverlayInteract();
|
||||
};
|
||||
|
||||
class InteractDescriptor
|
||||
{
|
||||
public:
|
||||
InteractDescriptor():_props(0) {}
|
||||
virtual ~InteractDescriptor() {}
|
||||
void setPropertySet(OFX::PropertySet* props){ _props = props; }
|
||||
virtual Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) = 0;
|
||||
void setHasAlpha();
|
||||
bool getHasAlpha() const;
|
||||
void setBitDepth();
|
||||
int getBitDepth() const;
|
||||
virtual OfxPluginEntryPoint* getMainEntry() = 0;
|
||||
virtual void describe() {}
|
||||
protected:
|
||||
OFX::PropertySet* _props;
|
||||
};
|
||||
|
||||
typedef InteractDescriptor EffectOverlayDescriptor;
|
||||
|
||||
class ParamInteractDescriptor : public InteractDescriptor
|
||||
{
|
||||
public:
|
||||
ParamInteractDescriptor():InteractDescriptor(){}
|
||||
virtual ~ParamInteractDescriptor() {}
|
||||
void setInteractSizeAspect(double asp);
|
||||
void setInteractMinimumSize(int x, int y);
|
||||
void setInteractPreferredSize(int x, int y);
|
||||
virtual void setParamName(const std::string& pName) { _paramName = pName; }
|
||||
protected:
|
||||
std::string _paramName;
|
||||
};
|
||||
|
||||
class ParamInteract : public Interact
|
||||
{
|
||||
public:
|
||||
ParamInteract(OfxInteractHandle handle, ImageEffect* effect);
|
||||
virtual ~ParamInteract() {}
|
||||
double getInteractSizeAspect() const;
|
||||
OfxPointI getInteractMinimumSize() const;
|
||||
OfxPointI getInteractPreferredSize() const;
|
||||
OfxPointI getInteractSize() const;
|
||||
protected:
|
||||
ImageEffect* _effect;
|
||||
};
|
||||
|
||||
namespace Private
|
||||
{
|
||||
OfxStatus interactMainEntry(const char *actionRaw,
|
||||
const void *handleRaw,
|
||||
OfxPropertySetHandle inArgsRaw,
|
||||
OfxPropertySetHandle outArgsRaw,
|
||||
InteractDescriptor& desc);
|
||||
}
|
||||
|
||||
template<class DESC>
|
||||
class InteractMainEntry
|
||||
{
|
||||
protected:
|
||||
static OfxStatus overlayInteractMainEntry(const char *action, const void* handle, OfxPropertySetHandle in, OfxPropertySetHandle out)
|
||||
{
|
||||
static DESC desc;
|
||||
return OFX::Private::interactMainEntry(action, handle, in, out, desc);
|
||||
}
|
||||
};
|
||||
|
||||
template<class DESC, class INSTANCE>
|
||||
class DefaultEffectOverlayDescriptor : public EffectOverlayDescriptor, public InteractMainEntry<DESC>
|
||||
{
|
||||
public:
|
||||
Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) { return new INSTANCE(handle, effect); }
|
||||
virtual OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry<DESC>::overlayInteractMainEntry; }
|
||||
};
|
||||
|
||||
template<class DESC, class INSTANCE>
|
||||
class DefaultParamInteractDescriptor : public ParamInteractDescriptor, public InteractMainEntry<DESC>
|
||||
{
|
||||
public:
|
||||
Interact* createInstance(OfxInteractHandle handle, ImageEffect *effect) { return new INSTANCE(handle, effect, _paramNameStatic); }
|
||||
virtual OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry<DESC>::overlayInteractMainEntry; }
|
||||
virtual void setParamName(const std::string& pName) { _paramNameStatic = pName; }
|
||||
protected:
|
||||
static std::string _paramNameStatic;
|
||||
};
|
||||
|
||||
template<class DESC, class INSTANCE> std::string OFX::DefaultParamInteractDescriptor<DESC, INSTANCE>::_paramNameStatic;
|
||||
};
|
||||
|
||||
|
||||
#undef mDeclareProtectedAssignAndCC
|
||||
|
||||
#endif
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
#ifndef _ofxsLog_H_
|
||||
#define _ofxsLog_H_
|
||||
// Copyright OpenFX and contributors to the OpenFX project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
/** @file This file contains OFX logging header code
|
||||
*/
|
||||
|
||||
/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
|
||||
*/
|
||||
namespace OFX {
|
||||
|
||||
/** @brief this namespace wraps up logging functionality */
|
||||
namespace Log {
|
||||
/** @brief Indent it, not MP sane at the moment */
|
||||
void indent(void);
|
||||
|
||||
/** @brief Outdent it, not MP sane at the moment */
|
||||
void outdent(void);
|
||||
|
||||
/** @brief Sets the name of the log file. */
|
||||
void setFileName(const std::string &value);
|
||||
|
||||
/** @brief Opens the log file, returns whether this was sucessful or not. */
|
||||
bool open(void);
|
||||
|
||||
/** @brief Closes the log file. */
|
||||
void close(void);
|
||||
|
||||
/** @brief Prints to the log file. */
|
||||
void print(const char *format, ...);
|
||||
|
||||
/** @brief Prints to the log file only if the condition is true and prepends a warning notice. */
|
||||
void warning(bool condition, const char *format, ...);
|
||||
|
||||
/** @brief Prints to the log file only if the condition is true and prepends an error notice. */
|
||||
void error(bool condition, const char *format, ...);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
#ifndef _ofxsMemory_H_
|
||||
#define _ofxsMemory_H_
|
||||
// Copyright OpenFX and contributors to the OpenFX project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
/** @file This file contains core code that wraps the ofx memory allocator with C++ functions.
|
||||
|
||||
This file only holds code that is visible to a plugin implementation, and so hides much
|
||||
of the direct OFX objects and any library side only functions.
|
||||
*/
|
||||
|
||||
/** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
|
||||
*/
|
||||
namespace OFX {
|
||||
|
||||
// forward declaration of class
|
||||
class ImageEffect;
|
||||
|
||||
/** @brief Namespace for general purpose memory allocation */
|
||||
namespace Memory {
|
||||
/** @brief Allocate memory.
|
||||
|
||||
\arg \e nBytes - the number of bytes to allocate
|
||||
\arg \e handle - effect instance to assosciate with this memory allocation, or NULL
|
||||
|
||||
This function has the host allocate memory using it's own memory resources
|
||||
and returns that to the plugin. This memory is distinct to any image memory allocation.
|
||||
|
||||
Succeeds or throws std::bad_alloc
|
||||
*/
|
||||
void *allocate(size_t nBytes,
|
||||
ImageEffect *handle = 0);
|
||||
|
||||
/** @brief release memory
|
||||
|
||||
\arg \e ptr - pointer previously returned by OFX::Memory::allocate
|
||||
*/
|
||||
void free(void *ptr) noexcept;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
#ifndef _ofxsMessage_H_
|
||||
#define _ofxsMessage_H_
|
||||
|
||||
namespace OFX
|
||||
{
|
||||
namespace Message
|
||||
{
|
||||
enum MessageReplyEnum
|
||||
{
|
||||
eMessageReplyOK,
|
||||
eMessageReplyYes,
|
||||
eMessageReplyNo,
|
||||
eMessageReplyFailed
|
||||
};
|
||||
|
||||
enum MessageTypeEnum
|
||||
{
|
||||
eMessageFatal,
|
||||
eMessageError,
|
||||
eMessageMessage,
|
||||
eMessageWarning,
|
||||
eMessageLog,
|
||||
eMessageQuestion
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
|
||||
#ifndef _ofxsMultiThread_H_
|
||||
#define _ofxsMultiThread_H_
|
||||
// Copyright OpenFX and contributors to the OpenFX project.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
/** @file This file contains core code that wraps OFX 'objects' with C++ classes.
|
||||
|
||||
This file only holds code that is visible to a plugin implementation, and so hides much
|
||||
of the direct OFX objects and any library side only functions.
|
||||
*/
|
||||
|
||||
#include "ofxsCore.h"
|
||||
|
||||
typedef struct OfxMutex* OfxMutexHandle;
|
||||
|
||||
namespace OFX {
|
||||
|
||||
/** @brief Multi thread namespace */
|
||||
namespace MultiThread {
|
||||
|
||||
/** @brief Class that wraps up SMP multi-processing */
|
||||
class Processor {
|
||||
private :
|
||||
/** @brief Function to pass to the multi thread suite */
|
||||
static void staticMultiThreadFunction(unsigned int threadIndex, unsigned int threadMax, void *customArg);
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
Processor();
|
||||
|
||||
/** @brief dtor */
|
||||
virtual ~Processor();
|
||||
|
||||
/** @brief function that will be called in each thread. ID is from 0..nThreads-1 nThreads are the number of threads it is being run over */
|
||||
virtual void multiThreadFunction(unsigned int threadID, unsigned int nThreads) = 0;
|
||||
|
||||
/** @brief call this to kick off multi threading
|
||||
|
||||
The nCPUs is 0, the maximum allowable number of CPUs will be used.
|
||||
*/
|
||||
virtual void multiThread(unsigned int nCPUs = 0);
|
||||
};
|
||||
|
||||
/** @brief Has the current thread been spawned from an MP */
|
||||
bool isSpawnedThread(void);
|
||||
|
||||
/** @brief The number of CPUs that can be used for MP-ing */
|
||||
unsigned int getNumCPUs(void);
|
||||
|
||||
/** @brief The index of the current thread. From 0 to numCPUs() - 1 */
|
||||
unsigned int getThreadIndex(void);
|
||||
|
||||
/** @brief An OFX mutex */
|
||||
class Mutex {
|
||||
protected :
|
||||
OfxMutexHandle _handle; /**< @brief The handle */
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
Mutex(int lockCount = 0);
|
||||
|
||||
/** @brief dtor */
|
||||
virtual ~Mutex(void);
|
||||
|
||||
/** @brief lock it, blocks until lock is gained */
|
||||
void lock();
|
||||
|
||||
/** @brief unlock it */
|
||||
void unlock();
|
||||
|
||||
/** @brief attempt to lock, non-blocking
|
||||
|
||||
\brief returns
|
||||
- true if the lock was achieved
|
||||
- false if it could not
|
||||
*/
|
||||
bool tryLock();
|
||||
};
|
||||
|
||||
/// a class to wrap around a mutex which is exception safe
|
||||
/// it locks the mutex on construction and unlocks it on destruction
|
||||
class AutoMutex {
|
||||
protected :
|
||||
Mutex &_mutex;
|
||||
|
||||
public :
|
||||
/// ctor, acquires the lock
|
||||
explicit AutoMutex(Mutex &m)
|
||||
: _mutex(m)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
/// dtor, releases the lock
|
||||
virtual ~AutoMutex()
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
+1868
File diff suppressed because it is too large
Load Diff
+230
@@ -0,0 +1,230 @@
|
||||
|
||||
|
||||
#ifndef _ofxsProcessing_h_
|
||||
#define _ofxsProcessing_h_
|
||||
|
||||
/*
|
||||
OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
|
||||
Copyright (C) 2005 The Open Effects Association Ltd
|
||||
Author Bruno Nicoletti bruno@thefoundry.co.uk
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name The Open Effects Association Ltd, 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 OWNER 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.
|
||||
|
||||
The Open Effects Association Ltd
|
||||
1 Wardour St
|
||||
London W1D 6PA
|
||||
England
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ofxsImageEffect.h"
|
||||
#include "ofxsMultiThread.h"
|
||||
#include "ofxsLog.h"
|
||||
|
||||
/** @file This file contains a useful base class that can be used to process images
|
||||
|
||||
The code below is not so much a skin on the base OFX classes, but code used in implementing
|
||||
specific image processing algorithms.
|
||||
*/
|
||||
|
||||
namespace OFX {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// base class to process images with
|
||||
class ImageProcessor : public OFX::MultiThread::Processor {
|
||||
protected :
|
||||
OFX::ImageEffect &_effect; /**< @brief effect to render with */
|
||||
OFX::Image *_dstImg; /**< @brief image to process into */
|
||||
OfxRectI _renderWindow; /**< @brief render window to use */
|
||||
bool _isEnabledOpenCLRender; /**< @brief is OpenCL Render Enabled */
|
||||
bool _isEnabledCudaRender; /**< @brief is Cuda Render Enabled */
|
||||
bool _isEnabledMetalRender; /**< @brief is Metal Render Enabled */
|
||||
void* _pOpenCLCmdQ; /**< @brief OpenCL Command Queue Handle */
|
||||
void* _pCudaStream; /**< @brief Cuda Stream Handle */
|
||||
void* _pMetalCmdQ; /**< @brief Metal Command Queue Handle */
|
||||
|
||||
public :
|
||||
/** @brief ctor */
|
||||
ImageProcessor(OFX::ImageEffect &effect)
|
||||
: _effect(effect)
|
||||
, _dstImg(0)
|
||||
, _isEnabledOpenCLRender(false)
|
||||
, _isEnabledCudaRender(false)
|
||||
, _isEnabledMetalRender(false)
|
||||
, _pOpenCLCmdQ(NULL)
|
||||
, _pCudaStream(NULL)
|
||||
, _pMetalCmdQ(NULL)
|
||||
{
|
||||
_renderWindow.x1 = _renderWindow.y1 = _renderWindow.x2 = _renderWindow.y2 = 0;
|
||||
}
|
||||
|
||||
/** @brief set the destination image */
|
||||
void setDstImg(OFX::Image *v) {_dstImg = v; }
|
||||
|
||||
/** @brief set OpenCL, CUDA render arguments */
|
||||
void setGPURenderArgs(const OFX::RenderArguments& args)
|
||||
{
|
||||
_isEnabledOpenCLRender = args.isEnabledOpenCLRender;
|
||||
_isEnabledCudaRender = args.isEnabledCudaRender;
|
||||
_isEnabledMetalRender = args.isEnabledMetalRender;
|
||||
|
||||
if (_isEnabledOpenCLRender)
|
||||
{
|
||||
_pOpenCLCmdQ = args.pOpenCLCmdQ;
|
||||
}
|
||||
if (_isEnabledCudaRender)
|
||||
{
|
||||
_pCudaStream = args.pCudaStream;
|
||||
}
|
||||
if (_isEnabledMetalRender)
|
||||
{
|
||||
_pMetalCmdQ = args.pMetalCmdQ;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief reset the render window */
|
||||
void setRenderWindow(OfxRectI rect) {_renderWindow = rect;}
|
||||
|
||||
/** @brief overridden from OFX::MultiThread::Processor. This function is called once on each SMP thread by the base class */
|
||||
void multiThreadFunction(unsigned int threadId, unsigned int nThreads)
|
||||
{
|
||||
// slice the y range into the number of threads it has
|
||||
unsigned int dy = _renderWindow.y2 - _renderWindow.y1;
|
||||
// the following is equivalent to std::ceil(dy/(double)nThreads);
|
||||
unsigned int h = (dy+nThreads-1)/nThreads;
|
||||
if (h == 0) {
|
||||
// there are more threads than lines to process
|
||||
h = 1;
|
||||
}
|
||||
if (threadId * h >= dy) {
|
||||
// empty render subwindow
|
||||
return;
|
||||
}
|
||||
unsigned int y1 = _renderWindow.y1 + threadId * h;
|
||||
|
||||
unsigned int step = (threadId + 1) * h;
|
||||
unsigned int y2 = _renderWindow.y1 + (step < dy ? step : dy);
|
||||
|
||||
OfxRectI win = _renderWindow;
|
||||
win.y1 = y1; win.y2 = y2;
|
||||
|
||||
// and render that thread on each
|
||||
multiThreadProcessImages(win);
|
||||
}
|
||||
|
||||
/** @brief called before any MP is done */
|
||||
virtual void preProcess(void) {}
|
||||
|
||||
/** @brief this is called by process to actually process images using OpenCL when isEnabledOpenCLRender is true, override in derived classes */
|
||||
virtual void processImagesOpenCL(void)
|
||||
{
|
||||
OFX::Log::print("processImagesOpenCL not implemented");
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
};
|
||||
|
||||
/** @brief this is called by process to actually process images using CUDA when isEnabledCudaRender is true, override in derived classes */
|
||||
virtual void processImagesCuda(void)
|
||||
{
|
||||
OFX::Log::print("processImagesCuda not implemented");
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
};
|
||||
|
||||
/** @brief this is called by process to actually process images using Metal when isEnabledMetalRender is true, override in derived classes */
|
||||
virtual void processImagesMetal(void)
|
||||
{
|
||||
OFX::Log::print("processImagesMetal not implemented");
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
};
|
||||
|
||||
/** @brief this is called by multiThreadFunction to actually process images, override in derived classes */
|
||||
virtual void multiThreadProcessImages(OfxRectI window)
|
||||
{
|
||||
OFX::Log::print("multiThreadProcessImages not implemented");
|
||||
OFX::throwSuiteStatusException(kOfxStatErrUnsupported);
|
||||
};
|
||||
|
||||
/** @brief called before any MP is done */
|
||||
virtual void postProcess(void) {}
|
||||
|
||||
/** @brief called to process everything */
|
||||
virtual void process(void)
|
||||
{
|
||||
// If _dstImg was set, check that the _renderWindow is lying into dstBounds
|
||||
if (_dstImg) {
|
||||
const OfxRectI& dstBounds = _dstImg->getBounds();
|
||||
// is the renderWindow within dstBounds ?
|
||||
assert(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 &&
|
||||
dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2);
|
||||
// exit gracefully in case of error
|
||||
if (!(dstBounds.x1 <= _renderWindow.x1 && _renderWindow.x2 <= dstBounds.x2 &&
|
||||
dstBounds.y1 <= _renderWindow.y1 && _renderWindow.y2 <= dstBounds.y2) ||
|
||||
(_renderWindow.x1 >= _renderWindow.x2) ||
|
||||
(_renderWindow.y1 >= _renderWindow.y2)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// call the pre MP pass
|
||||
preProcess();
|
||||
|
||||
if (_isEnabledOpenCLRender)
|
||||
{
|
||||
OFX::Log::print("processing via OpenCL");
|
||||
processImagesOpenCL();
|
||||
}
|
||||
else if (_isEnabledCudaRender)
|
||||
{
|
||||
OFX::Log::print("processing via CUDA");
|
||||
processImagesCuda();
|
||||
}
|
||||
else if (_isEnabledMetalRender)
|
||||
{
|
||||
OFX::Log::print("processing via Metal");
|
||||
processImagesMetal();
|
||||
}
|
||||
else // is CPU
|
||||
{
|
||||
OFX::Log::print("processing via CPU");
|
||||
// make sure there are at least 4096 pixels per CPU and at least 1 line par CPU
|
||||
unsigned int nCPUs = (std::min(_renderWindow.x2 - _renderWindow.x1, 4096) *
|
||||
(_renderWindow.y2 - _renderWindow.y1)) / 4096;
|
||||
// make sure the number of CPUs is valid (and use at least 1 CPU)
|
||||
nCPUs = std::max(1u, std::min(nCPUs, OFX::MultiThread::getNumCPUs()));
|
||||
|
||||
// call the base multi threading code, should put a pre & post thread calls in too
|
||||
multiThread(nCPUs);
|
||||
}
|
||||
|
||||
// call the post MP pass
|
||||
postProcess();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Olive Community Edition - Non-Linear Video Editor
|
||||
# Copyright (C) 2025 Olive CE Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Package all local libraries into an application or plugin bundle on OSX
|
||||
#
|
||||
# Author: Frederic Devernay <frederic.devernay@m4x.org>
|
||||
#
|
||||
# This script copies the .so, .la and .xml files needed to redistribute a mac application
|
||||
# This file is strongly inspired from the osx-app.sh script from the Inkscape source code
|
||||
#
|
||||
# In the XCode project, the "Runtime search paths" of your binaries should be set to
|
||||
# "@loader_path/../Frameworks @loader_path/../Libraries" so that it finds libraries
|
||||
# and frameworks at runtime.
|
||||
# If using a Makefile, you should add the following flags at link time:
|
||||
# -Wl,-rpath,@loader_path/../Frameworks -Wl,-rpath,@loader_path/../Libraries
|
||||
#
|
||||
# References:
|
||||
# http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
|
||||
# http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/
|
||||
|
||||
# env LANG=C is necessary so that sed doesn't try to interpret the binary file with a specific encoding
|
||||
LANG=C
|
||||
export LANG
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo "Usage: $0 AppName.app|Bundle.bundle Executablename"
|
||||
echo "moves macports and local libraries into AppName.app"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MACPORTS=/opt/local
|
||||
HOMEBREW=/brew2/local
|
||||
LOCAL=/usr/local
|
||||
|
||||
# add to PATH
|
||||
PATH="$MACPORTS/bin:$HOMEBREW/bin:$LOCAL/bin:$PATH"
|
||||
|
||||
if ! port help > /dev/null 2>&1; then
|
||||
echo "Please make sure that MacPorts is installed in /opt/local"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
package="$1"
|
||||
binary="$package/Contents/MacOS/$2"
|
||||
libdir="Libraries"
|
||||
pkglib="$package/Contents/$libdir"
|
||||
|
||||
if [ ! -x "$binary" ]; then
|
||||
echo "Error: $binary does not exist or is not an executable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rpath=`otool -l $binary | grep -A 3 LC_RPATH |grep path|awk '{ print $2 }'`
|
||||
if [[ ! ("$rpath" == *"@loader_path/../Libraries"*) ]]; then
|
||||
echo "Error:: The runtime search path in $binary does not contain \"@loader_path/../Libraries\". Please set it in your Xcode project, or link the binary with the flags -Xlinker -rpath -Xlinker \"@loader_path/../Libraries\""
|
||||
exit 1
|
||||
fi
|
||||
# Test dirs
|
||||
test -d "$pkglib" || mkdir "$pkglib"
|
||||
test -d "$pkglib/share/" || mkdir "$pkglib/share/"
|
||||
|
||||
LIBADD=
|
||||
|
||||
#############################
|
||||
# test if ImageMagick is used
|
||||
if otool -L "$binary" | fgrep libMagick > /dev/null; then
|
||||
# Check that ImageMagick is properly installed
|
||||
if ! pkg-config --modversion ImageMagick >/dev/null 2>&1; then
|
||||
echo "Missing ImageMagick -- please install ImageMagick ('sudo port install ImageMagick +no_x11 +universal') and try again." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update the ImageMagick path in startup script.
|
||||
IMAGEMAGICKVER=`pkg-config --modversion ImageMagick`
|
||||
IMAGEMAGICKMAJ=${IMAGEMAGICKVER%.*.*}
|
||||
IMAGEMAGICKLIB=`pkg-config --variable=libdir ImageMagick`
|
||||
IMAGEMAGICKSHARE=`pkg-config --variable=prefix ImageMagick`/share
|
||||
# if I get this right, sed substitutes in the exe the occurences of IMAGEMAGICKVER
|
||||
# into the actual value retrieved from the package.
|
||||
# We don't need this because we use MAGICKCORE_PACKAGE_VERSION declared in the <magick/magick-config.h>
|
||||
# sed -e "s,IMAGEMAGICKVER,$IMAGEMAGICKVER,g" -i "" $pkgbin/DisparityKillerM
|
||||
|
||||
# copy the ImageMagick libraries (.la and .so)
|
||||
cp -r "$IMAGEMAGICKLIB/ImageMagick-$IMAGEMAGICKVER" "$pkglib/"
|
||||
cp -r "$IMAGEMAGICKSHARE/ImageMagick-$IMAGEMAGICKMAJ" "$pkglib/share/"
|
||||
|
||||
LIBADD="$LIBADD $pkglib/ImageMagick-$IMAGEMAGICKVER/modules-*/*/*.so"
|
||||
WITH_IMAGEMAGICK=yes
|
||||
fi
|
||||
|
||||
# expand glob patterns in LIBADD
|
||||
LIBADD=`echo $LIBADD`
|
||||
|
||||
# Find out the library dependencies
|
||||
# (i.e. $LOCAL or $MACPORTS), then loop until no changes.
|
||||
a=1
|
||||
nfiles=0
|
||||
alllibs=""
|
||||
endl=true
|
||||
while $endl; do
|
||||
#echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
|
||||
libs="`otool -L $pkglib/* $LIBADD $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep -e $LOCAL'\\|'$HOMEBREW'\\|'$MACPORTS | sort | uniq`"
|
||||
if [ -n "$libs" ]; then
|
||||
cp -f $libs $pkglib
|
||||
alllibs="`ls $alllibs $libs | sort | uniq`"
|
||||
fi
|
||||
let "a+=1"
|
||||
nnfiles=`ls $pkglib | wc -l`
|
||||
if [ $nnfiles = $nfiles ]; then
|
||||
endl=false
|
||||
else
|
||||
nfiles=$nnfiles
|
||||
fi
|
||||
done
|
||||
|
||||
# all the libraries were copied, now change the names...
|
||||
## We use @rpath instead of @executable_path/../$libdir because it's shorter
|
||||
## than /opt/local, so it always works. The downside is that the XCode project
|
||||
## has to link the binary with "Runtime search paths" set correctly
|
||||
## (e.g. to "@loader_path/../Frameworks @loader_path/../Libraries" ).
|
||||
if [ -n "$alllibs" ]; then
|
||||
changes=""
|
||||
for l in $alllibs; do
|
||||
changes="$changes -change $l @rpath/`basename $l`"
|
||||
done
|
||||
|
||||
for f in $pkglib/* $LIBADD "$binary"; do
|
||||
# avoid directories
|
||||
if [ -f $f ]; then
|
||||
if ! install_name_tool $changes $f; then
|
||||
echo "Error: 'install_name_tool $changes $f' failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
#if [ "$WITH_IMAGEMAGICK" = "yes" ]; then
|
||||
# and now, obfuscate all the default paths in dynamic libraries
|
||||
# and ImageMagick modules and config files
|
||||
|
||||
# generate a pseudo-random string which has the same length as $MACPORTS
|
||||
RANDSTR="R7bUU6jiFvqrPy6zLVPwIC3b93R2b1RG2qD3567t8hC3b93R2b1RG2qD3567t8h"
|
||||
MACRAND=${RANDSTR:0:${#MACPORTS}}
|
||||
HOMEBREWRAND=${RANDSTR:0:${#HOMEBREW}}
|
||||
LOCALRAND=${RANDSTR:0:${#LOCAL}}
|
||||
find $pkglib -type f -exec sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" {} \;
|
||||
sed -e "s@$MACPORTS@$MACRAND@g" -e "s@$HOMEBREW@$HOMEBREWRAND@g" -e "s@$LOCAL@$LOCALRAND@g" -i "" "$binary"
|
||||
#fi
|
||||
Reference in New Issue
Block a user