change: Switch to offical OpenFX Support. Still can't compile.
This commit is contained in:
-147
@@ -1,147 +0,0 @@
|
|||||||
# Generated from CLion Inspection settings
|
|
||||||
---
|
|
||||||
Checks: '-*,
|
|
||||||
bugprone-argument-comment,
|
|
||||||
bugprone-assert-side-effect,
|
|
||||||
bugprone-bad-signal-to-kill-thread,
|
|
||||||
bugprone-branch-clone,
|
|
||||||
bugprone-copy-constructor-init,
|
|
||||||
bugprone-dangling-handle,
|
|
||||||
bugprone-dynamic-static-initializers,
|
|
||||||
bugprone-fold-init-type,
|
|
||||||
bugprone-forward-declaration-namespace,
|
|
||||||
bugprone-forwarding-reference-overload,
|
|
||||||
bugprone-inaccurate-erase,
|
|
||||||
bugprone-incorrect-roundings,
|
|
||||||
bugprone-integer-division,
|
|
||||||
bugprone-lambda-function-name,
|
|
||||||
bugprone-macro-parentheses,
|
|
||||||
bugprone-macro-repeated-side-effects,
|
|
||||||
bugprone-misplaced-operator-in-strlen-in-alloc,
|
|
||||||
bugprone-misplaced-pointer-arithmetic-in-alloc,
|
|
||||||
bugprone-misplaced-widening-cast,
|
|
||||||
bugprone-move-forwarding-reference,
|
|
||||||
bugprone-multiple-statement-macro,
|
|
||||||
bugprone-no-escape,
|
|
||||||
bugprone-parent-virtual-call,
|
|
||||||
bugprone-posix-return,
|
|
||||||
bugprone-reserved-identifier,
|
|
||||||
bugprone-sizeof-container,
|
|
||||||
bugprone-sizeof-expression,
|
|
||||||
bugprone-spuriously-wake-up-functions,
|
|
||||||
bugprone-string-constructor,
|
|
||||||
bugprone-string-integer-assignment,
|
|
||||||
bugprone-string-literal-with-embedded-nul,
|
|
||||||
bugprone-suspicious-enum-usage,
|
|
||||||
bugprone-suspicious-include,
|
|
||||||
bugprone-suspicious-memset-usage,
|
|
||||||
bugprone-suspicious-missing-comma,
|
|
||||||
bugprone-suspicious-semicolon,
|
|
||||||
bugprone-suspicious-string-compare,
|
|
||||||
bugprone-suspicious-memory-comparison,
|
|
||||||
bugprone-suspicious-realloc-usage,
|
|
||||||
bugprone-swapped-arguments,
|
|
||||||
bugprone-terminating-continue,
|
|
||||||
bugprone-throw-keyword-missing,
|
|
||||||
bugprone-too-small-loop-variable,
|
|
||||||
bugprone-undefined-memory-manipulation,
|
|
||||||
bugprone-undelegated-constructor,
|
|
||||||
bugprone-unhandled-self-assignment,
|
|
||||||
bugprone-unused-raii,
|
|
||||||
bugprone-unused-return-value,
|
|
||||||
bugprone-use-after-move,
|
|
||||||
bugprone-virtual-near-miss,
|
|
||||||
cert-dcl21-cpp,
|
|
||||||
cert-dcl58-cpp,
|
|
||||||
cert-err34-c,
|
|
||||||
cert-err52-cpp,
|
|
||||||
cert-err60-cpp,
|
|
||||||
cert-flp30-c,
|
|
||||||
cert-msc50-cpp,
|
|
||||||
cert-msc51-cpp,
|
|
||||||
cert-str34-c,
|
|
||||||
cppcoreguidelines-interfaces-global-init,
|
|
||||||
cppcoreguidelines-narrowing-conversions,
|
|
||||||
cppcoreguidelines-pro-type-member-init,
|
|
||||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
|
||||||
cppcoreguidelines-slicing,
|
|
||||||
google-default-arguments,
|
|
||||||
google-explicit-constructor,
|
|
||||||
google-runtime-operator,
|
|
||||||
hicpp-exception-baseclass,
|
|
||||||
hicpp-multiway-paths-covered,
|
|
||||||
misc-misplaced-const,
|
|
||||||
misc-new-delete-overloads,
|
|
||||||
misc-no-recursion,
|
|
||||||
misc-non-copyable-objects,
|
|
||||||
misc-throw-by-value-catch-by-reference,
|
|
||||||
misc-unconventional-assign-operator,
|
|
||||||
misc-uniqueptr-reset-release,
|
|
||||||
modernize-avoid-bind,
|
|
||||||
modernize-concat-nested-namespaces,
|
|
||||||
modernize-deprecated-headers,
|
|
||||||
modernize-deprecated-ios-base-aliases,
|
|
||||||
modernize-loop-convert,
|
|
||||||
modernize-make-shared,
|
|
||||||
modernize-make-unique,
|
|
||||||
modernize-pass-by-value,
|
|
||||||
modernize-raw-string-literal,
|
|
||||||
modernize-redundant-void-arg,
|
|
||||||
modernize-replace-auto-ptr,
|
|
||||||
modernize-replace-disallow-copy-and-assign-macro,
|
|
||||||
modernize-replace-random-shuffle,
|
|
||||||
modernize-return-braced-init-list,
|
|
||||||
modernize-shrink-to-fit,
|
|
||||||
modernize-unary-static-assert,
|
|
||||||
modernize-use-auto,
|
|
||||||
modernize-use-bool-literals,
|
|
||||||
modernize-use-emplace,
|
|
||||||
modernize-use-equals-default,
|
|
||||||
modernize-use-equals-delete,
|
|
||||||
modernize-use-nodiscard,
|
|
||||||
modernize-use-noexcept,
|
|
||||||
modernize-use-nullptr,
|
|
||||||
modernize-use-override,
|
|
||||||
modernize-use-transparent-functors,
|
|
||||||
modernize-use-uncaught-exceptions,
|
|
||||||
mpi-buffer-deref,
|
|
||||||
mpi-type-mismatch,
|
|
||||||
openmp-use-default-none,
|
|
||||||
performance-faster-string-find,
|
|
||||||
performance-for-range-copy,
|
|
||||||
performance-implicit-conversion-in-loop,
|
|
||||||
performance-inefficient-algorithm,
|
|
||||||
performance-inefficient-string-concatenation,
|
|
||||||
performance-inefficient-vector-operation,
|
|
||||||
performance-move-const-arg,
|
|
||||||
performance-move-constructor-init,
|
|
||||||
performance-no-automatic-move,
|
|
||||||
performance-noexcept-move-constructor,
|
|
||||||
performance-trivially-destructible,
|
|
||||||
performance-type-promotion-in-math-fn,
|
|
||||||
performance-unnecessary-copy-initialization,
|
|
||||||
performance-unnecessary-value-param,
|
|
||||||
portability-simd-intrinsics,
|
|
||||||
readability-avoid-const-params-in-decls,
|
|
||||||
readability-const-return-type,
|
|
||||||
readability-container-size-empty,
|
|
||||||
readability-convert-member-functions-to-static,
|
|
||||||
readability-delete-null-pointer,
|
|
||||||
readability-deleted-default,
|
|
||||||
readability-inconsistent-declaration-parameter-name,
|
|
||||||
readability-make-member-function-const,
|
|
||||||
readability-misleading-indentation,
|
|
||||||
readability-misplaced-array-index,
|
|
||||||
readability-non-const-parameter,
|
|
||||||
readability-redundant-control-flow,
|
|
||||||
readability-redundant-declaration,
|
|
||||||
readability-redundant-function-ptr-dereference,
|
|
||||||
readability-redundant-smartptr-get,
|
|
||||||
readability-redundant-string-cstr,
|
|
||||||
readability-redundant-string-init,
|
|
||||||
readability-simplify-subscript-expr,
|
|
||||||
readability-static-accessed-through-instance,
|
|
||||||
readability-static-definition-in-anonymous-namespace,
|
|
||||||
readability-string-compare,
|
|
||||||
readability-uniqueptr-delete-release,
|
|
||||||
readability-use-anyofallof'
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# CMake artifacts
|
# CMake artifacts
|
||||||
/build*/
|
/build*/
|
||||||
|
build
|
||||||
# Doxygen
|
# Doxygen
|
||||||
/docs/
|
/docs/
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -1,10 +1,6 @@
|
|||||||
[submodule "ext/core"]
|
[submodule "ext/core"]README
|
||||||
path = ext/core
|
path = ext/core
|
||||||
url = https://github.com/olive-editor/core
|
url = https://github.com/olive-editor/core
|
||||||
[submodule "ext/KDDockWidgets"]
|
[submodule "ext/KDDockWidgets"]
|
||||||
path = ext/KDDockWidgets
|
path = ext/KDDockWidgets
|
||||||
url = https://github.com/olive-editor/KDDockWidgets.git
|
url = https://github.com/olive-editor/KDDockWidgets.git
|
||||||
[submodule "third_party/openfx"]
|
|
||||||
path = third_party/openfx
|
|
||||||
url = https://github.com/AcademySoftwareFoundation/openfx.git
|
|
||||||
branch = main
|
|
||||||
|
|||||||
+10
-3
@@ -14,10 +14,16 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.30 FATAL_ERROR)
|
||||||
|
|
||||||
project(olive-editor VERSION 0.2.0 LANGUAGES CXX)
|
project(olive-editor VERSION 0.2.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
|
||||||
|
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD ON)
|
||||||
|
find_package(expat REQUIRED)
|
||||||
|
|
||||||
option(BUILD_QT6 "Build with Qt 6 over 5 (experimental)" ON)
|
option(BUILD_QT6 "Build with Qt 6 over 5 (experimental)" ON)
|
||||||
option(BUILD_DOXYGEN "Build Doxygen documentation" OFF)
|
option(BUILD_DOXYGEN "Build Doxygen documentation" OFF)
|
||||||
option(BUILD_TESTS "Build unit tests" OFF)
|
option(BUILD_TESTS "Build unit tests" OFF)
|
||||||
@@ -31,10 +37,11 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
|
||||||
# Generates a compile_commands.json in the build dir, link that to the repo
|
# Generates a compile_commands.json in the build dir, link that to the repo
|
||||||
# root to enrich your IDE with clangd language server protocol functionalities
|
# root to enrich your IDE with clangd language server protocol functionalities
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
add_subdirectory(third_party/openfx/HostSupport)
|
||||||
# Sanitizers
|
# Sanitizers
|
||||||
add_library(olive-sanitizers INTERFACE)
|
add_library(olive-sanitizers INTERFACE)
|
||||||
include(cmake/Sanitizers.cmake)
|
include(cmake/Sanitizers.cmake)
|
||||||
@@ -168,7 +175,7 @@ list(APPEND OLIVE_LIBRARIES
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Link FFmpeg
|
# Link FFmpeg
|
||||||
find_package(FFMPEG 3.0 REQUIRED
|
find_package(FFMPEG 7.0 REQUIRED
|
||||||
COMPONENTS
|
COMPONENTS
|
||||||
avutil
|
avutil
|
||||||
avcodec
|
avcodec
|
||||||
|
|||||||
+6
-5
@@ -18,7 +18,6 @@
|
|||||||
set(OLIVE_SOURCES
|
set(OLIVE_SOURCES
|
||||||
core.h
|
core.h
|
||||||
core.cpp
|
core.cpp
|
||||||
pluginSupport/DrawSuite.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#set(OLIVE_RESOURCES)
|
#set(OLIVE_RESOURCES)
|
||||||
@@ -33,7 +32,6 @@ add_subdirectory(dialog)
|
|||||||
add_subdirectory(node)
|
add_subdirectory(node)
|
||||||
add_subdirectory(packaging)
|
add_subdirectory(packaging)
|
||||||
add_subdirectory(panel)
|
add_subdirectory(panel)
|
||||||
add_subdirectory(pluginSupport)
|
|
||||||
add_subdirectory(render)
|
add_subdirectory(render)
|
||||||
add_subdirectory(shaders)
|
add_subdirectory(shaders)
|
||||||
add_subdirectory(task)
|
add_subdirectory(task)
|
||||||
@@ -75,8 +73,10 @@ add_library(libolive-editor
|
|||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
${OLIVE_RESOURCES}
|
${OLIVE_RESOURCES}
|
||||||
)
|
)
|
||||||
|
add_subdirectory(pluginSupport)
|
||||||
target_include_directories(libolive-editor PUBLIC ../third_party/openfx/include)
|
target_compile_features(libolive-editor PUBLIC cxx_std_23)
|
||||||
|
include_directories(../third_party/openfx/include
|
||||||
|
../third_party/openfx/HostSupport/include)
|
||||||
# Remove prefix - prevents CMake calling it "liblibolive-editor"
|
# Remove prefix - prevents CMake calling it "liblibolive-editor"
|
||||||
set_target_properties(libolive-editor PROPERTIES PREFIX "")
|
set_target_properties(libolive-editor PROPERTIES PREFIX "")
|
||||||
|
|
||||||
@@ -86,7 +86,8 @@ add_executable(olive-editor
|
|||||||
$<TARGET_OBJECTS:libolive-editor>
|
$<TARGET_OBJECTS:libolive-editor>
|
||||||
$<TARGET_OBJECTS:olive-version-obj>
|
$<TARGET_OBJECTS:olive-version-obj>
|
||||||
)
|
)
|
||||||
|
target_include_directories(olive-editor PUBLIC pluginSupport)
|
||||||
|
target_link_libraries(olive-editor PUBLIC OfxHost)
|
||||||
# Create docs if doxygen was found
|
# Create docs if doxygen was found
|
||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
set(DOXYGEN_PROJECT_NAME "Olive")
|
set(DOXYGEN_PROJECT_NAME "Olive")
|
||||||
|
|||||||
+10
-1
@@ -52,7 +52,7 @@ extern "C" {
|
|||||||
#ifdef USE_CRASHPAD
|
#ifdef USE_CRASHPAD
|
||||||
#include "common/crashpadinterface.h"
|
#include "common/crashpadinterface.h"
|
||||||
#endif // USE_CRASHPAD
|
#endif // USE_CRASHPAD
|
||||||
|
#include "OlivePlugin.cpp"
|
||||||
int decompress_project(const QString &project)
|
int decompress_project(const QString &project)
|
||||||
{
|
{
|
||||||
if (project.isEmpty()) {
|
if (project.isEmpty()) {
|
||||||
@@ -214,6 +214,11 @@ int main(int argc, char *argv[])
|
|||||||
QStringLiteral("project"),
|
QStringLiteral("project"),
|
||||||
QCoreApplication::translate("main", "Project to open on startup"));
|
QCoreApplication::translate("main", "Project to open on startup"));
|
||||||
|
|
||||||
|
auto no_plugin = parser.AddOption(
|
||||||
|
{ QStringLiteral("-no-plugin") },
|
||||||
|
QCoreApplication::translate("main", "Don't load plugins")
|
||||||
|
);
|
||||||
|
|
||||||
// Qt options re-implemented (add to this as necessary)
|
// Qt options re-implemented (add to this as necessary)
|
||||||
//
|
//
|
||||||
// Because we don't use QCommandLineParser, we must filter out Qt's arguments ourselves. Here,
|
// Because we don't use QCommandLineParser, we must filter out Qt's arguments ourselves. Here,
|
||||||
@@ -280,6 +285,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!no_plugin->IsSet()) {
|
||||||
|
olive::plugin::loadPlugins("plugins");
|
||||||
|
}
|
||||||
|
|
||||||
if (crash_option->IsSet()) {
|
if (crash_option->IsSet()) {
|
||||||
startup_params.set_crash_on_startup(true);
|
startup_params.set_crash_on_startup(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#define PLUGIN_NODES_H
|
#define PLUGIN_NODES_H
|
||||||
#include "node/node.h"
|
#include "node/node.h"
|
||||||
#include "pluginSupport/Plugin.h"
|
#include "pluginSupport/Plugin.h"
|
||||||
#include "pluginSupport/OlivePlugin.h"
|
#include "pluginSupport/OlivePlugin.cpp"
|
||||||
namespace olive
|
namespace olive
|
||||||
{
|
{
|
||||||
namespace plugin
|
namespace plugin
|
||||||
|
|||||||
@@ -1,22 +1,6 @@
|
|||||||
set(OLIVE_SOURCES
|
target_sources(libolive-editor PRIVATE
|
||||||
${OLIVE_SOURCES}
|
OliveHost.h
|
||||||
pluginSupport/OlivePlugin.h
|
OliveHost.cpp
|
||||||
pluginSupport/OlivePlugin.cpp
|
OliveInstance.h
|
||||||
pluginSupport/Dialog.cpp
|
OliveInstance.cpp
|
||||||
pluginSupport/Core.cpp
|
|
||||||
pluginSupport/DrawSuite.cpp
|
|
||||||
pluginSupport/GpuRender.cpp
|
|
||||||
pluginSupport/ImageEffect.cpp
|
|
||||||
pluginSupport/Interact.cpp
|
|
||||||
pluginSupport/KeySyms.cpp
|
|
||||||
pluginSupport/Memory.cpp
|
|
||||||
pluginSupport/MultiThread.cpp
|
|
||||||
pluginSupport/OpenGLRender.cpp
|
|
||||||
pluginSupport/Param.cpp
|
|
||||||
pluginSupport/ParametricParam.cpp
|
|
||||||
pluginSupport/Pixels.cpp
|
|
||||||
pluginSupport/Progress.cpp
|
|
||||||
pluginSupport/Property.cpp
|
|
||||||
pluginSupport/TimeLine.cpp
|
|
||||||
PARENT_SCOPE
|
|
||||||
)
|
)
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <ofxDialog.h>
|
|
||||||
|
|
||||||
OfxStatus NotifyRedrawPending()
|
|
||||||
{
|
|
||||||
return kOfxStatReplyDefault;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "DrawSuite.h"
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "node/project.h"
|
||||||
|
#include "ofxhImageEffect.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <ofxhPluginCache.h>
|
||||||
|
#include <ofxhBinary.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include "OliveHost.h"
|
||||||
|
using namespace OFX::Host;
|
||||||
|
using namespace olive::plugin;
|
||||||
|
void loadPlugins(QString path)
|
||||||
|
{
|
||||||
|
QDir dir=(QCoreApplication::applicationDirPath()+path);
|
||||||
|
QFileInfoList files=dir.entryInfoList();
|
||||||
|
for (auto& file:files) {
|
||||||
|
if (file.isDir()) {
|
||||||
|
OFX::Binary binary(file.absoluteFilePath().toStdString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OliveHost::~OliveHost()
|
||||||
|
{
|
||||||
|
for(auto& descriptor:descriptors_){
|
||||||
|
delete descriptor;
|
||||||
|
descriptor=nullptr;
|
||||||
|
}
|
||||||
|
for(auto& instance:instances_){
|
||||||
|
delete instance;
|
||||||
|
instance=nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ImageEffect::Descriptor *
|
||||||
|
OliveHost::makeDescriptor(ImageEffect::ImageEffectPlugin* plugin)
|
||||||
|
{
|
||||||
|
ImageEffect::Descriptor* desc = new ImageEffect::Descriptor(plugin);
|
||||||
|
descriptors_.append(desc);
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
ImageEffect::Descriptor *
|
||||||
|
OliveHost::makeDescriptor(const ImageEffect::Descriptor &rootContext,
|
||||||
|
ImageEffect::ImageEffectPlugin *plugin)
|
||||||
|
{
|
||||||
|
ImageEffect::Descriptor* desc = new ImageEffect::Descriptor(rootContext,plugin);
|
||||||
|
descriptors_.append(desc);
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
ImageEffect::Descriptor *
|
||||||
|
OliveHost::makeDescriptor(const std::string &bundlePath,
|
||||||
|
ImageEffect::ImageEffectPlugin *plugin)
|
||||||
|
{
|
||||||
|
ImageEffect::Descriptor* desc = new ImageEffect::Descriptor(bundlePath, plugin);
|
||||||
|
descriptors_.append(desc);
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::Instance* OliveHost::newInstance(void* clientData,
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin* plugin,
|
||||||
|
OFX::Host::ImageEffect::Descriptor& desc,
|
||||||
|
const std::string& context){
|
||||||
|
//ImageEffect::Instance* instance=new ImageEffect::Instance(clientData,plugin,desc,context);
|
||||||
|
instances_.append(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "ofxhHost.h"
|
||||||
|
#include "ofxhImageEffectAPI.h"
|
||||||
|
#include "ofxCore.h"
|
||||||
|
#include "ofxhImageEffect.h"
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
#include <any>
|
||||||
|
#include <list>
|
||||||
|
#include <OpenImageIO/detail/fmt/chrono.h>
|
||||||
|
#include <qlist.h>
|
||||||
|
namespace olive {
|
||||||
|
namespace plugin {
|
||||||
|
|
||||||
|
|
||||||
|
void loadPlugins(QString path);
|
||||||
|
class OliveHost: public OFX::Host::ImageEffect::Host{
|
||||||
|
public:
|
||||||
|
OliveHost()=default;
|
||||||
|
~OliveHost() override;
|
||||||
|
|
||||||
|
bool pluginSupported(OFX::Host::ImageEffect::ImageEffectPlugin *plugin,
|
||||||
|
std::string &reason) const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::Instance* newInstance(void* clientData,
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin* plugin,
|
||||||
|
OFX::Host::ImageEffect::Descriptor& desc,
|
||||||
|
const std::string& context) override;
|
||||||
|
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::Descriptor *makeDescriptor(
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin* plugin) override;
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::Descriptor *makeDescriptor(
|
||||||
|
const OFX::Host::ImageEffect::Descriptor &rootContext,
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin *plugin) override;
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::Descriptor *makeDescriptor(
|
||||||
|
const std::string &bundlePath,
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin *plugin) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<OFX::Host::ImageEffect::Descriptor*> descriptors_;
|
||||||
|
QList<OFX::Host::ImageEffect::Instance*> instances_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "OliveInstance.h"
|
||||||
|
#include "ofxCore.h"
|
||||||
|
#include "ofxMessage.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <qmessagebox.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <QString>
|
||||||
|
namespace olive{
|
||||||
|
namespace plugin {
|
||||||
|
OfxStatus OliveInstance::vmessage(const char* type,
|
||||||
|
const char* id,
|
||||||
|
const char* format,
|
||||||
|
va_list args){
|
||||||
|
|
||||||
|
char *buffer=new char[1024];
|
||||||
|
|
||||||
|
memset(buffer, 0, 1024*sizeof(char));
|
||||||
|
vsprintf(buffer, format, args);
|
||||||
|
|
||||||
|
QString message(buffer);
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
if(strncmp(type, kOfxMessageQuestion, strlen(kOfxMessageQuestion))){
|
||||||
|
|
||||||
|
auto ret= QMessageBox::information(nullptr,
|
||||||
|
"", message,
|
||||||
|
QMessageBox::Ok, QMessageBox::Cancel);
|
||||||
|
|
||||||
|
if(ret==QMessageBox::Ok){
|
||||||
|
return kOfxStatReplyYes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return kOfxStatReplyNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
QMessageBox::information(nullptr,
|
||||||
|
"", message);
|
||||||
|
return kOfxStatOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ofxImageEffect.h"
|
||||||
|
#include "ofxhImageEffect.h"
|
||||||
|
namespace olive {
|
||||||
|
namespace plugin{
|
||||||
|
class OliveInstance : public OFX::Host::ImageEffect::Instance {
|
||||||
|
public:
|
||||||
|
OliveInstance(
|
||||||
|
OFX::Host::ImageEffect::ImageEffectPlugin* plugin,
|
||||||
|
OFX::Host::ImageEffect::Descriptor& desc,
|
||||||
|
const std::string& context,
|
||||||
|
bool interactive)
|
||||||
|
: OFX::Host::ImageEffect::Instance(plugin, desc, context, interactive)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~OliveInstance() override = default;
|
||||||
|
virtual const std::string &getDefaultOutputFielding() const{
|
||||||
|
return kOfxImageFieldNone;
|
||||||
|
};
|
||||||
|
|
||||||
|
OFX::Host::ImageEffect::ClipInstance *newClipInstance(
|
||||||
|
OFX::Host::ImageEffect::Instance *plugin,
|
||||||
|
OFX::Host::ImageEffect::ClipDescriptor *descriptor,
|
||||||
|
int index) override;
|
||||||
|
|
||||||
|
OfxStatus vmessage(const char* type,
|
||||||
|
const char* id,
|
||||||
|
const char* format,
|
||||||
|
va_list args) override;
|
||||||
|
|
||||||
|
OfxStatus setPersistentMessage(const char* type,
|
||||||
|
const char* id,
|
||||||
|
const char* format,
|
||||||
|
va_list args) override;
|
||||||
|
|
||||||
|
OfxStatus clearPersistentMessage() override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
#include "OlivePlugin.h"
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
olive::plugin::OlivePlugin::~OlivePlugin()
|
|
||||||
{
|
|
||||||
for (void *p:mems) {
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getProp(QString key, int index,
|
|
||||||
char **str)
|
|
||||||
{
|
|
||||||
*str=nullptr;
|
|
||||||
if (stringProps.contains(key)) {
|
|
||||||
if (stringProps[key].count()>index) {
|
|
||||||
*str=stringProps[key][index];
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getPropN(QString key,
|
|
||||||
char ***str)
|
|
||||||
{
|
|
||||||
*str=nullptr;
|
|
||||||
if (stringProps.contains(key)) {
|
|
||||||
*str=stringProps[key].data();
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getProp(QString key, int index,
|
|
||||||
void **str)
|
|
||||||
{
|
|
||||||
*str=nullptr;
|
|
||||||
if (pointerProps.contains(key)) {
|
|
||||||
if (pointerProps[key].count()>index) {
|
|
||||||
*str=pointerProps[key][index];
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getPropN(QString key,
|
|
||||||
void ***p)
|
|
||||||
{
|
|
||||||
*p=nullptr;
|
|
||||||
if (pointerProps.contains(key)) {
|
|
||||||
*p=pointerProps[key].data();
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getProp(QString key, int index,
|
|
||||||
int* p)
|
|
||||||
{
|
|
||||||
*p=0;
|
|
||||||
if (intProps.contains(key)) {
|
|
||||||
if (intProps[key].count()>index) {
|
|
||||||
*p=intProps[key][index];
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getPropN(QString key,
|
|
||||||
int **p)
|
|
||||||
{
|
|
||||||
*p=nullptr;
|
|
||||||
if (intProps.contains(key)) {
|
|
||||||
*p=intProps[key].data();
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getProp(QString key, int index,
|
|
||||||
double* p)
|
|
||||||
{
|
|
||||||
*p=0;
|
|
||||||
if (doubleProps.contains(key)) {
|
|
||||||
if (doubleProps[key].count()>index) {
|
|
||||||
*p=doubleProps[key][index];
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::getPropN(QString key,
|
|
||||||
double **p)
|
|
||||||
{
|
|
||||||
*p=nullptr;
|
|
||||||
if (doubleProps.contains(key)) {
|
|
||||||
*p=doubleProps[key].data();
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
return kOfxStatErrUnknown;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setProp(QString key, int index, char *str)
|
|
||||||
{
|
|
||||||
char *p=(char*)calloc(strlen(str)+1,sizeof(char));
|
|
||||||
strcpy(p,str);
|
|
||||||
if (stringProps.contains(key)) {
|
|
||||||
if (stringProps[key].count()>index) {
|
|
||||||
stringProps[key].insert(index, p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
stringProps[key].emplace_back(p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
QVector<char *> vec;
|
|
||||||
vec.emplace_back(str);
|
|
||||||
stringProps[key]=vec;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setPropN(QString key, int count, char **strs)
|
|
||||||
{
|
|
||||||
QVector<char *> vector;
|
|
||||||
for (int i=0;i<count;i++) {
|
|
||||||
char *p=(char*)calloc(strlen(strs[i])+1,sizeof(char));
|
|
||||||
strcpy(p,strs[i]);
|
|
||||||
vector.emplace_back(p);
|
|
||||||
}
|
|
||||||
stringProps[key]=vector;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setProp(QString key, int index, void *p)
|
|
||||||
{
|
|
||||||
if (pointerProps.contains(key)) {
|
|
||||||
if (pointerProps[key].count()>index) {
|
|
||||||
pointerProps[key].insert(index, p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
pointerProps[key].emplace_back(p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
QVector<void *> vec;
|
|
||||||
vec.emplace_back(p);
|
|
||||||
pointerProps[key]=vec;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, void **ps)
|
|
||||||
{
|
|
||||||
QVector<void *> vector;
|
|
||||||
vector.reserve(count);
|
|
||||||
memcpy(vector.data(), ps, sizeof(void *)*count);
|
|
||||||
pointerProps[key]=vector;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setProp(QString key, int index, int p)
|
|
||||||
{
|
|
||||||
if (intProps.contains(key)) {
|
|
||||||
if (intProps[key].count()>index) {
|
|
||||||
intProps[key].insert(index, p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
intProps[key].emplace_back(p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
QVector<int> vec;
|
|
||||||
vec.emplace_back(p);
|
|
||||||
intProps[key]=vec;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, int *ps)
|
|
||||||
{
|
|
||||||
QVector<int> vector;
|
|
||||||
vector.reserve(count);
|
|
||||||
memcpy(vector.data(), ps, sizeof(int)*count);
|
|
||||||
intProps[key]=vector;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setProp(QString key, int index, double p)
|
|
||||||
{
|
|
||||||
if (doubleProps.contains(key)) {
|
|
||||||
if (doubleProps[key].count()>index) {
|
|
||||||
doubleProps[key].insert(index, p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
doubleProps[key].emplace_back(p);
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
QVector<double> vec;
|
|
||||||
vec.emplace_back(p);
|
|
||||||
doubleProps[key]=vec;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
OfxStatus olive::plugin::OlivePlugin::setPropN(QString key,int count, double *ps)
|
|
||||||
{
|
|
||||||
QVector<double> vector;
|
|
||||||
vector.reserve(count);
|
|
||||||
memcpy(vector.data(), ps, sizeof(doubleProps)*count);
|
|
||||||
doubleProps[key]=vector;
|
|
||||||
return kOfxStatOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OLIVE_PLUGIN_H
|
|
||||||
#define OLIVE_PLUGIN_H
|
|
||||||
#include "OlivePlugin.h"
|
|
||||||
#include "ofxCore.h"
|
|
||||||
#include <QVariant>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <QString>
|
|
||||||
#include <QMap>
|
|
||||||
#include <any>
|
|
||||||
#include <list>
|
|
||||||
#include <OpenImageIO/detail/fmt/chrono.h>
|
|
||||||
namespace olive
|
|
||||||
{
|
|
||||||
namespace plugin
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
enum class Type {
|
|
||||||
FLOAT, STRING, INT, POINTER, ARRAY, NONE
|
|
||||||
};
|
|
||||||
struct plugin_mem_ptr {
|
|
||||||
void *mem;
|
|
||||||
int32_t count=0;
|
|
||||||
};
|
|
||||||
class OlivePlugin {
|
|
||||||
public:
|
|
||||||
OlivePlugin()=default;
|
|
||||||
~OlivePlugin();
|
|
||||||
OfxStatus getProp(QString key, int index, char **str);
|
|
||||||
OfxStatus getPropN(QString key, char *** strs);
|
|
||||||
OfxStatus getProp(QString key, int index, void **p);
|
|
||||||
OfxStatus getPropN(QString key, void ***ps);
|
|
||||||
OfxStatus getProp(QString key, int index, int *p);
|
|
||||||
OfxStatus getPropN(QString key, int **ps);
|
|
||||||
OfxStatus getProp(QString key, int index, double *p);
|
|
||||||
OfxStatus getPropN(QString key, double **ps);
|
|
||||||
OfxStatus setProp(QString key, int index, char *str);
|
|
||||||
OfxStatus setPropN(QString key,int count, char ** strs);
|
|
||||||
OfxStatus setProp(QString key, int index, void *p);
|
|
||||||
OfxStatus setPropN(QString key,int count, void **ps);
|
|
||||||
OfxStatus setProp(QString key, int index, int p);
|
|
||||||
OfxStatus setPropN(QString key,int count, int *ps);
|
|
||||||
OfxStatus setProp(QString key, int index, double p);
|
|
||||||
OfxStatus setPropN(QString key, int count, double *ps);
|
|
||||||
void addMem(void *mem)
|
|
||||||
{
|
|
||||||
mems.emplace_back(mem);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
uint64_t id;
|
|
||||||
QString name;
|
|
||||||
QString version;
|
|
||||||
QMap<QString, QVector<char *>> stringProps;
|
|
||||||
QMap<QString, QVector<int>> intProps;
|
|
||||||
QMap<QString, QVector<double>> doubleProps;
|
|
||||||
QMap<QString, QVector<void *>> pointerProps;
|
|
||||||
std::list<void *> mems;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct OfxPropertySetStruct {
|
|
||||||
olive::plugin::OlivePlugin* plugin;
|
|
||||||
};
|
|
||||||
#endif //OLIVE_PLUGIN_H
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
#include "node/plugins/Plugin.h"
|
|
||||||
|
|
||||||
#include <ofxProperty.h>
|
|
||||||
#include <OpenImageIO/simd.h>
|
|
||||||
#include <oneapi/tbb/detail/_template_helpers.h>
|
|
||||||
|
|
||||||
OfxStatus propSetPointer(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, void *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetString(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, const char *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setProp(property, index, const_cast<char *>(value));
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetDouble(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, double value)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetInt(OfxPropertySetHandle properties, const char *property,
|
|
||||||
int index, int value)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetPointerN(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int count, void * const*value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setPropN(property, count, const_cast<void**>(value));
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetStringN(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, int count,const char *const *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setPropN(property, count, const_cast<char**>(value));
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetDoubleN(OfxPropertySetHandle properties,
|
|
||||||
const char *property,int count, const double* value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setPropN(property, count, const_cast<double *>(value));
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetIntN(OfxPropertySetHandle properties, const char *property,
|
|
||||||
int count, const int *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->setPropN(property, count, const_cast<int *>(value));
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetPointer(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, void **value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetString(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, char **value)
|
|
||||||
{
|
|
||||||
std::any val;
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetDouble(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, double *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetInt(OfxPropertySetHandle properties, const char *property,
|
|
||||||
int index, int *value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (index<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getProp(property, index, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetPointerN(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int count, void ***value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getPropN(property, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propGetStringN(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int count, char ***value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getPropN(property, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetDoubleN(OfxPropertySetHandle properties,
|
|
||||||
const char *property, int index, int count, double** value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getPropN(property, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
OfxStatus propSetIntN(OfxPropertySetHandle properties, const char *property,
|
|
||||||
int index, int count, int **value)
|
|
||||||
{
|
|
||||||
if (properties->plugin) {
|
|
||||||
if (count<0) {
|
|
||||||
return kOfxStatErrBadIndex;
|
|
||||||
}
|
|
||||||
return properties->plugin->getPropN(property, value);
|
|
||||||
}
|
|
||||||
return kOfxStatErrBadHandle;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
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];
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user